mercredi 13 août 2008

Une approche tout shader ?

Je commence à réflechir sur les techniques que l'on pourrait utiliser pour rendre de la 2d avec GLSL.
Bien que cela puisse être discutable, il me semble plus interessant d'utiliser des graphismes palettisés plutôt que en couleurs vraies.Tout d'abord, les jeux originaux utilisent peu de couleurs, entre 2 et 16 pour le CPC (31+1 transparente pour le CPC+), 4096 au maximum pour l'amiga, les consoles et les machines arcade utilisent des palettes locales pour les sprites et les arrières plans (généralement 16couleurs).

D'où une définition du nombre de couleurs qui me semble raisonnables serait :
  • 256 couleurs par sprites
  • 256 couleurs par plan de parallax
Techniquement, la gestion des sprites est limite triviale.Les sprites partageant la même palette sont stockés sur la même image 8bits stockée comme texture2D dans un format à une composante (GL_R par exemple).La palette est une texture1D au format RGBA de dimensions 256*1.Ne reste plus qu'a afficher le sprite sous forme de GL_QUAD, GL_TRIANGLES ou encore GL_TRIANGLE_STRIP/FAN avec un shader dans des conditions spécifiques:
  • Unit0 : texture2D,table de sprite, filtre : GL_NEAREST
  • Unit1 : texture1D, palette, filtre : GL_NEAREST
Le shader recupère la donnée sur l'unité de texture 0 et s'en sert comme coordonées de texture du l'unité de texture 1 où il recupère la bonne couleur.

Pout la gestion des plans de parralax, l'idée est aussi simple mais la nature même des plan rend difficile l'utilisation directe sous forme de texture.Les machines utilisant les sprites Hardware 'découpent' les élements graphiques (généralement 16*16), cette technique se prête assez bien à mon projet et on peut utiliser un index pour supprimer les parties redondantes.Donc on a le set de données suivant :
  • Une texture 2d contenant les morceaux du plan (tiles)
  • Une palette RGBA de ce plan
  • Une table d'index contenant l'agencement des tiles
On pourrait alors en utilisant la table d'index calculer chaque tile à afficher et envoyer le tout au shader mais j'ai dans l'idée une autre approche :
  • Unit0 : texture2D,table de tiles, filtre : GL_NEAREST
  • Unit1 : texture1D, palette, filtre : GL_NEAREST
  • Unit2 : table d'indexes, filtre : GL_NEAREST
En utilisant les textures de coordonées et les variables uniformes, on pourrait donner au shader les informations sur où commencer dans la table d'indexes, la taille, etc... Il n'y aurait plus qu'à dessiner un GL_QUAD de la taille l'écran affichable pour afficher le plan.

Avec cette technique, tout le travail d'affichage, du calcul de géométrie jusqu'au dessin en lui même serait confié au shader, d'où mon titre.

Voilà, maintenant ce n'est pas tout d'avoir exposé cette idée, il va falloir l'implementer.Ne me reste plus qu'a trouver quelques sprites et quelques 'backgrounds' et let's get busy !