lundi 13 avril 2009

Océan - Une vidéo

Finalement, je suis tombé sur "gtk-recordmydesktop", lequel a été capable de me sortir une vidéo potable. Voilà donc l'animation de l'océan, basée sur C++, SDL, OpenSceneGraph(OSG), et une épaisse couche de shaders GLSL:

video

dimanche 12 avril 2009

La couleur de l'eau

J'ai tout d'abord réessayé le bump mapping, ce qui a donné des résultats tout à fait ridicules. Je me suis ensuite basé sur une texture de flotte assez standard, pour des résultats qui m'ont immédiatement plus plu. Cependant, restait le problème de savoir comment mélanger le reflet et la texture d'eau.

- Addition -> Joli, mais les reflets apparaissent beaucoup plus clairs que l'objet original
- Multiplication -> L'eau est presque noire!
- Max -> A peu près potable si la couleur de l'eau est sombre, fait disparaître des éléments qui devraient être reflétés sinon
- Min -> Situation inverse de max, la couleur de l'eau doit être claire, sinon on perd des reflets

En fait, la couleur de l'eau "sans rien" est vraiment la couleur du ciel réfléchie. Ce que l'on veut vraiment, c'est la couleur du reflet si il existe, et l'océan (de fait, le ciel!) sinon. En modifiant ma caméra de reflet pour qu'elle retourne une couleur de fond transparente, j'ai ensuite combiné mon reflet à mon océan en utilisant la valeur alpha dans mon shader:

gl_FragColor = ocean * (1. - refl.a) + refl * refl.a;

Ainsi, mon océan n'est visible que si mon reflet est transparent (c'est à dire correspond à la couleur de fond), et disparaît lorsqu'un reflet existe.

J'ai même la sourde impression que ce code devrait fonctionner même le jour où je voudrais réfléchir des objets semi-transparents, puisqu'effectivement c'est le ciel qui apparaîtrait au travers.

Et voilà le résultat!

Ocean

Probablement les premières captures qui ressemblent vraiment à quelque chose! J'ai beaucoup diminué l'intensité du mouvement, ce qui semble mieux marcher.


samedi 11 avril 2009

Réflection qui bouge!

Il m'a fallu changer de méthode, et fortement m'inspirer de ce post. Il m'aura quand même fallu pas mal batailler avec le plan de clipping pour que ça rende correctement quelle que soit la position du miroir!

Voilà le résultat, en ayant ajouté au shader la texture de bruit habituelle. Le voir bouger rend bien sûr beaucoup mieux!



Après quelques tests, je me suis rendu compte que la réflexion engendrait quelques soucis: il était possible de sélectionner l'objet reflété, et la boite de sélection dorée se réfléchissait également, ce qui est contraire à l'idée qu'elle n'est que virtuelle. Fort heureusement, après avoir un poil cherché, il est apparu qu'OSG fournissait l'intéressant concept de NodeMask. En mettant un masque spécial sur la partie réfléchie et en mettant un masque opposé sur la recherche d'intersections, l'on élimine la sélection du reflet. Et en mettant un masque particulier sur le rectangle de sélection avec le masque opposé sur la caméra qui regarde le reflet, l'on élimine le rendu sur la partie reflétée. Bingo!

Maintenant, c'est là que tout ce complique. Techniquement, toutes les pièces ou presque sont en place. C'est maintenant un problème artistique que de trouver les bonnes couleurs, textures et paramètres de shader pour faire un rendu d'océan potable (j'allais dire d'eau potable, hey, jeu de mots laid!).

vendredi 10 avril 2009

Réfléchissons

J'ai porté le code de osgreflect pour supporter un miroir plus facile à déplacer par rapport à la scène qu'il reflète. Cela n'a pas été sans mal, mais voilà le résultat. Il reste encore à comprendre pourquoi l'éclairage a soudainement disparu de mon véhicule, et ensuite, le gros morceau: faire un rendu de la scène réfléchie vers un buffer, pour pouvoir le rendre via une texture que je me ferai un plaisir de déformer.

Skysphere, suite et fin (pour le moment)

M skysphere qui me satisfait. Le shader sur laquelle elle est basée est simpliste, mais fait son boulot de fournir un dégradé qui ressemble à quelque chose. Bien sûr, l'ajout d'un soleil, de nuages, d'étoiles et autres esthétismes permettra d'aller un poil plus loin, mais au moins je suis débarrassé de l'horrible fond violet, et l'on va pouvoir commencer à sérieusement s'occuper du sol.



Voilà le shader, qui se contente d'appliquer la coordonnée de texture au composantes rouge et verte. Pour avoir des dégradés un poil plus intéressants, on pourra par exemple se baser sur une texture 1D et l'appliquer sur la longitude.

Vertex shader

varying vec2 texture_coordinate;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
texture_coordinate = vec2(gl_MultiTexCoord0);
}

Fragment shader
varying vec2 texture_coordinate;
void main()
{
gl_FragColor = vec4(texture_coordinate.y, texture_coordinate.y, 1, 1);
}

Shader anneau

Ce qui est intéressant, avec les shaders, c'est qu'il est souvent difficile, à partir d'un certain niveau de complexité, de vraiment percevoir l'effet final avant de l'essayer. Plus encore, l'effet peut dépendre fortement de la géométrie, et en changeant ma boite en sphère, j'ai été étonné d'obtenir une sphère dont le centre devient transparent au fur et à mesure qu'elle s'éloigne.






Bizarre.

La Skysphere, deuxième!

Voilà la capture dont je parlais dans mon post précédent:



Je trouve excellente d'idée sur la mailing-list OSG de dessiner la skybox (ou en ce qui me concerne la skysphere) en dernier, ce qui permet de sauver du pixel shader pour les objets qui se trouveraient devant. Je ne sais pas, par contre, si le culling fonctionne pour les polygones individuels d'une sphère, et donc si la partie de la sphère qui se trouve derrière la caméra est effectivement envoyée à la carte vidéo (dans tous les cas, cela ne va pas m'empêcher de dormir!).

Une skysphere

Avoir un beau ciel, sans avoir à se casser la tête avec des textures et un gros cube: j'ai implémenté en un rien de temps une skysphere en me servant des objets de base d'OSG, et en prenant exemple sur la skybox décrite dans ce mail. Rien de trop compliqué: une sphère, en coordonnées absolues pour qu'elle suive nos mouvements, rendue en dernier, à profondeur maximale. Normalement, l'on voudrait également supprimer le rendu des lumières, et avoir une texture, ou mieux, un beau shader, pour représenter un beau ciel bleu, orageux, au soleil couchant, und so weiter. Mais pour un premier jet, l'éclairage ne rend de fait pas si mal, donc je l'ai gardé encore un peu pour faire une capture. Je poste la chose dès que Blogspot a réparé le transfer des images.

mercredi 8 avril 2009

Encore de la génération de code

Moi qui d'habitude déteste les générateurs de code, voilà que je m'y mets!

Bref, je me suis ré-attaqué à mon générateur de messages, avec l'idée d'y ajouter aussi le code de base de données, pour les messages qui en sont directement extraits. J'ai refactoré violemment, en faisant quelque chose de beaucoup plus construit, et il ne reste plus que quelques détails à implémenter, dont créer un nouveau schéma XML qui permette de définir pour chaque champ s'il doit être transmis et s'il est lié à la base de données.

Le problème, c'est que plus je rend ma génération de code ajustable, plus mon XML va grossir et s'approcher d'une génération à la main!