Naissance d'un shader - étape 1 : le besoin et la recherche.
Mardi 14 octobre 2008 à 15 h 48
Crise financière aidant, j'ai (on) a un peu de temps libre pour developper nos outils. Ayant récemment eu besoin de faire des cheveux, je me suis rendu compte que les outils dont nous disposions étaient insuffisants.
le passé
Jusqu'ici, j'avais developpé des shaders pour fourrures ou poils courts, avec un resultat plutot satisfaisant, aussi bien niveau look que temps de rendu :
(celui ci étant plutot tricky : faire tenir une projection sur des poils qui se deforment)
Ce shader, facile à éclairer, donnant un agréable rendu très doux, donne un resultat peu satisfaisant sur de longs poils !
Hors, problème :
Quand on éclaire une surface en 3d, on calcule en fait des angles. Entre la lumière, le point de vue de la camera et la normale de la surface.

Dans le cas d'une diffusion (ci dessus), C'est l'angle entre les vecteurs de la normale de la surface (N) et la lumière (L).
Cet angle (a) définit l'illumination.
Si l'angle = 0 (lumière perpendiculaire), on éclaire au maximum la surface -> illumination à 100%
Si l'angle = 90 (lumière rasante), on éclaire au minimum la surface -> illumination à 0%
(essayez en vrai avec une lampe torche et une feuille de papier : plus la lampe est perpendiculaire à la feuille, plus elle est "blanche")
Une fonction mathématique simple résout ce modèle : le cosinus.
cosinus de 0 = 1, cosinus de 90 = 0. Angle à 45° ? 70% d'illumination (cosinus de 45 = 0.7)
Si vous avez accès à un programme 3d, vous pouvez vérifier : surface blanche, lampe d'intensité 1, à 45° d'un plan : vous aurez un pixel d'une valeur de 0.7.
Dans le cas de vecteur ce n'est pas un sinus mais un produit scalaire (dot product).
Ce modele mathématique basique s'appelle un lambert. C'est le plus simple, mais on en utilise bien d'autres plus complexes..
votre rendu, avec ou sans poils ? AVEC

cas n°1 avec L1 : L1 et N1(surface) sont perpendiculaire, L1 et N2 (poils) sont parallèles.
cas n°2 avec L2 : L2 et N1(surface) sont parallèle, L2 et N2 (poils) sont perpendiculaire.
Vous aurez peut etre déjà compris le problème : on illumine selon des angles.. Hors, un poil court pousse +- selon la perpendiculaire à la normale.. Si on applique la meme formule sur le poil, là où la surface est censée etre eclairée, le poil sera noir. Et inversement.
-> Le poil devient tres dur à illuminer (des zones sombres apparaissent là où il ne faut pas,...)
Dans les papiers du siggraph 2002, une méthode utilisée pour stuart little a été présentée : copier la normale de la surface à la base du poil et fader le long du poil vers la "vraie" normale, ce qui resoud ce problème.
C'est ce que fait "mon" shader de poil court.
Plus on s'éloigne de la surface, moins on est perpendiculaire.. Et ce qui marche sur des poils courts est inoperant sur des poils longs.. D'où le besoin de supprimer ce "cheat" de normale, et de revenir à un shader de base à peine amélioré.
Je vous passe les maths derrière, mais le modèle mathématique date de 1989 (de Kajiya & Kay).
Résultat :

