Résumé
Temps de
développement :
Environ 2 mois
Librairies:
OpenGL, GL4D, SDL2, Assimp
Restrictions :
L'archive devait faire moins de 64Mo
Beholder est une démo en temps réel que j'ai réalisée dans le cadre de mon cours de synthèse d'images . Je l'ai ensuite présentée dans la Track 1 du concours API8 2026 d'où elle est sortie gagnante face à une dizaine d'autres démos.
Sur cette page, je reviendrais succintement sur les différentes techniques implémentées pour cette réalisation :
L'Effet vieille pélicule
Pour cette démo, je voulais essayer d'imiter le style visuel de la pélicule
abimée que l'on peut trouver dans les représentations contemporaines de
certains films des années 20-30. De plus, je voulais essayer de travailler
le noir et blanc tel qu'il peut l'être avec une pellicule, c'est-à-dire
rendre des modèles en couleurs et les post-traités dans le fragment shader.
Tout cet effet est donc réalisé dans le fragment shader.
Pour le noir et blanc, j'utilise les valeurs de luminances classiques du pixel que passe ensuite par une fonction sigmoïde pour tirer les valeurs vers le noir et le blanc et donner un effet brulé à l'image.
Pour les effets de dégâts de la pellicule, je sample simplement un bruit en fonction de la position du pixel dans l'écran.
Enfin, je rajoute des barres noires sur les côtés de l'image pour rendre un format 4:3 qui est celui des pellicules d'époque.
Tentacules
Les tentacules du monstres sont définies comme des courbes de béziers que j'interpole entre elles pour obtenir une animation. J'utilise par ailleurs la même structure de courbe de bézier pour les déplacements d'objets ou de la caméra dans l'espace.
Pour dessiner ces courbes de bézier, j'utilise un plan que "j'enroule" dans le vertex shader pour obtenir un cylindre. Je map ensuite ce cylindre sur la courbe de bézier et je réduit son diamètre en fonction de la distance à la base pour obtenir l'effet désiré.
Herbe et shell texturing
Ayant du temps de disponible, j'ai voulu rajouter de l'herbe dans le projet. Pour cela, j'ai utilisé une technique nommée shell texturing.
Pour chaque modèle concerné, dans le geometry shader, je regarde si la normale du plan pointe vers le haut, c'est-à-dire qu'il s'agit d'un plan de sol. Si c'est le cas, je répète le plan une dizaine de fois vers le haut.
Dans le vertex shader ensuite, pour chacun de ces plans, je choisis de dessiner le pixel ou non en fonction d'un bruit blanc. Cela donne des brins d'herbe de taille variées et avec une densité suffisante, l'effet est assez subtil pour est agréable dans cette démo.
L'Eau
Pour faire l'eau dans ce projet, j'utilise une simple fonction de somme de sinus dans le vertex shader. J'ai deux types de vagues : les vagues directionnelles qui s'appliquent tout le temps et représentent les vagues générales de la mer et les vagues positionnelles qui représentent les vagues émannent d'un objet dans l'eau (tentacules, monstre, etc).
De plus, mon ciel est réalisé avec une cube map, je peux alors facilement la sampler pour créer de belles réflections de la lune et des étoiles sur l'eau.