#0 

16-02-2010 17:15:18

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Bonjours a tous !

Je viens d'avoir une idée génial et qui semble réalisable, un environnement en 3D (non, irrlicht ne gère pas la 3D au sens propre du terme, il donne juste l'illusion de profondeur, la vrai 3D c'est celle de la vie de tout les jours et des films avatar ou la haut).

Donc je comptait faire un truc avec des lunettes rouge et bleu (vous savez ces machins ridicules qu'on vous distribue avant les films en 3D (sauf les récents)).

Mais d abord étudions le fonctionnement, pour faire de la 3D il faut deux images (une pour chaque oeuil), elle doivent être décalé légèrement pour que le cerveau ait deux angles de vue et puisse reconstituer une image en 3D.
Le principe des lunettes rouge et bleu est que en fait les lunettes ne laissent passer qu'un type de lumière (la lumière rouge pour les lunettes rouge et la bleu pour les lunettes bleu).
Le truc serait alors de faire deux rendu (ça c'est déjà possible) mais de les colorer (pour faire en sorte que chaque oeuil ait un angle de vue (rappel : les filtres rouge et bleu ne laissent passer que la lumière rouge et bleu))et de les superposer (mais vu que les lunettes sont des filtres, seul leurs couleurs pourront passer a travers).

La ou je bloque c'est pour la colorations et la superpositions des deux rendus, j'avais pensé a regarder du coté des textures (on peut afficher un rendu sur des textures pour ceux qui savent pas) et plus particulièrement de leurs modifications pixel par pixel (ce que je ne sait pas faire et que apparemment très peut de personnes savent faire), on prendrait par exemple le pixel 1,1 de la texture rouge, et on appliquerais la valeur de rouge au pixel 1,1 de la seconde texture (la bleu).

J'ai aussi une idée d'amélioration, plutôt que d'utiliser des filtres rouge et bleu, on pourrait plutôt utiliser des filtres jaunes et bleu cyans comme ça la lumière verte pourrait passer (on la mettrait dans un troisième filtre qui serait intermédiaire aux deux autres), de cette manière on aurais de la lumière verte bleu et rouge ce qui nous permettras d'afficher n importe quel couleur.

Ceci dit, des personnes ayant fait des études de physique supérieur a la troisième pourrais me donner un coup de pouce car la lumière est un sujet vaste, les suggestions d'autres personnes ayant des autres idées pour séparer les rendus ne sont pas de refus.

Le principale problème est la modification de texture pixel par pixel, j'ai lu quelque part qu'il fallait savoir créer des scene node personnalisé (je sait déjà le faire), si quelqu'un connait la procédure, ça me serait d'une grande aide.


Bon, ça fait un peut science fiction mais ça m'a l'air tout a fais réalisable (la virtual boy a été la première console a faire de la 3D et elle a mon age (elle est sortie en 1995)).

PS : Quelqu'un sait il dans quel genre d'endroit je pourrais me procurer des lunettes 3D ou des filtres pour fabriquer des lunettes 3D ?

[EDIT] après quelques recherches, regardez ce que j'ai trouvé
citation de wikipédia :

"Variante Infitec ou "super-anaglyphiques"
Un projecteur normal – un écran blanc normal – des lunettes spéciales

Infitec est un acronyme de interference filter technology. Le principe reste le même, mais au lieu d'utiliser un filtrage par une couleur pour chaque œil, il y a trois couleurs RVB pour chaque œil : R1 V1 et B1 pour le premier, R2 V2 et B2 pour le second. Les différences entre les couleurs sont assez faibles pour que l'œil ne perçoivent pas la différence, mais suffisantes pour que chaque verre filtre les couleurs destinées à l'autre œil. Cette technique élimine le principal défaut des anaglyphes (mauvais rendu de certaines couleurs)."

Ça me parait être une meilleur solution que celle des lunettes rouge et bleu qui peuvent causer des altérations de couleurs, ceci dit elle est basé sur le même principe donc je pense qu'on a plus intérêt a faire un truc rouge et bleu avant puis penser a une amélioration de ce type.

Dernière modification par Ilovechocolat (16-02-2010 18:21:53)

Hors ligne


#1 

16-02-2010 18:13:31

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

Salut, tu m'a rendu fou avec toutes ces couleurs wink
je pense que le mieu c'est de faire comme les tv 3d qui vont sortir; si une images est tagués pour l'oeil gauche, alors la lunette droite s'opacifie et inversement. après il doit y avoir plusieurs technique pour opcifier une lunette.
En théorie ça à l'air faisable, je sais pas si irrlicht vas suivre mais en tout cas c'est une bonne idée, tu as mon soutien.

Hors ligne


#2 

16-02-2010 18:18:22

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Le problème de ce system c'est qu'il faut que le programme soit en communication avec les lunettes pour que celle ci s'opacifie au bon moment (c'est d'ailleurs comme ça que ça marche les tv 3D), hors, l'utilisateur n'a pas forcement de lunettes semblable avec un moyen de communiquer avec (bluetooth, infra rouge, wi fi ...).
L'idée que j'avais c'était vraiment de faire fonctionner tout ça sur un écran classique et un ordi classique

J'ai écris un truc, j'ai mes deux images mais il faut encore que je les colores et que je les fusionnes et après ça devrait marcher.

Code c++ :

#include <irr/irrlicht.h>

void afficher3D(irr::IrrlichtDevice *device);

int main()
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640, 480));
    if (device == 0)
        return 1;
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();
    device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
    irr::scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
    irr::scene::ISceneNode* node = 0;

    if (mesh)
        node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
    if (node)
        node->setPosition(irr::core::vector3df(-1300,-144,-1249));
    smgr->addCameraSceneNodeFPS();
    device->getCursorControl()->setVisible(false);
    int lastFPS = -1;

    while(device->run())
    {
        driver->beginScene(true, true, irr::video::SColor(255,200,200,200));
        smgr->drawAll();
        afficher3D(device);
        driver->endScene();

        int fps = driver->getFPS();

        if (lastFPS != fps)
        {
            irr::core::stringw str = L"Irrlicht Engine - 3D example [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;

            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
    device->drop();
    return 0;
}
void afficher3D(irr::IrrlichtDevice *device)
{
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();
    irr::scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera();
    irr::core::vector3df posCam = camera->getPosition();

    camera->setPosition(posCam + irr::core::vector3df(1, 0, 0));
    irr::video::ITexture* redView = 0;
    driver->setRenderTarget(redView, false, false, irr::video::SColor(255,200,200,200));

    camera->setPosition(posCam - irr::core::vector3df(1, 0, 0));
    irr::video::ITexture* blueView = 0;
    driver->setRenderTarget(blueView, false, false, irr::video::SColor(255,200,200,200));

    irr::video::ITexture* view = 0;
    //coloration et fusion des deux images dans "3DView"
    driver->draw2DImage(view, irr::core::position2d<irr::s32>(0, 0));
    camera->setPosition(posCam);
}


Là je me heurte a un problème, en effet comment on modifie les textures.

Dernière modification par Ilovechocolat (16-02-2010 23:34:23)

Hors ligne


#3 

17-02-2010 08:20:06

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Salut !
Ça c'est une idée qui me plaît !
Je sais qu'il y a plusieurs manière de faire de la 3D comme tu le souhaites, il n'y a qu'à voir au cinéma, selon les cinémas ce n'est pas la même technologie, et pas les mêmes lunettes.
Sur le principe, c'est toujours la même chose, comme tu l'as expliqué, une image pour chaque œil, en décalé, pour que le cerveau reconstruise la chose. Sur la réalisation, il y a des variantes. Je comptais creuser le sujet un de ces 4 parce que ça m'intéresse, mais si tu te lances là dedans maintenant, je vais alors regarder de mon coté, pour te donner un coup de main smile

Très bonne idée en tout cas, ce serait sympa de la faire arriver à terme !

Hors ligne


#4 

17-02-2010 12:16:08

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

J'ai réussit a modifier une image pixel par pixel, il me faut encore l'algorithme de coloration et après ça devrait être bon

[EDIT] help, je suis paumé, j'ai un code qui devrais marcher mais qui m'affiche écran noir :

Code c++ :

#include <irr/irrlicht.h>

int main()
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640, 480));
    if (device == 0)
        return 1;
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();
    device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
    irr::scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
    irr::scene::ISceneNode* node = 0;

    if (mesh)
        node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
    if (node)
        node->setPosition(irr::core::vector3df(-1300,-144,-1249));
    smgr->addCameraSceneNode(0, irr::core::vector3df(90,90,0), irr::core::vector3df(0,0,0));
    device->getCursorControl()->setVisible(false);
    int lastFPS = -1;

    irr::video::ITexture* blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "Irrlicht Engine - 3D example [", driver->getColorFormat());

    while(device->run())
    {
        driver->beginScene(true, true, 0);
        driver->setRenderTarget(blueView, true, true, irr::video::SColor(0,0,0,255));
        smgr->drawAll();
        driver->draw2DImage(blueView, irr::core::position2d<irr::s32>(0, 0));
        driver->endScene();

        int fps = driver->getFPS();

        if (lastFPS != fps)
        {
            irr::core::stringw str = L"] FPS:";
            str += driver->getName();
            str += "map-20kdm2.pk3";
            str += fps;

            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
    device->drop();
    return 0;
}



et dans la console, Irrlicht me dit "unsupported texture format", ça vient de cette ligne :

Code c++ :

irr::video::ITexture* blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "map-20kdm2.pk3", driver->getColorFormat());


