IV. Tutoriel 2. Placage de relief▲
Ce tutoriel montre comment effectuer un placage de relief simple et efficace sur iOS. Cette technique est largement utilisée dans les jeux pour ajouter des détails aux modèles sans avoir besoin d'un modèle complexe ou comportant un nombre élevé de polygones. Nous avons besoin d'une texture contenant les normales en plus de la diffuse. La position de l'éclairage est envoyée au shader dans le système de coordonnées espace monde puis convertie en espace tangent pour effectuer les calculs de lumière. Dans le pixel shader, nous récupérons la normale depuis la normal map pour chaque pixel, menant ainsi à un calcul non uniforme de la lumière sur la surface du modèle. Sans la normal map nous aurions un éclairage uniforme sur une surface plane. La capture d'écran ci-dessous montre le résultat de cette technique appliquée à une simple caisse. (Modèle 3D de turbosquid.com.)
IV-A. Code de la procédure▲
Le shader a besoin d'une texture normale définissant le vecteur normal pour chaque pixel. Nous fournissons aussi la position de la lumière dans l'espace modèle, ce qui peut être fait en multipliant la position de la lumière par l'inverse de la matrice de transformation du modèle comme suit :
// Cette partie sert à animer et déplacer la lumière sur une trajectoire circulaire
static float
y =
0
.f;
static float
x =
0
.f;
x =
-
80
.f *
sinf
(
time);
y =
-
80
.f *
cosf
(
time);
// Conversion de la position de la lumière dans l'espace modèle, de sorte que le calcul de l'éclairage puisse être effectué dans l'espace modèle au sein du shader
// Pour ce faire, nous multiplions la position de la lumière par l'inverse de la matrice de transformation du modèle
vec4f lightPos =
modelBumpMeshMat.inverse
(
) *
vec4f
(
x, y, 0
, 1
.f);
// Envoi de la position de la lumière au shader
m_pShaderBump->
SetUniform3fv
(
"LightPosModel"
, 1
, &
lightPos.x);
Après, dans le vertex shader, nous construisons la matrice Tangent Bitangent Normal (TBN). Cette matrice effectue le passage du système de coordonnées modèle au système tangent. Nous multiplions ainsi le vecteur direction de la lumière par cette matrice pour le convertir dans l'espace tangent. En fait nous avons besoin d'un système de coordonnées commun pour effectuer le calcul de l'éclairage. Les normales et tangentes étant données dans l'espace tangent, nous devons faire passer le vecteur lumière dans le même système de coordonnées pour que cela ait un sens.
// Création de la matrice d'espace tangent
mat3
tangentSpaceXform =
mat3
(
tangent, bitangent, normal);
// Conversion du vecteur direction de la lumière depuis l'espace modèle vers l'espace tangent
v_lightVec =
lightDirection *
tangentSpaceXform;
Dans le vexter shadex, nous créons la normale par pixel à partir de la texture normale, puis calculons l'intensité de la lumière en faisant le produit scalaire entre le vecteur de la normale et le vecteur direction de la lumière.
// Normale par pixel
vec3
normal =
texture2D
(
textureBump, v_texCoord).rgb *
2
.0
-
1
.0
;
// L'intensité lumineuse est le produit scalaire du vecteur direction de la lumière par la normale par pixel
float
lightIntensity =
dot
(
v_lightVec, normal);