Salut,
Je suis en train d'essayer de projeter une texture sur une scène avec un shader. J'ai lu des tas de choses sur le sujet, je pense avoir compris comment ça fonctionne mais je n'arrive pas à obtenir un bon résultat. Voilà ce que je fais :
1. Calcul de la matrice T transformant les coordonnées d'un vertex V de world space en light clip space :
T = L-1 * PL
L-1 est la matrice qui permet de passer de world space à light space.
PL est la matrice de projection de la light.
2. Je multiplie mon vertex (en world) par cette matrice T et j'obtiens mon vertex en light clip space :
V' = V*T
Normalement ici j'ai :
-V'.w < V'.x < V'.w
-V'.w < V'.y < V'.w
0 < V'.z < V'.w
3. Je procède à la "division de perspective" pour passer en Normalized Device Coordinates :
V' /= V'.w
Maintenant j'ai :
-1.0 < V'.x < 1.0
-1.0 < V'.y < 1.0
0 < V'.z < 1.0
4. Je multiplie enfin V' par la matrice mappant les Normalized Device Coords en coords de texture (entre 0 et 1) :
B = {
{ 0.5, 0.0, 0.0, 0.0 }
{ 0.0, -0.5, 0.0, 0.0 }
{ 0.0, 0.0, 1.0, 0.0 }
{ 0.5, 0.5, 0.0, 1.0 } }
V' *= B
Maintenant j'ai :
0.0 < V'.x < 1.0
0.0 < V'.y < 1.0
0.0 < V'.z < 1.0
qui sont mes coordonnées de texture.
Voilà pour ma méthode. Ca a l'air de fonctionner pour une projection orthographique, mais dès que j'utilise une projection en perspective, la texture projeté est déformée et apparait en dehors du frustum de projection.
Voilà la partie du vertex shader importante :
La question fatidique : d'où vient le problème ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 // matrice permettant de passer des Normalized Device Coordinates // en coordonnées de texture static matrix Bias = { { 0.5f, 0.0f, 0.0f, 0.0f }, { 0.0f, -0.5f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.5f, 0.5f, 0.0f, 1.0f } }; struct CVertexShaderOutput { ... // UV pour la texture projetée float2 LightTextureUV : TEXCOORD2; // UV pour la texture de falloff de la lumière float2 LightTextureW : TEXCOORD3; ... }; VertexShader() { ... // World est la matrice permettant de passer de local en world float4 UVW = mul(input.Position, World); // LightUVMatrix est la matrice T, passant de world en light clip space UVW = mul(UVW, LightUVMatrix); // division pour passer en Normalized Device Coordinates UVW.xyz /= UVW.w; // force w à 1 UVW.w = 1.0f; // mapping [-1,1] -> [0,1] pour x et y (z est déjà entre 0 et 1) UVW = mul(UVW, Bias); // coordonnées pour la texture projetée (2D) output.LightTextureUV.xy = UVW.xy; // La coordonnée y ne sert à rien, la texture de falloff sert de texture 1D, // je la mets arbitrairement à 1.0f output.LightTextureW.xy = float2(UVW.z,1.0f); ... }
Partager