I-6. Tutoriel 6 : La lumière▲
I-6-a. Résumé▲
Dans les tutoriaux précédents, le monde semblait ennuyant car tous les objets été éclairés de la même façon.
Ce tutoriel va introduire le concept d'éclairage simple et comment il peut être appliqué.
La technique utilisée sera l'éclairage lambertien.
Le résultat de ce tutoriel modifiera l'exemple précédent pour inclure une source de lumière.
Cette source de lumière sera attachée au cube en orbite.
Les effets de lumière pourront être vu sur le cube centré.
I-6-b. Source▲
(SDK root)\Samples\C++\Direct3D10\Tutorials\Tutorial06
I-6-c. L'éclairage▲
Dans ce tutoriel, le type le plus basique d'éclairage sera introduit : l'éclairage lambertien.
L'éclairage lambertien a une intensité uniforme irrespectueuse de la distance par rapport à la lumière.
Quand la lumière touche la surface, le montant de lumière réfléchie est calculé par l'angle d'incidence que la lumière a sur la surface.
Quand une lumière brille directement sur une surface, elle est montrée pour refletter toute la lumière, avec une intensité maximum.
Cependant, comme l'angle de la lumière augmente, l'intensité de la lumière s'estompera.
Pour calculer l'intensité qu'une lumière a sur une surface, l'angle entre la direction de la lumière et la normale de la surface doit être calculé.
La normale pour une surface est définie en tant qu'un vecteur qui est perpendiculaire à la surface.
Le calcul de l'angle peut être effectué avec un simple produit en croix, lequel retournera la projection de la direction du vecteur de la lumière sur la normale.
Plus large est l'angle, plus petite sera la projection.
Donc, cela nous donne la fonction correcte pour moduler la lumière diffusée.
La source de lumière utilisée dans ce tutoriel est une approximation de l'éclairage directionnel.
Le vecteur qui décrit la source de lumière détermine la direction de la lumière.
Comme c'est une approximation, peu importe où se trouve un objet, la direction dans laquelle la lumière brille est la même.
Un exemple de cette source de lumière est le soleil;
le soleil est toujours vu comme brillant dans la même direction pour tous les objets dans la scène.
En plus, l'intensité de la lumière sur des objets individuels n'est pas prise en considération.
Les autres types de lumières incluent les points lumineux (point lights), qui rayonnent uniformément la lumière depuis son centre, et les spots lumineux (spot lights), qui sont directionnels mais pas uniformes au travers de tous les objets.
I-6-d. initialiser les lumières▲
Dans ce tutoriel, il y aura deux sources de lumières.
Une sera placée statiquement au dessus et derrière le cube, et une autre sera en orbite autour du cube centré.
Notez que le cube en orbite dans le tutoriel précédent a été remplacé avec cette source de lumière.
Comme l'éclairage est calculé par les shaders, les variables devront être déclarées et ensuite attribuées dans les variables à l'intérieur de la technique.
Dans cet exemple, nous avons juste besoin de la direction de la source de lumière, ainsi que de sa couleur.
La première lumière est grise et immobile, et la seconde est une lumière rouge en orbite.
// Configure nos paramètres d'éclairage
D3DXVECTOR4 vLightDirs[2
] =
{
D3DXVECTOR4
(
-
0
.577f
, 0
.577f
, -
0
.577f
, 1
.0f
),
D3DXVECTOR4
(
0
.0f
, 0
.0f
, -
1
.0f
, 1
.0f
),
}
;
D3DXVECTOR4 vLightColors[2
] =
{
D3DXVECTOR4
(
0
.5f
, 0
.5f
, 0
.5f
, 0
.0f
),
D3DXVECTOR4
(
0
.5f
, 0
.0f
, 0
.0f
, 0
.0f
)
}
;
La lumière en orbite tourne juste comme le cube dans le dernier tutoriel. La matrice de rotation appliquée changera la direction de la lumière, pour afficher l'effet qui brille toujours face au centre. Notez que la fonction D3DXVec3Transform est utilisée pour multiplier une matrice avec un vecteur. Dans le tutoriel précédent, nous avons juste multiplié les matrices de transformation dans la matrice monde, nous sommes passée ensuite dans le shader pour transformation; mais dans ce cas, nous allons faire la transformation monde de la lumière par le CPU, pour une question de simplicité.
//fait tourner la seconde lumière autour de l'origine
D3DXMATRIX mRotate;
D3DXVECTOR4 vOutDir;
D3DXMatrixRotationY
(
&
mRotate, -
2
.0f
*
t );
D3DXVec3Transform
(
&
vLightDirs[1
], (
D3DXVECTOR3*
)&
vLightDirs[1
], &
mRotate );
La direction de la lumière et la couleur sont toutes les deux passées dans le shader juste comme des matrices. La variable associée est appelée pour affecter, et le paramètre y est passé.
//
// Met à jour les variables d'éclairage
//
g_pLightDirVariable->
SetFloatVectorArray
(
(
float
*
)vLightDirs, 0
, 2
);
g_pLightColorVariable->
SetFloatVectorArray
(
(
float
*
)vLightColors, 0
, 2
);
I-6-e. Rendu des lumières dans le Pixel Shader▲
Une fois que nous avons toutes les données configurées et le shader correctement fourni avec les données, on peut calculer le terme de l'éclairage lambertien sur chaque pixel depuis les sources de lumière.
Nous utiliserons la règle du produit en croix discutée plus haut.
Une fois que l'on a pris le produit en croix de la lumière par rapport à la normale, celui-ci peut être multiplié avec la couleur de la lumière pour calculer l'effet de cette lumière.
Cette valeur est passée au travers de la fonction saturate, qui converti la portée vers [0, 1].
Finalement, le résultat depuis les deux éclairages séparés sont additionnés ensemble pour créer la couleur pixel finale.
Considérez que le matériau de la surface n'est pas factorisé dans le calcul de la lumière;
la couleur finale sur la surface est le résultat des couleurs des lumières.
//
// Pixel Shader
//
float4 PS
(
PS_INPUT input) : SV_Target
{
float4 finalColor =
0
;
//do NdotL lighting for 2 lights
for
(
int
i=
0
; i<
2
; i++
)
{
finalColor +=
saturate
(
dot
(
(
float3)vLightDir[i],input.Norm) *
vLightColor[i] );
}
return
finalColor;
}
Une fois au travers du pixel shader, les pixels auront été modulés par les lumières et vous pouvez voir l'effet de chaque lumière sur la surface du cube. Notez que la lumière dans ce cas semble plate car les pixels sur la même surface auront la même normale. La lumière diffuse est un modèle d'éclairage très simple et très facile à calculer. Des modèles d'éclairage plus complexes peuvent être utilisés pour accomplir des matériaux plus riches et plus réalistes.