I. Explications▲
Cet article est valide pour toutes les versions d'OpenGL (2, 3 et 4) ainsi que toutes les versions de Direct3D (9, 10 et 11). Je donne les exemples de code en OpenGL 2 et en Direct3D 9. Les codes sont compatibles avec OpenGL 3/4 et Direct3D 10/11 et peuvent être facilement déduits des versions OpenGL 2/D3D9.
Pour calculer la position transformée(1) (gl_Position en GLSL, dans l'espace de clipping), vous avez besoin de trois matrices : projection, view (vue) et model (modèle). Les matrices de projection et de vue sont les matrices correspondant à la caméra et la matrice de modèle est la matrice de transformation de l'objet actuellement affiché.
Les trois matrices sont passées par l'application hôte au vertex shader comme variables d'entrée (déclarées uniform en GLSL).
Dans le code des vertex shaders suivants, P est la position XYZ du vertex dans l'espace local (espace du point de vue de l'objet), c'est-à-dire la position sans aucune transformation. Il en est de même pour N, la normale du vertex dans l'espace local, sans aucune transformation.
II. Shader OpenGL (GLSL)▲
uniform
mat4
projectionMatrix;
uniform
mat4
viewMatrix;
uniform
mat4
modelMatrix;
varying
vec3
normal;
void
main
(
)
{
vec3
P =
gl_Vertex.xyz;
vec3
N =
gl_Normal.xyz;
mat4
modelView =
viewMatrix *
modelMatrix;
mat4
modelViewProjection =
projectionMatrix *
modelView;
gl_Position
=
modelViewProjection *
vec4
(
P, 1
.0
);
normal =
modelView *
vec4
(
N, 0
.0
);
}
III. Shader Direct3D (HLSL)▲
float4x4
projectionMatrix;
float4x4
viewMatrix;
float4x4
modelMatrix;
struct VS_OUTPUT
{
float4
Position : POSITION
;
float3
Normal : TEXCOORD0
;
}
;
VS_OUTPUT VertexShaderD3D
(
float4
P : POSITION
, float3
N : NORMAL
)
{
VS_OUTPUT o;
float4x4
modelView =
mul
(
modelMatrix, viewMatrix);
float4x4
modelViewProjection =
mul
(
modelView, projectionMatrix);
o.Position =
mul
(
float4
(
P.xyz, 1
.0
), modelViewProjection);
o.Normal =
mul
(
N, (
float3x3
)modelView);
return
o;
}
IV. Conclusion▲
La convention pour les matrices dans OpenGL est column-major alors que les matrices Direct3D sont row-major. Cela explique pourquoi les multiplications de matrices ne sont pas effectuées dans le même ordre entre OpenGL et Direct3D.
Si vous souhaitez jouer avec le shader GLSL (programmation en live), vous pouvez le trouver dans le pack de code de GeeXlab dans le dossier GLSL_ComputePosNorm/ de l'archive. La dernière version de GeeXlab est disponible sur le site de Geeks3D.
Lancez GeeXLab et glissez/déposez le fichier de démonstration (GLSL_Compute_PosNorm.xml) dans le logiciel et c'est tout.
V. Remerciements▲
Cet article est une traduction autorisée de l'article paru sur Geeks3D.com.
Je tiens à remercier Winjerome et dourouc05 pour leur relecture lors de la traduction de cet article, ainsi que ClaudeLELOUP et _Max_ pour leur relecture orthographique.