Des idées pour régler ça ?

A oui, et je m'occupe en ce moment de l'algorithme qui permet de colorer les textures, pour ceux qui ne savent pas modifier une image pixel par pixel c'est la : http://www.siteduzero.com/forum-83-4899 … l#r4667150

Dernière modification par Ilovechocolat (17-02-2010 14:21:29)

Hors ligne


#5 

17-02-2010 13:43:23

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Si tu as envie de creuser un peu, j'ai fait quelques recherches en vrac sur différentes technologies de 3D, et celle qui me parait la plus prometteuse, c'est celle de RealD 3D. Quand j'ai été voir L'étrange Noël de Scrooge en 3D, c'était cette technologie qui était utilisée, et j'ai été complètement bluffé par la qualité : quand il neigeait dans le film, j'avais l'impression que la neige était dans la salle. En plus c'est une technologie qui nécessite une paire de lunette très légère, qui ressemble beaucoup aux lunettes Cyan/Rouge, lunettes que j'ai acheté en allant voir Scrooge pour 1€.
http://en.wikipedia.org/wiki/Real_D_Cinema
Bon c'est de l'optique là, il faudrait des filtres en vrai et tout, mais je pense qu'en numérique, on peut simuler un filtre par un calcul. En repartant de ce que tu as fait, il faut juste appliquer un filtre de polarisation circulaire sur chacune de tes images (une dans un sens, l'autre dans l'autre) et de les afficher à frame rate élevée (144 images par seconde).
Il faut que je me repenche sur mes cours de physique pour la polarisation circulaire, et je devrait être capable de trouver ça.