Suremment fort bien à l'époque, il est loin d'etre convaincant à l'heure actuelle.
Premier gros problème : les reflections. Un cheveux etre tres reflectif, ce qui donne la brillance tant vantée par les pubs pour shampoing. Gardons la diffusion telle quelle, et tweakons un peu les reflections (ou spéculaires), sans cohérence physique réelle (c'est du code "artistique" :)

Je m'étendrais pas sur le code ce shader, ca n'a pas grand interet.
C'est mieux et ça a suffit pour le moment. Mais on a besoin de quelque chose de plus "réaliste" et basé sur une réalité physique.
La recherche
Bon, il faut savoir que les modèles mathématiques utilisés en 3d (temps réel ou non) sont d'abord concus par des mathématiciens ou physiciens. Pas des infographistes.
Pour faire communiquer ces deux mondes, il y a, entre autre, le siggraph. Et du coup, des gens comme lui

(Marschner Steve, nerd plus ou moins incompréhensible)
sortent des papiers comme ça
Je reviendrais dessus.
Ca date de 2003, c'est un modèle plus avancé. Des améliorations de ce modèles ont suivi, jusqu'en 2008
Avant de commencer à lire ces indigestes pages, on recherche d'abord si quelqu'un s'est tapé le boulot de traduction en code, et on lui pique sans lui demander son avis.
Pas de bol ici, ce modèle, utilisé par ilm (depuis star wars) et weta (sur king kong) et en temps réel (demos nvidia), est bien gardé secret par les personnes qui ont passé quelques jours à décoder les formules.
A vrai dire, il est meme vendu par une boite ! http://www.gmp-vfx.com/www/worldwide/src/software2.htm
Il faudra donc se frapper la retranscription du pdf, et c'est là que ça devient passionnant.. Suite au prochain épisode :)
le passé
Jusqu'ici, j'avais developpé des shaders pour fourrures ou poils courts, avec un resultat plutot satisfaisant, aussi bien niveau look que temps de rendu :
(celui ci étant plutot tricky : faire tenir une projection sur des poils qui se deforment)
Ce shader, facile à éclairer, donnant un agréable rendu très doux, donne un resultat peu satisfaisant sur de longs poils !
Hors, problème :
Quand on éclaire une surface en 3d, on calcule en fait des angles. Entre la lumière, le point de vue de la camera et la normale de la surface.
Dans le cas d'une diffusion (ci dessus), C'est l'angle entre les vecteurs de la normale de la surface (N) et la lumière (L).
Cet angle (a) définit l'illumination.
Si l'angle = 0 (lumière perpendiculaire), on éclaire au maximum la surface -> illumination à 100%
Si l'angle = 90 (lumière rasante), on éclaire au minimum la surface -> illumination à 0%
(essayez en vrai avec une lampe torche et une feuille de papier : plus la lampe est perpendiculaire à la feuille, plus elle est "blanche")
Une fonction mathématique simple résout ce modèle : le cosinus.
cosinus de 0 = 1, cosinus de 90 = 0. Angle à 45° ? 70% d'illumination (cosinus de 45 = 0.7)
Si vous avez accès à un programme 3d, vous pouvez vérifier : surface blanche, lampe d'intensité 1, à 45° d'un plan : vous aurez un pixel d'une valeur de 0.7.
Dans le cas de vecteur ce n'est pas un sinus mais un produit scalaire (dot product).
Ce modele mathématique basique s'appelle un lambert. C'est le plus simple, mais on en utilise bien d'autres plus complexes..
votre rendu, avec ou sans poils ? AVEC

cas n°1 avec L1 : L1 et N1(surface) sont perpendiculaire, L1 et N2 (poils) sont parallèles.
cas n°2 avec L2 : L2 et N1(surface) sont parallèle, L2 et N2 (poils) sont perpendiculaire.
Vous aurez peut etre déjà compris le problème : on illumine selon des angles.. Hors, un poil court pousse +- selon la perpendiculaire à la normale.. Si on applique la meme formule sur le poil, là où la surface est censée etre eclairée, le poil sera noir. Et inversement.
-> Le poil devient tres dur à illuminer (des zones sombres apparaissent là où il ne faut pas,...)
Dans les papiers du siggraph 2002, une méthode utilisée pour stuart little a été présentée : copier la normale de la surface à la base du poil et fader le long du poil vers la "vraie" normale, ce qui resoud ce problème.
C'est ce que fait "mon" shader de poil court.
Plus on s'éloigne de la surface, moins on est perpendiculaire.. Et ce qui marche sur des poils courts est inoperant sur des poils longs.. D'où le besoin de supprimer ce "cheat" de normale, et de revenir à un shader de base à peine amélioré.
Je vous passe les maths derrière, mais le modèle mathématique date de 1989 (de Kajiya & Kay).
Résultat :

Suremment fort bien à l'époque, il est loin d'etre convaincant à l'heure actuelle.
Premier gros problème : les reflections. Un cheveux etre tres reflectif, ce qui donne la brillance tant vantée par les pubs pour shampoing. Gardons la diffusion telle quelle, et tweakons un peu les reflections (ou spéculaires), sans cohérence physique réelle (c'est du code "artistique" :)

Je m'étendrais pas sur le code ce shader, ca n'a pas grand interet.
C'est mieux et ça a suffit pour le moment. Mais on a besoin de quelque chose de plus "réaliste" et basé sur une réalité physique.
La recherche
Bon, il faut savoir que les modèles mathématiques utilisés en 3d (temps réel ou non) sont d'abord concus par des mathématiciens ou physiciens. Pas des infographistes.
Pour faire communiquer ces deux mondes, il y a, entre autre, le siggraph. Et du coup, des gens comme lui

(Marschner Steve, nerd plus ou moins incompréhensible)
sortent des papiers comme ça
Je reviendrais dessus.
Ca date de 2003, c'est un modèle plus avancé. Des améliorations de ce modèles ont suivi, jusqu'en 2008
Avant de commencer à lire ces indigestes pages, on recherche d'abord si quelqu'un s'est tapé le boulot de traduction en code, et on lui pique sans lui demander son avis.
Pas de bol ici, ce modèle, utilisé par ilm (depuis star wars) et weta (sur king kong) et en temps réel (demos nvidia), est bien gardé secret par les personnes qui ont passé quelques jours à décoder les formules.
A vrai dire, il est meme vendu par une boite ! http://www.gmp-vfx.com/www/worldwide/src/software2.htm
Il faudra donc se frapper la retranscription du pdf, et c'est là que ça devient passionnant.. Suite au prochain épisode :)
Real time hair, siggraph
Hair rendering in Nalu demo
Et si tu as besoin d'aide sur leur implémentation parfois tu peux tenter d'emailer leurs auteurs (et certains parlent français d'ailleurs..).
Le plus compliqué est stocké dans une lookup table générée dans une passe, et qu'ils se gardent bien de publier :)
et rien dans le SDK touchant de pret ou de loin à ça , comme par hazard :)
Visiblement, certaines boites ayant investi dans ce code, voyent d'un mauvais oeil la diffusion publique des sources..
Le plus proche trouvable sur internet, c'est ça :
http://www.gamedev.net/community/forums/topic.asp?topic_id=478561
Mais t'inquiètes pas, tu verras dans 3 jours qu'avoir un patron qui a publié ce genre de truc : http://portal.acm.org/citation.cfm?id=646257.685550&coll=GUIDE&dl=&CFID=15151515&CFTOKEN=6184618 aide pas mal à debrouissaller les maths :)
C'est pas un résumé au jour le jour, on est bcp plus loin que ça :-)
rien compris au titre :/
ya pas un pdf accessible quelque part ?
Par contre en shader j'y connais rien ! :)