1

Je préviens : je débute avec openGL et avec le GLSL.
J'ai un model que je souhaite ombrer grâce au vertex shader. J'essais de suivre ce tuto.
J'ai donc :
 varying float intensity;             // passe du vertex shader au pixel shader.
 uniform vec3 lightDir;              // que j'envoi du code principal

et ensuite :
intensity = dot(lightDir, gl_Normal);

Comment envoyer cette normal au pixel shader?

Dans le tuto, il y a écrit:
The vertex shader has access to the normals, as specified in the OpenGL application, through the attribute variable gl_Normal. This is the normal as defined in the

OpenGL application with the glNormal function, hence in model local space.


Dans mon code, je rempli mon tableau de vertices comme ça:
mVertices[id] = point1;

et je me demande donc comment et ou appeller glNormal ? Et ce que ça fait. (la doc n'est pas clair)

Dois-je calculer le vecteur "normal" de mon vertex et l'envoyer, comme ça : glNormal3f(normal.x,normal.y,normal.z); ?
Dans ce cas, comment est associée cette valeur à mon vertex, qui lui est envoyé dans un tableau ?

2

Je n'ai jamais utilisé GLSL avec OpenGL, mais j'imagine qu'il suffit que tu fasses exactement comme tu fais déjà avec tes vertex, en utilisant les appels équivalents pour passer des normales, non ?

Soit tu utilises glVertex3f & co et il te faudra ajouter pour chaque vertex un appel supplémentaire à glNormal3f pour spécifier la normale, soit tu utilises glVertexPointer et tu auras besoin d'un appel à glNormalPointer avec un tableau de même dimension dans lequel à chaque indice [i] il aura la normale du vertex [i].

Après, il me semble avoir lu que tout ça était deprecated et qu'il était plus mieux d'appeler glVertexAttribPointer & co, sauf que ça ne te renseignera pas automatiquement les variables gl_Vertex et gl_Normal, il faudra que tu déclares tes propres attributs (mais ça n'est pas plus compliqué). Quelqu'un qui s'y connait pourra peut-être confirmer ou non smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

Merci pour ta réponse.
Le lancement du vertex shader est lancé par glVertex ou gl_Normal il me semble? Donc pas au même moment, et j'ai l'impression que mon vertex ne contiendra pas la normale.
Est-ce d'ailleur possible, puisque la normale est celle de la face, donc de 3 vertex. Dans le pixel shader ça me poserait moins de problème de compréhension.

4

Par "lancé" tu veux dire exécuté ? Parceque la procédure qui appelle ton vertex shader et ton pixel shader n'est lancée qu'une seule fois pour tout le rendu, donc après tous tes appels à glVertex et glNormal. La seule contrainte est d'avoir appelé autant de fois glVertex que glNormal (enfin je suppose, je n'ai jamais utilisé cette technique) et tu pourras automatiquement accéder dans ton vertex shader à la normale correspondant à chaque vertex.

Théoriquement, la notion de vecteur normal est associé à une face, mais en pratique ça provoquerait des rendus assez moches (imagine un sol constitué de petits carrés avec des orientations différentes, chaque carré aurait un éclairage uniforme et différent de son voisin à côté, à cause de son orientation, ça serait pas terrible). Du coup on calcule plutôt un vecteur normal par vertex (si le vertex est partagé entre plusieurs faces, ça sera la "moyenne" des normales de chacune de ces faces, c'est à dire la somme normalisée de chaque normale), ce qui permet d'interpoler linéairement la normale en chaque point de ta surface.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

La normale est celle de la surface, mais la normale peut avoir une différente en chaque point de la surface. Il ne faut simplement pas penser surface = face = triangle, car le triangle n'est que la manière de représenter (approximer la plupart du temps) la vraie surface. (face = triangle c'était au temps du flat shading, mais de nos jours ça n'a plus vraiment de sens, en dehors des objets cubiques ^^)
Un cube par exemple, c'est six surfaces planes que tu approximes à chaque fois par au moins deux triangles droits. Et qui dit plan dit vecteur normal constant.
Mais une sphère, c'est une seule surface, sphérique, que tu approxime par plein de petites faces triangulaires. Mais le vecteur normal n'est pas constant. (C'est en gros le "vecteur rayon vers le point" normalisé)

En plus, les points ne peuvent pas être réutilisés entre plusieurs faces planes. Par exemple, avec les normales, un cube ce n'est pas seulement 8 points, mais c'est 6*4=24 points.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

6

Un point peut tout à fait être réutilisé entre plusieurs faces planes, il suffit de calculer une normale moyenne à partir des normales de chaque surface qui utilise ce point :

tnormals.gif

Dans certains cas ça permet d'ailleurs d'éviter d'avoir des réflexions de lumière très différentes d'un pixel à l'autre (et donc irréalistes), juste parceque l'un de ces deux pixels était sur la face 1 et l'autre sur la face 2.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

7

avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

8

Je crois que tu es un peu en avance par rapport au topic, mais ça reste un lien intéressant ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

Je vais modifier ma classe VBO pour ajouter les normales avec glNormal.
Si je comprend bien, je peux même appeler glNormal lors de la construction des triangles, quand je fais " mVertices[id] = point1; " puisque le shader est appelé à la fin. Par contre ce sera moins propre et moins rapide que d'envoyer un normalbuffer, mais pour le moment c'est pour tester.
J'avais peu peur que ça ne serve à rien, car je pensais que le pixel shader était appelé par glVertex. (et donc aussi souvent)
Du coup, ça devrait donc se faire quasi tout seul.
Merci pour vos réponses.