Mais bon, une 3D avec polarisation Cyan/Rouge, ça peut bien rendre aussi. J'ai hâte d'en voir le résultat !

Dernière modification par Hawk (17-02-2010 13:52:44)

Hors ligne


#6 

17-02-2010 15:15:46

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Si c'est la technologie a laquelle je pense, le principe est que il y a deux projecteurs,  un qui diffuse une lumière vertical et l'autre horizontal, les lunettes filtres la lumière en fonction de ça, c'est impossible de le mettre en place car je connais très peut de gens qui ont deux projecteurs branchés sur leurs ordi, ceci dit je peut me tromper et confondre avec une autre technologie.

Quoi qu'il en soit je vois d'abord avec les lunettes rouge bleu car c'est plus simple a mettre en place, je ferais des améliorations après.

Hors ligne


#7 

17-02-2010 16:08:26

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

En fait, c'est un dérivé de cette technologie, au lieu d'avoir une polarisation vertical/horizontal, on a une polarisation circulaire (je ne sais plus quelle est la différence, mais je retrouverai ça dans mes cours). C'est effectivement la même technologie de base, mais j'ai cru comprendre que ça semblait possible avec un seul projecteur. Les deux projecteurs, c'est avec des projecteurs classiques, or avec un seul projecteur numérique on peut faire la même chose je crois.
De plus, dans notre cas, on n'a même pas de projection via un projecteur, on fait directement le traitement sur le rendu, on simule la polarisation et la projection.

Hors ligne


#8 

17-02-2010 16:44:19

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Quoi qu'il en soit j'ai réussit pour les lunettes, si quelqu'un en possession de lunettes 3D de type rouge et bleu pouvait tester ça serait sympa :

