Sollen bei Beleuchtungsberechnungen nur die ambienten und diffusen Reflexionsanteile berücksichtigt werden und sind einzelne Modellteile darüber hinaus nicht separat animierbar, dann wäre die Transformation der Textur-Normalen in die aktuelle Orientierung des 3D-Modells eine unnötige Verschwendung von Performance. Stattdessen bietet sich die Rücktranformation der Lichtrichtung in den Object (Model) Space an, da diese vor dem Rendering pro Objekt nur ein einziges Mal durchgeführt werden muss:
// Richtung des Sonnenlichts im Modellraum berechnen:
D3DXMATRIXA16 TransposedMatrix;
D3DXVECTOR3 LightDirModelSpace;
D3DXMatrixTranspose(&TransposedMatrix, pRotationMatrix);
Multiply3DVectorWithRotationMatrix(&LightDirModelSpace, &LightDir,
&TransposedMatrix);
// umgekehrte Ausbreitungsrichtung des Sonnenlichts im Modellraum
// an das Shader Programm übergeben:
pShader->Set_ShaderFloatVector3(&D3DXVECTOR3(-LightDirModelSpace.x,
-LightDirModelSpace.y,
-LightDirModelSpace.z),
"negLightDirModelSpace");
D3DXMATRIXA16 TransposedMatrix;
D3DXVECTOR3 LightDirModelSpace;
D3DXMatrixTranspose(&TransposedMatrix, pRotationMatrix);
Multiply3DVectorWithRotationMatrix(&LightDirModelSpace, &LightDir,
&TransposedMatrix);
// umgekehrte Ausbreitungsrichtung des Sonnenlichts im Modellraum
// an das Shader Programm übergeben:
pShader->Set_ShaderFloatVector3(&D3DXVECTOR3(-LightDirModelSpace.x,
-LightDirModelSpace.y,
-LightDirModelSpace.z),
"negLightDirModelSpace");
Für die Beleuchtungsberechnungen im Fragment Shader bedarf es lediglich zweier Codezeilen:
vec3 Normal = 2.0*texture2D(NormalTexture, gs_TexCoord[0].st).rgb - 1.0;
gs_FragColor = max(dot(Normal, negLightDirModelSpace), AmbientValue)*
LightColor*SurfaceTextureColor;
gs_FragColor = max(dot(Normal, negLightDirModelSpace), AmbientValue)*
LightColor*SurfaceTextureColor;
Tangent (Texture) Space Normal Mapping: Bei der Generierung einer Normal Map wird lediglich der Höhenverlauf der Modelloberfläche berücksichtigt (siehe Artikel Normal Maps und Height Maps). Damit die Beleuchtungsberechnungen korrekt durchgeführt werden können, müssen die Lichtvektoren zuvor im Vertex Shader in den Tangent (Texture) Space transformiert werden. Bei mehreren Lichtquellen müssen diese Transformationen für jede Quelle wiederholt werden.
World Space Normal Mapping: Bei der Generierung einer Normal Map wird wiederum lediglich der Höhenverlauf der Modelloberfläche berücksichtigt. Vor den eigentlichen Beleuchtungsberechnungen werden nun jedoch die Normalen in den World Space transformiert. Diese Transformation muss unabhängig von der Anzahl der zu berücksichtigenden Lichtquellen nur ein einziges Mal durchgeführt werden.
Hinweis:
Im nächsten Artikel werden wir das World Space Normal Mapping in aller Ausführlichkeit behandeln.