Voir la version complète : Technique d'affichage en relief
Bonjour
En tombant sur une paire de lunettes en carton avec des filtres rouge et vert, qui servent à voir en relief les dessins faits pour, je me suis dit que ça pourrait être intéressant d'utiliser ce système dans des jeux vidéos.
Je rappelle rapidement le principe :
Une scène 3D est dessinée sur une feuille (ou écran) une fois en rouge, et une fois en vert, avec un léger décalage de point de vue. Sans lunettes, on voit 2 images décalées, mais avec des lunettes laissant passer que la lumière rouge pour un oeil et que la verte pour l'autre oeil, on ne voit plus qu'une seule image (un peu grise), et les objets apparaissent en relief, devant ou derrière la feuille selon leur distance dans la scène 3D. Cette illusion vient du cerveau, qui utilise les différences des images provenant de chaque oeil pour déterminer la distance des objets qu'on observe.
Pour réaliser un tel affichage sur un écran d'ordinateur, je me suis dit qu'il suffisait d'afficher deux fois la scène (scène en niveaux de gris), avec un léger décalage de la caméra, en changeant la couleur de dessin entre les deux passes. Mais il y a un problème : même en remettant le Z-buffer à l'infini entre les deux passes, chaque pixel sera soit rouge, sois vert, alors qu'il faudrait qu'il puisse avoir les deux couleurs, car les deux images sont indépendantes. Il faudrait en fait que chaque passe n'agisse que sur sa composante, sans modifier les autres composantes. Je ne vois pas comment mettre en place ce mécanisme (en OpenGL), sauf en dessinant dans deux buffers séparés, puis en recomposant l'image finale en prenant la composante verte dans l'image verte et la composante rouge dans l'image rouge (j’aimerais éviter cette solution coûteuse en temps et en mémoire).
L'avantage de l'informatique par rapport au dessin est que l'utilisateur pourra ajuster l'affichage en fonction de l'écartement de ses yeux, de sa distance à l'écran, et en fonction de la couleur des lunettes qu'il possède.
Je n'ai pas de projet précis pour utiliser cet affichage, mais la question m'intéresse, et cette technique inspirera sans doute des gens.
Squall.c
01/07/2007, 14h34
Salut,
Je me souvenais d'un moteur 3D qui le faisait, j'ai rechercher et je l'ai retrouvé :
http://forum.games-creators.org/showthread.php?t=3430
Le lien est mort mais j'ai retrouvé cela :
http://yannick.gerometta.free.fr/base.php?id=moteurnavig3d
J'ai pas tout lue mais ca peut te faire une base de recherche ou même tu pourai essayé de le contacter.
la solution m'interresse (juste pour savoir)
Bonne chance.
Merci !
Je suis allé voir sur le 1er lien :
En fait tu fais 2 rendus de la scène, légèrement décalés, pour simuler l'écart que tout être humain normalement constitué a entre ses 2 yeux ^^, puis tu stocke ces 2 rendus dans des textures, tu balance tout ça au shader qui lui te sort une texture, qui correspond a l'image recombinée.
J'ai regardé le pixel shader en question, il se contente de choisir le vert dans la texture de l'oeil droit, le rouge dans la texture pour l'oeil gauche, et fait une moyenne pour le bleu. Ca permet de conserver de la couleur, même si il y a un peu de perte.
Le problème de l'anaglyphe est que la vue fatigue vite (ça fait loucher), ce qui doit expliquer qu'on entende pas parler de jeux qui utilisent cette technique.
J'ai téléchargé la démo du moteur, mais ma carte graphique (Geforce4 MX) n'a pas l'air de gérer ces pixel shaders, donc je n'ai pas pu profiter du mode anaglyphe. :00000012: J'ai juste vus leurs screenshots, qui rendent bien.
Au passage j'ai trouvé une collection de photos des alpes en anaglyphe : http://www.chez.com/alpesstereo/
Au moins j'aurais appris un nouveau mot : anaglyphe. ça aide pour les recherches.
deathangel
01/07/2007, 22h03
Il faudrait en fait que chaque passe n'agisse que sur sa composante, sans modifier les autres composantes. Je ne vois pas comment mettre en place ce mécanisme (en OpenGL), sauf en dessinant dans deux buffers séparés, puis en recomposant l'image finale en prenant la composante verte dans l'image verte et la composante rouge dans l'image rouge (j’aimerais éviter cette solution coûteuse en temps et en mémoire).
j'avais fait un truc du style pour un projet, je t'enverrai le code demain. Côté performance, j'ai pas vraiment vu de différences, et ca marchait plutot bien.
deathangel
02/07/2007, 11h24
voila j'ai retrouvé ma ligne
en fait, il te suffit d'appeler la fonction glColorMask en spécifiant les couleurs autorisées à être écrites
donc ca te donne au final un truc du style :
- glColorMask(0,1,1,1);
- placer la caméra gauche
- rendu des objets
- glColorMask(1,0,0,1);
- placer la caméra droite
- rendu des objets
- glColorMask(1,1,1,1);
- swapBuffer
ca devrait t'aider je pense
Pratique la fonction glColorMask, ça m'évitera de passer par les pixel shaders. J'imagine que dans ton code il y a un glClear(GL_DEPTH_BUFFER_BIT) entre les deux passes.
Ton code affiche le rouge pour un oeil et le cyan pour l'autre. Si on a des lunettes à filtres rouge et vert, il reste à faire la moyenne des deux bleus.
Pour utiliser des textures, en activant le mode modulation (multiplie la couleur courante par la couleur de la texture, composante par composante), avec comme couleur courante (1, 1, 0.5, 1), je pensais m'en sortir, mais la deuxième passe écrase de toute manière le bleu de la première.
Pour le rouge et vert, la solution du pixel shader me semble plus élégante qu'un quelconque bricolage.
Je crois que je vais essayer de me trouver des lunettes à filtres rouge et cyan. Mais de toute manière mon filtre rouge laisse très peu passer le bleu, et le filtre vert le laisse plutôt bien passer, donc ta solution devrait bien convenir à mes lunettes.
deathangel
03/07/2007, 07h16
je n'ai pas de glClear, ca se limite à :
glPushMatrix();
glColorMask(0,1,1,1);
modeAffichage=MODE_AFFICHAGE_FACE;
glLoadIdentity();
maCamera.setCameraG();
modele.dessiner();
glColorMask(1,0,0,1);
glLoadIdentity();
maCamera.setCameraD();
modele.dessiner();
modeAffichage=MODE_AFFICHAGE_STEREO;
glColorMask(1,1,1,1);
glPopMatrix();
ce qui me donne un rendu comme ca :
http://cyril.kern.free.fr/stereo.JPG
par contre les réglages d'espacement sont pas super bien configurés, à voir donc comment ca ressort
J'ai fait des tests.
Si je ne vide pas le depth buffer entre les deux passes (mais je le vide toujours entre 2 frames), je vois apparaître des raies noires, et certaines zones sont noires. Je pense que c'est dû au fait que lors de la seconde passe, certains fragments ne sont pas dessinés, car leur profondeur est légèrement supérieur à celle du pixel de la passe précédente, à cause du décalage de la caméra. C'est peut-être pour cela que sur ton image, on voit des limites franches rouge/vert, sur la portière et sur le capot. Cependant, à d'autres endroits (la roue avant par exemple) le test de profondeur ne semble pas gêner le dessin des deux couches. Ce qui m'intrigue, ce sont ces zones rouges. L'image cyan est complète, mais pas la rouge.
Sinon, j'ai remarqué que lorsque on a une image claire, il faut inverser le sens des lunettes, car une couleur vu à travers le filtre de la même couleur apparaît claire, et se fond dans le reste de l'image, tandis que l'autre couleur apparaît sombre, et est perçue comme étant le détail.
Pour la distance focale, je n'ai pas trouvé de réglage parfait. J'ai surtout remarqué que lorsqu'elle est trop petite, on louche, on voit mal et ça fait mal aux yeux.
deathangel
07/07/2007, 11h00
En fait chez moi, je n'ai pas espacé les caméras, j'ai juste fait une rotation autour du point de focale, c'est peut être pour ca que je n'ai pas besoin d'effacer mon backbuffer, j'ai juste mes deux images qui sont tournées l'une par rapport à l'autre, d'ou la limite franche
Comment ai-je pu passer à côté de cette discussion ????
Pour info, la technique anaglyphe pour reproduire le relief (ou stéréoscopie), reste la plus simple a mettre en oeuvre, mais aussi (ca va souvent de paire) la plus désagréable (niveau confort comme qualité de reproduction), ou presque.
Les drivers NVidia fournissent de base le driver stéréo qui permet de passer n'importe quelle appli 3D en stéréo suivant plusieurs techniques différentes (anaglyphes, séquentiel, ...). Il est possible aussi d'activer l'option directement sous OpenGL (jamais fait de directx), de même que certains drivers (fournis à l'achat de lunettes spécifiques, comme les séquentielles) permettent de passer toute appli en stéréo, avec les drivers NVidia ou ATI (mais marchent moins bien niveau rendu que les drivers NVidia de base).
PAr contre, tout ca c'est pour du windows. Je n'ai pas vraiment encore cherché et encore moins trouvé pour linux !
Merci, j'avais lu quelque chose sur ces drivers, mais j'avais cru que c'était uniquement pour l'utilisation de lunettes spéciales (qui coûtent cher). Je regarderai ça en détail quand j'en aurai le temps (c'est à dire sûrement l'été prochain :( ).
En fait, oui effectivement les drivers demandent souvent de passer par des lunettes, mais pas toujours chers (parfois gratuites dans certaines revues) :
en gros le séquentiel c'est bien (a condition d'avoir un écran >120Hz) mais c'est cher (120€ de mémoire)
l'anaglyphe c'es tpas cher (quasi gratis parfois) mais pas super terrible niveau couleurs
après les autres je sais plus ! (et souvent bien cher)
vBulletin® v.3.6.5, Copyright ©2000-2010, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org