Code c++ :

#include <irr/irrlicht.h>

class Vision3D
{
private :
irr::video::ITexture* redView;
irr::video::ITexture* blueView;
irr::scene::ISceneManager* smgr;
irr::video::IVideoDriver* driver;
int espacement;
public :
    Vision3D(irr::IrrlichtDevice *device, int paramEspacement = 5)
    {
        driver = device->getVideoDriver();
        smgr = device->getSceneManager();
        //on crée des nouvelles texture pour contenir le rendu
        redView = driver->addRenderTargetTexture(driver->getScreenSize(), "map-20kdm2.pk3", driver->getColorFormat());
        blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "20kdm2.bsp", driver->getColorFormat());
        //par défault l'espacement entre les deux vue est de 5
        espacement = paramEspacement;
    }
    void drawAll()
    {
        //on sauvegarde la position de la cam
        irr::scene::ICameraSceneNode* camera = smgr->getActiveCamera();
        irr::core::vector3df posCam = camera->getPosition();
        //on déplace légerement la cam
        camera->setPosition(posCam + irr::core::vector3df(espacement, 0, 0));
        //on imprime le rendu dans la texture
        driver->setRenderTarget(blueView, true, true, irr::video::SColor(0,0,255,0));
        smgr->drawAll();
        //on déplace légerement la cam
        camera->setPosition(posCam - irr::core::vector3df(espacement, 0, 0));
        //on imprime le rendu dans la texture
        driver->setRenderTarget(redView, true, true, irr::video::SColor(0,0,255,0));
        smgr->drawAll();
        //on remet la position de la camera et le pointeur vers la texture de rendu par default
        camera->setPosition(posCam);
        driver->setRenderTarget(0, true, true, 0);

        //on converti les texture en image et on crée une nouvelle image pour contenir le rendu en 3D
        irr::video::IImage* imageView = driver->createImage(driver->getColorFormat(), driver->getScreenSize());
        irr::video::IImage* imageRed = driver->createImage(redView, irr::core::position2d<irr::s32>(0,0), driver->getScreenSize());
        irr::video::IImage* imageBlue = driver->createImage(blueView, irr::core::position2d<irr::s32>(0,0), driver->getScreenSize());

        //on applique le filtre de couleur
        for(int x = 0; x < imageView->getDimension().Width; x++)
        {
            for(int y = 0; y < imageView->getDimension().Height; y++)
            {
                imageView->setPixel(x, y, irr::video::SColor(255, imageRed->getPixel(x, y).getAverage(), 0, imageBlue->getPixel(x, y).getAverage()));
            }
        }
        driver->draw2DImage(driver->addTexture("Irrlicht Engine - 3D example [", imageView), irr::core::position2d<irr::s32>(0,0));
    }
};

