Pour afficher des ombres douces, vous avez besoin d'une carte 3D avec :
L'idée de base est d'afficher plusieurs ombres en secouant la source lumière, et de les mélanger.
Comme une GeForce n'est pas assez rapide pour afficher tous ces volumes en même temps, on utilisera de la coherence temporelle pour la simuler.
Pendant le calcul d'une image, on affichera le volume courrant, et on le mélangera à ceux des quelques images précédentes. Cette idée est basée sur l'effet de Motion Blur rapide de la Demoscene.
On va additionner les volumes dans le buffer Alpha. Les différentes étapes de l'algorithme sont :
Pour déplacer la lumière, je la place à Position+un de ces 8 déplacements :
Image | X | Y | Z |
0 | -SIZE | -SIZE | -SIZE |
1 | +SIZE | +SIZE | -SIZE |
2 | -SIZE | +SIZE | +SIZE |
3 | +SIZE | -SIZE | +SIZE |
4 | -2*SIZE | -2*SIZE | -2*SIZE |
5 | +2*SIZE | +2*SIZE | -2*SIZE |
6 | -2*SIZE | +2*SIZE | +2*SIZE |
7 | +2*SIZE | -2*SIZE | +2*SIZE |
Comme vous pouvez le voir, j'ai choisi 4 coins de 2 cubes autour de la lumière, afin qu'il y ait aussi peu de positions partagant un même plan. Ainsi aucun volume ne sera totalement inclu dans les autres.
Le Fade out est fait en affichant un quadrilataire par dessus l'écran avec les couleurs et blendings suivant :
glColorMask( GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE ); glBlendFunc(GL_ZERO,GL_SRC_ALPHA); glColor4f(0,0,0,0.95f);
Quand la lumière bouge, on peut au choix agiter ou non la lumière. Les deux méthodes fonctionnent en donnant des résultats très similaires.
Le problème quand la caméra bouge est que les volumes précédents ne sont pas placés correctement.
Si le taux d'affichage est élevé, l'erreur dans le positionnement des volumes précédents reste peu éleve.
Si l'affichage est plus lent, ces erreurs deviennent trop important et il faut réduire le nombre de volumes affichés, en faisant un fade out plus rapide.
J'utilise en général 8 volumes quand la caméra est statique et 2 volumes quand elle bouge.
Sur une carte 3D plus rapide, on peut afficher tous les volumes à chaque image calculée :
For volume = 0 To MaxVolume
Main page | email : Sly |