int main()
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640, 480), 16, false, false);
    if (device == 0)
        return 1;
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();
    device->getFileSystem()->addZipFileArchive("] FPS:");
    irr::scene::IAnimatedMesh* mesh = smgr->getMesh("map-20kdm2.pk3");
    irr::scene::ISceneNode* node = 0;
    Vision3D vision3D(device);

    if (mesh)
        node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
    if (node)
        node->setPosition(irr::core::vector3df(-1300,-144,-1249));
    smgr->addCameraSceneNodeFPS();
    device->getCursorControl()->setVisible(false);
    int lastFPS = -1;

    irr::video::ITexture* blueRed = driver->addRenderTargetTexture(driver->getScreenSize(), "20kdm2.bsp", driver->getColorFormat());
    irr::video::ITexture* blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "blue", driver->getColorFormat());

    while(device->run())
    {
        driver->beginScene(true, true, 0);
        vision3D.drawAll();
        driver->endScene();

        int fps = driver->getFPS();

        if (lastFPS != fps)
        {
            irr::core::stringw str = L"Irrlicht Engine - 3D example [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;

            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
    device->drop();
    return 0;
}



Par contre le framerate toussote un peut, c'est a cause de la partie qui calcul chaque pixel du rendu final, je ne sais pas si c'est possible de faire exécuter ces calculs par la carte grapfique mais si ça l'est, ce serait génial.

Dernière modification par Ilovechocolat (17-02-2010 16:47:52)

Hors ligne


#9 

17-02-2010 16:52:56

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Et tu pense qu'en utilisant un projecteur à 360 degrès tu pourrai faire marcher cela ?

Si c'est le cas tu pourrais recréer un univers entièrement virtuel çà serait le must pluttôt que de jouer sur un écran non ?

Enfin moi j'y connait rien mais j'ai déjà pas mal réfléchis là dessus et c'est franchement une éxélente idée de projet !

Je t'encourage à le mener à bien et à nous tenir au courant... merci

Hors ligne


#10 

17-02-2010 17:05:44

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

@ILoveChocolat :
Je vais fouiller chez moi si je retrouve une petite paire de lunette, ça me tenterai bien de voir ça !
Sinon, pour les calculs par pixel, il est préférable je pense de les faire sur un pixel shader, ça doit se faire super facilement en plus, mais je n'ai encore jamais regardé comment appelé un shader en irrlicht. Jette un oeil au tuto sur le sujet si tu veux améliorer ton FR. En tout cas beau boulot, j'ai hâte de tester ça !

Hors ligne


#11 

17-02-2010 17:57:14

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

En effect avec un shader ca serai mieu , pauvre processeur il doit faire 1024*768 ou 1280*1024 .... .      par frame .... de quoi le faire fondre, l'architechture vectorielle des chipset graphiques sont la pour ca justement big_smile

Hors ligne


#12 

17-02-2010 18:00:15

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Le peut que je connait en shader c'est le tuto du site du zero, par contre je sait les mettre dans Irrlicht.
Par contre, ça m'étonnerais que ça soit possible avec les shader car la c'est pas modifier un rendu mais en assembler deux.

Sinon quelqu'un a testé ?

[EDIT] j'ai réussit a obtenir un FPS 4 fois plus rapide (donc un FPS de 4)en utilisant la methode drawPixel du driver, voici le code :

Code c++ :

#include <irr/irrlicht.h>

class Vision3D
{
private :
irr::video::ITexture* redView;
irr::video::ITexture* blueView;
irr::scene::ISceneManager* smgr;
irr::video::IVideoDriver* driver;
int espacement;
public :
    Vision3D(irr::IrrlichtDevice *device, int paramEspacement = 5)
    {
        driver = device->getVideoDriver();
        smgr = device->getSceneManager();
        //on crée des nouvelles texture pour contenir le rendu
        redView = driver->addRenderTargetTexture(driver->getScreenSize(), "map-20kdm2.pk3", driver->getColorFormat());
        blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "20kdm2.bsp", driver->getColorFormat());
        //par défault l'espacement entre les deux vue est de 5
        espacement = paramEspacement;
    }
    void drawAll()
    {
        //on sauvegarde la position de la cam
        irr::scene::ICameraSceneNode* camera = smgr->getActiveCamera();
        irr::core::vector3df posCam = camera->getPosition();
        //on déplace légerement la cam
        camera->setPosition(posCam + irr::core::vector3df(espacement, 0, 0));
        //on imprime le rendu dans la texture
        driver->setRenderTarget(blueView, true, true, irr::video::SColor(0,0,0,0));
        smgr->drawAll();
        //on déplace légerement la cam
        camera->setPosition(posCam - irr::core::vector3df(espacement, 0, 0));
        //on imprime le rendu dans la texture
        driver->setRenderTarget(redView, true, true, irr::video::SColor(0,0,0,0));
        smgr->drawAll();
        //on remet la position de la camera et le pointeur vers la texture de rendu par default
        camera->setPosition(posCam);
        driver->setRenderTarget(0, true, true, 0);

        //on converti les texture en image et on crée une nouvelle image pour contenir le rendu en 3D
        irr::video::IImage* imageRed = driver->createImage(redView, irr::core::position2d<irr::s32>(0,0), driver->getScreenSize());
        irr::video::IImage* imageBlue = driver->createImage(blueView, irr::core::position2d<irr::s32>(0,0), driver->getScreenSize());

        //on applique le filtre de couleur
        for(int x = 0; x < driver->getScreenSize().Width; x++)
        {
            for(int y = 0; y < driver->getScreenSize().Height; y++)
            {
                driver->drawPixel(x, y, irr::video::SColor(255, imageRed->getPixel(x, y).getAverage(), 0, imageBlue->getPixel(x, y).getAverage()));
            }
        }
    }
};

int main()
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640, 480), 16, false, false);
    if (device == 0)
        return 1;
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();
    device->getFileSystem()->addZipFileArchive("Irrlicht Engine - 3D example [");
    irr::scene::IAnimatedMesh* mesh = smgr->getMesh("] FPS:");
    irr::scene::ISceneNode* node = 0;
    Vision3D vision3D(device);

    if (mesh)
        node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
    if (node)
        node->setPosition(irr::core::vector3df(-1300,-144,-1249));
    smgr->addCameraSceneNodeFPS();
    device->getCursorControl()->setVisible(false);
    int lastFPS = -1;

    irr::video::ITexture* blueRed = driver->addRenderTargetTexture(driver->getScreenSize(), "map-20kdm2.pk3", driver->getColorFormat());
    irr::video::ITexture* blueView = driver->addRenderTargetTexture(driver->getScreenSize(), "20kdm2.bsp", driver->getColorFormat());

    while(device->run())
    {
        driver->beginScene(true, true, 0);
        vision3D.drawAll();
        driver->endScene();

        int fps = driver->getFPS();

        if (lastFPS != fps)
        {
            irr::core::stringw str = L"blue";
            str += driver->getName();
            str += "Irrlicht Engine - 3D example [";
            str += fps;

            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
    device->drop();
    return 0;
}

Dernière modification par Ilovechocolat (17-02-2010 18:23:19)

Hors ligne


#13 

17-02-2010 19:06:29

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Avec un shader ca te prendra presque rien tout et c'est fait pour ; pour des effets de parallalax ou de bump la carte graphique fait des centaines d'opration par pixel afin de calculer l'eclairage et les coords uv; alors c'est pas ac un simple addition qu'il va y avoir un probleme.L'idée est la suivant :

-tu fais comme c'est deja le cas 2 rendus;
-tu crées un shaderCallback ( cf tuto )
-tu crées un quad/sprite collé devant la camera ( ie : 4 vertices  , 2 triangles  en forme de carré , avec par exemple un CustomSceneNode -cf le tuto- en enfant de la camera bien placé de la sorte que le quad prenne tout l'ecran )
-tu definis le  material du quad avec le shader
- dans le fragment shader ( cad le shader des pixels )tu fais la moyenne des couleurs des texture;
-dans la boucle tu cache le quad pour les 2 rendus puis tu cache toute la scene sauf le quad puis tu affiche le quad seul;

Hors ligne


#14 

17-02-2010 19:44:43

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Je vais essayer de faire ça, mais comment je fait pour coller le quad sur ma cam.
[EDIT]J'y arrive pas, même avec tout ce que tu m'a dis . On peut pas passer au GLSL des textures ? Comme ça il regarde a quel pixel il est, il analyse le même pixel de mes deux textures et donne la couleur final.

Dernière modification par Ilovechocolat (17-02-2010 20:23:48)

Hors ligne


#15 

17-02-2010 20:55:14

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

si c'est justemement le but ; tu appliques les textures sur le quad , en couche 0 et 1 :

Code:

quad->setMaterialTexture(0,redView);
quad->setMaterialTexture(1,blueView);

pour coller le quad sur la camera tu fais quad->setParent(camera); quad->setPosition(vector3df(0,0,1));
pour qu'il soit a la bonne taille ( tu le fais de 2 par defaut dans le customSceneNode : les vertex en (0,-+1,-+1)  ) tu le scale de camera->getNearValue()*sin(camera-getFOV());

Dernière modification par firnafin (17-02-2010 20:56:39)

Hors ligne


#16 

17-02-2010 22:56:36

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

J'ai créé le qual (avec un scene node personnalisé, mais ça marche pas (damnation), j'utilise ce que tu m'a dit mais la qual est trop petit).
Bon maintenant je m'adresse au connaisseur de GLSL, comment je récupère les textures ?

[EDIT]étrangement mon qual ne supporte pas les textures, voici son code :

Code c++ :

class QuadSceneNode : public irr::scene::ISceneNode
{
public :
    QuadSceneNode(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr,
    irr::s32 id = -1, irr::core::rectf size = irr::core::rectf(-1,-1,1,1))
    : irr::scene::ISceneNode(parent, mgr, id)
    {
        m_material.Wireframe = false;
        m_material.Lighting = false;

        irr::core::position2df position(size.getCenter().X - (size.getSize()/2).Width, size.getCenter().Y - (size.getSize()/2).Height);
        m_box = irr::core::aabbox3d<irr::f32>(position.X, position.Y, 0, position.X + size.getWidth(), position.Y + size.getHeight(), 0);

        m_vertices[0] = irr::video::S3DVertex(position.X, position.Y + size.getHeight(),0,0,0,0,  irr::video::SColor(0,0,0,0), 0, 0);
        m_vertices[1] = irr::video::S3DVertex(position.X + size.getWidth(), position.Y + size.getHeight(),0,0,0,0, irr::video::SColor(0,0,0,0), 0, 0);
        m_vertices[2] = irr::video::S3DVertex(position.X, position.Y,0,0,0,0, irr::video::SColor(0,0,0,0), 0, 0);
        m_vertices[3] = irr::video::S3DVertex(position.X + size.getWidth(), position.Y,0,0,0,0, irr::video::SColor(0,0,0,0), 0, 0);
        m_material.BackfaceCulling = false;
    }
    virtual void OnRegisterSceneNode()
    {
        if(IsVisible)
            SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_SOLID);

        ISceneNode::OnRegisterSceneNode();
    }
    void render()
    {
        irr::video::IVideoDriver* driver = SceneManager->getVideoDriver();

        driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);

        /*if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY)
            mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
        else
            driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial());
        driver->setMaterial(mat);*/

        driver->setMaterial(m_material);

        irr::u16 indices[] = {0,1,2, 1,2,3};
        driver->drawIndexedTriangleList(&m_vertices[0], 4, &indices[0], 2);
        driver->draw3DBox(m_box, irr::video::SColor(255, 255, 255, 255));

        driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);
    }
    const irr::core::aabbox3d<irr::f32>& getBoundingBox() const
    {
        return m_box;
    }
    irr::u32 getMaterialCount() const
    {
        return 1;
    }
    irr::video::SMaterial& getMaterial(irr::u32 i)
    {
        return m_material;
    }
private :
    irr::core::aabbox3d<irr::f32> m_box;
    irr::video::SMaterial m_material;
    irr::video::S3DVertex m_vertices[4];
};

Dernière modification par Ilovechocolat (18-02-2010 16:01:47)

Hors ligne


#17 

18-02-2010 16:13:51

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

c'est vrai que c'est mal explicité ca dans irrlicht;
dans le shadercallback :

Code:

int var0=0;
services->setPixelShaderConstant("redView", (float*)(&var0), 1); 
int var1=1;
services->setPixelShaderConstant("blueview", (float*)(&var1), 1);

( il se peut meme que sens  , ca marche aussi ... me souviens pas trop de glsl )

et dans le fragment shader :

uniform sampler2D redView;
uniform sampler2D blueView;

void main(void)
{
vec4 redViewColor = texture2D(redView,vec2(gl_TexCoord[0]));
vec4 blueViewColor = texture2D(blueView,vec2(gl_TexCoord[0]));
 
gl_FragColor= "tu fais les calcules que tu veux sur  redViewColor et BlueViewColor ; exemple = vec4((redViewcolor.r+redViewColor.g+redViewColor.b)/3,0,(blueViewcolor.r+blueViewColor.g+blueViewColor.b)/3,1));"
 



}

Dernière modification par firnafin (18-02-2010 16:16:11)

Hors ligne


#18 

18-02-2010 17:03:35

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Merci, J'ai fini la shader, sinon, tu comprend pourquoi mon quad n'affiche pas les textures.
Tient que pense-tu de ma shader :

Code c++ :

uniform sampler2D blueTexture;
uniform sampler2D redTexture;

void main(void)
{
    vec4 finalColor;
    vec4 blueColor = texture2D(blueTexture, gl_TexCoord[0]);
    vec4 redColor = texture2D(redTexture, gl_TexCoord[0]);
    finalColor.b = (blueColor.r + blueColor.b + blueColor.g) / 3;
    finalColor.a = 255;
    finalColor.g = 0;
    finalColor.r = (redColor.r + redColor.b + redColor.g) / 3;
    gl_FragColor = finalColor;
}

Dernière modification par Ilovechocolat (18-02-2010 17:04:54)

Hors ligne


#19 

18-02-2010 17:17:32

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

pour la taille je ne vois pas pourquoi le quad est trop petit ,mets le code du QuadSceneNode pour voir si ca ne vient pas de la ;  vérifie qu'il est bien en lighting =off  et que les coords uv sont bonnes.
Un petit conseil pour le shader : 
-premierement il est plus rapide de faire 0.25*x que x/4 alors dans la mesure du possible autant faire des multiplication que des division , sur une programme destiné au CPU c'est pas tres grave mais pour un shader il faut penser a optimiser bien que maintenant les cartes graphiques devienent des monstres de calculs.
-deuxiemement la moyenne des composants rgb c'est pas le ce qu'il y a de mieu pour un rendu monochrome regarde par la  : http://fr.wikipedia.org/wiki/Niveau_de_gris

Dernière modification par firnafin (18-02-2010 17:29:18)

Hors ligne


#20 

18-02-2010 21:18:48

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Le code du quad est quelques sujets plus haut, il bug au niveau des textures (c'est mon premier scene node).

Hors ligne


#21 

18-02-2010 22:11:43

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

en effet il semble y avoir une probleme au niveau du quad ( pas de coordonnées de texture ) , mets plutot ca :

Code c++ :

  m_vertices[0] = irr::video::S3DVertex(-1,1,0 ,0,0,-1,video::SColor(255,255,255,255),0,0); //les deux derniers chiffres sont les coordonnées de texture
  m_vertices[1] = irr::video::S3DVertex(1,1,0  ,0,0,-1,video::SColor(255,255,255,255),1,0);
  m_vertices[2] = irr::video::S3DVertex(1,-1,0 ,0,0,-1,video::SColor(255,0,255,255),1,1);
  m_vertices[3] = irr::video::S3DVertex(-1,-1,0 ,0,0,-1,video::SColor(255,0,255,255),0,1);

Dernière modification par firnafin (18-02-2010 22:19:39)

Hors ligne


#22 

20-02-2010 19:50:57

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Et pour le vertex shader, je met juste le truc de base ?

Code c++ :

void main(void)
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}



PS : a partir de demain, je ne serait pas en mesure de bosser avant la rentré (vacance oblige).

[EDIT] Il doit y avoir une erreur dans le code de ma pixel shader, toute la texture est de couleur violette (donc un mélange de rouge et bleu) et unis (apparemment ça fait les calculs sur la couleur globale des textures).

Code c++ :

uniform sampler2D blueTexture;
uniform sampler2D redTexture;

void main(void)
{
    vec4 finalColor;
    vec4 blueColor = texture2D(blueTexture, vec2(gl_TexCoord[0]));
    vec4 redColor = texture2D(redTexture, vec2(gl_TexCoord[0]));
    finalColor.b = blueColor.r * 0.299 + blueColor.b * 0.114 + blueColor.g * 0.587;
    finalColor.a = 255;
    finalColor.g = 0;
    finalColor.r = redColor.r * 0.299 + redColor.b * 0.114 + redColor.g * 0.587;
    gl_FragColor = finalColor;
}


Ma class de shader :

Code c++ :

class RenderShader3D : public irr::video::IShaderConstantSetCallBack
{
public:
    virtual void OnSetConstants(irr::video::IMaterialRendererServices* services, irr::s32 userData)
    {
        int a = 0; services->setPixelShaderConstant("map-20kdm2.pk3", (const float*)&a, 1);
        a = 1; services->setPixelShaderConstant("20kdm2.bsp", (const float*)&a, 1);
    }
};

Dernière modification par Ilovechocolat (20-02-2010 20:19:50)

Hors ligne


#23 

21-02-2010 14:48:41

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

ca vient de gl_TexCoord[0] qui doit renvoyer (0,0) ; car il doit manquer un truc du style gl_TexCoord[0] = gl_MultiTexCoord0; dans le vertex shader

Hors ligne


#24 

28-02-2010 12:19:06

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

C'est bon, j'ai plus qu'a régler le problème des dimensions du quad et après c'est bon.

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
882 membres
1429 sujets
11119 messages
Dernier membre inscrit: LiseBuisson96
35 invités en ligne
Aucun membre connecté
RSS Feed