#0 

06-05-2017 23:45:34

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

Bonjour,

J'essai de changer la couleur de mon ciel en fonction de l'heure de la journée.

Pour le moment je fais un setVisible sur plusieurs nodes de skybox (skyboxMatin, skyboxmidi, skybox aprem,skybox  soir,skybox  nuit).
Chaque skybox a la même texture mais de couleur différente (Retouchées sur Gimp).
A chaque événement matin, midi, ... on affiche la skybox qui correspond.
Jusque là tout va bien ...
Le soucis c'est que je préférerais avoir une seule skybox et jouer sur sa coloration au niveau code du genre :

Code c++ :


UniqueSkybox->getMaterial(0).DiffuseColor = SColorf(50.0, 3.0, 1.0); /// DiffuseColor c'est un exemple hein j'ai copié le code d'une light


Sauf que çà, bien-sur çà ne marche pas...
Avez-vous une piste sur laquelle je pourrais m'orienter pour faire cela.

Merci wink

Hors ligne


#1 

07-05-2017 00:52:40

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

un petit coup de shader: (ici version 1.2)

Code c++ :


uniform sampler2D texture;
uniform vec4 color;

void main(){
    gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * color;
}



sinon tu retouche directement la texture (donc garder un double en mémoire)
tu itère sur tous les pixel de ta texture et tu multipli par une couleur de reference

Code c++ :


      char* tmp = (char*)texture->lock();
      for(int x = 0; x<texture->getSize().X; x += 4) {
          for(int y = 0; y<texture->getSize().y; ++y) {
               tmp[y * texture->getSize().X + x + 0] *= color_alpha;
               tmp[y * texture->getSize().X + x + 1] *= color_red;
               tmp[y * texture->getSize().X + x + 2] *= color_green;
               tmp[y * texture->getSize().X + x + 3] *= color_blue;
          }
     }



il faut évidement vérifier le type de la texture, ici je te les fait pour A8R8G8B8
dsl je n'ai pas toucher au texture d'irrlicht depusi un moment, il faudras tester wink

si tu compte ajouter d'autre effets plus complexe et dynamique a ton ciel il vaut mieux un shader

Hors ligne


#2 

07-05-2017 01:27:13

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

Merci Magun pour tas réponse.
Par contre en ce qui concerne les shaders je suis au niveau 0.
Je ne vois pas comment çà s'utilise, peux tu m'expliquer tas premiére solution stp ?

En attendant, j'ai essayé de tester la deuxième solution qui me parait plus gourmande :

Code c++ :


    /// Chargement texture du MATIN
    ITexture *SkyBoxTO_Mat = driver->getTexture ("media/map/summer_day1/matin_6.jpg"); // top
    ITexture *SkyBoxBO_Mat = driver->getTexture ("media/map/summer_day1/matin_5.jpg"); // bottom
    ITexture *SkyBoxLE_Mat = driver->getTexture ("media/map/summer_day1/matin_4.jpg"); // left
    ITexture *SkyBoxRI_Mat = driver->getTexture ("media/map/summer_day1/matin_2.jpg"); // right
    ITexture *SkyBoxFR_Mat = driver->getTexture ("media/map/summer_day1/matin_1.jpg"); // front
    ITexture *SkyBoxBK_Mat = driver->getTexture ("media/map/summer_day1/matin_3.jpg"); // back

    int color_alpha = 0;
    int color_red   = 255;
    int color_green = 0;
    int color_blue  = 0;

    char* tmp = (char*)SkyBoxTO_Mat->lock();
    for(int x = 0; x<SkyBoxTO_Mat->getSize().Width; x += 4)
    {
          for(int y = 0; y<SkyBoxTO_Mat->getSize().Height; ++y)
          {
               tmp[y * SkyBoxTO_Mat->getSize().Width + x + 0] *= color_alpha;
               tmp[y * SkyBoxTO_Mat->getSize().Width + x + 1] *= color_red;
               tmp[y * SkyBoxTO_Mat->getSize().Width + x + 2] *= color_green;
               tmp[y * SkyBoxTO_Mat->getSize().Width + x + 3] *= color_blue;
          }
     }
    SkyBoxTO_Mat->unlock();

    /// Creation de la skybox du MATIN
    MapItems.skybox[skyboxMatin_e] = smgr->addSkyBoxSceneNode((ITexture *)tmp, SkyBoxBO_Mat,SkyBoxLE_Mat,SkyBoxRI_Mat,SkyBoxFR_Mat,SkyBoxBK_Mat,0,-1);



Et çà ne fonctionne pas, mon programme compile mais plante littéralement. J'ai fais une erreur ?

Dernière modification par jonath313 (07-05-2017 02:07:05)

Hors ligne


#3 

07-05-2017 11:38:52

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

probablement que tes texture sont en rgb et non en rgba comme je tes dit il faut prendre en consideration le type de la texture wink
je retouche le code d'exemple d'irrlicht et je passe ça

pour ce qui est des shaders tu prend le code d'exemple http://irrlicht.sourceforge.net/docu/example010.html
pas très compliquer, deux fichier (*.vert pour le vertex shader (deformation) et un *.frag pour la rasterisation (~texture rendu))
tu fait un copier coller de l'initialisation -> addHighLevelShaderMaterialFromFiles et tu crée un IShaderConstantSetCallBack pour passer la couleur que tu veux au moment de l'affichage
je vais voir si j'ai le temp de te faire un bout de code

Hors ligne


#4 

07-05-2017 12:33:00

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

voila un premier example avec un effet sepia

Code c++ :

  irr::core::array<irr::video::ITexture*> skybox;
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_6.jpg"));
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_5.jpg"));
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_4.jpg"));
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_2.jpg"));
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_1.jpg"));
  skybox.push_back(driver->getTexture(mediaPath + "media/map/summer_day1/matin_3.jpg"));
 
  float sepia = 0.8f;
 
  for(unsigned i = 0; i<skybox.size(); ++i)
  {
      irr::video::SColor color;
      unsigned char *buffer = (unsigned char*)skybox[i]->lock();
     
      u32 pitch = skybox[i]->getPitch();
      u32 bytes = video::IImage::getBitsPerPixelFromFormat(skybox[i]->getColorFormat()) / 8;
     
      for(unsigned x = 0; x<skybox[i]->getSize().Width; ++x)
      {
          for(unsigned y = 0; y<skybox[i]->getSize().Height; ++y)
          {
              unsigned char *dst = buffer + (y * pitch) + (x * bytes);
              color.setData(dst, skybox[i]->getColorFormat());
             
              float r = color.getRed() / 255.f;
              float g = color.getGreen() / 255.f;
              float b = color.getBlue() / 255.f;
             
              float rsepia = r * 0.393 + g * 0.769 + b * 0.189;
              float gsepia = r * 0.349 + g * 0.686 + b * 0.168;
              float bsepia = r * 0.272 + g * 0.534 + b * 0.131;
             
              r = sepia*r + (1.0-sepia)*rsepia;
              g = sepia*g + (1.0-sepia)*gsepia;
              b = sepia*g + (1.0-sepia)*bsepia;
             
              color.setRed(std::min(r * 225.f, 255.f));
              color.setGreen(std::min(g * 225.f, 255.f));
              color.setBlue(std::min(b * 225.f, 255.f));
             
              color.getData(dst, skybox[i]->getColorFormat());
          }
      }
     
      skybox[i]->unlock();
  }

    smgr->addSkyBoxSceneNode(
      skybox[0], skybox[1],
      skybox[2], skybox[3],
      skybox[4], skybox[5]
  );

Hors ligne


#5 

07-05-2017 14:21:18

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

ok super, cette solution fonctionne mais elle est pas trop gourmande en calcule si je l'applique 1 fois par secondes.
Sinon j'avais pensé calculer toutes les couleurs de textures que j'ai besoin dans les init mais çà risque de faire énormément de valeurs maintenues en mémoire non ?
Tu en pense coi toi ?

Dernière modification par jonath313 (07-05-2017 18:11:58)

Hors ligne


#6 

07-05-2017 22:52:55

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

une fois par seconde ça va, c'est pas si gourmant que sa
tout garder un mémoire, ça depend de la taille de ta texture sauf que si tu génère une fois par second ça fait beaucoup oui
après il y a d'autre solution avec le multi-texturing (une texture de 1px qui donne la couleur superposer par la "vrai"), et/ou modifier la couleurs des vertices de la skybox
mais a la fin un shader ça reste plus simple et ça te permet de faire des effets temps réel ( http://glslsandbox.com/e#39812.0 ), évidement ça a un coup aussi

Hors ligne


#7 

08-05-2017 23:00:00

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

A ouais carrément il y a des effets bluffants là dessus.

Et moi qui pinaille a faire changer la texture d'une skybox pour faire des nuages ...



Enfin bref çà fonctionne.

Dernière modification par jonath313 (16-05-2017 23:29:58)

Hors ligne


#8 

09-05-2017 18:52:44

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

Magun,

J'utilise t'as fonction de coloration des pixels et j'ai un petit soucis :
Je colorie l'image plusieurs fois de suite et du coups je repart de la nouvelle coloration pour recolorier la suivante.
Le soucis c'est que quand je me rapproche du noir, il m'est impossible de revenir sur un bleu ciel ...

J'ai alors pensé a avoir 2 fois le même texture, une qu'on ne touche pas qui sert de base pour calculer la nouvelle couleur .
Je ne vois pas comment modifier pour faire cela, j'ai bien essayé de remplacer dans le code mais çà ne fonctionne pas.

Hors ligne


#9 

10-05-2017 13:02:23

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

tu doit crée une nouvelle texture (irrlicht met en cache quand tu fait getTexture et donc c'est la même que u modifi je suppose)
donc tu utilise rendered.push_back(driver->addTexture(skybox[0]-> getSize(), "skybox_left", skybox[0]-> getColorFormat()))

il te suffi de lock les deux texture, un memcpy de l'original vers la copie, et tu fait ton operation sur les pixel ou les deux a la fois wink

Code c++ :


for(int i = 0; i<skybox.size(); ++i)
{
    irr::core::stringc name = "media/map/summer_day1/matin_6.jpg";
    name += i;
    rendered.push_back(driver->addTexture(skybox[0]-> getSize(), name.c_str(), skybox[0]-> getColorFormat()))
}

// puis

for(int i = 0; i<skybox.size(); ++i)
{
      irr::video::SColor color;
      unsigned char *src = (unsigned char*) skybox[i]->lock(ETLM_READ_ONLY);
      unsigned char *dst = (unsigned char*) rendered[i]->lock(ETLM_WRITE_ONLY);
     
      u32 pitch = skybox[i]->getPitch();
      u32 bytes = video::IImage::getBitsPerPixelFromFormat(skybox[i]->getColorFormat()) / 8;

      for(unsigned x = 0; x<skybox[i]->getSize().Width; ++x)
      {
          for(unsigned y = 0; y<skybox[i]->getSize().Height; ++y)
          {
              unsigned char *in = src + (y * pitch) + (x * bytes);
              unsigned char *out = dst + (y * pitch) + (x * bytes);

              color.setData(in, skybox[i]->getColorFormat());

              // bla bla bla

              color.getData(out, skybox[i]->getColorFormat());
          }
      }

      rendered[i]->unlock();
      skybox[i]->unlock();
}

Hors ligne


#10 

11-05-2017 16:12:49

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

Ok merci pour ton aide c'est vraiment sympas.
Néanmoins il m'affiche la même texture sur tous les layer ...

Code c++ :


irr::core::array<irr::video::ITexture*> rendered;

void set_color(array<irr::video::ITexture*> skybox, vector3df RedCoef, vector3df GreenCoef, vector3df BlueCoef,float colorCoeff)
{
    for(int i = 0; i<skybox.size(); ++i)
    {
        irr::core::stringc name = "media/map/summer_day1/matin_6.jpg";
        name += i;
        rendered.push_back(driver->addTexture(skybox[0]-> getSize(), name.c_str(), skybox[0]-> getColorFormat()));
        rendered.push_back(driver->addTexture(skybox[1]-> getSize(), name.c_str(), skybox[1]-> getColorFormat()));
        rendered.push_back(driver->addTexture(skybox[2]-> getSize(), name.c_str(), skybox[2]-> getColorFormat()));
        rendered.push_back(driver->addTexture(skybox[3]-> getSize(), name.c_str(), skybox[3]-> getColorFormat()));
        rendered.push_back(driver->addTexture(skybox[4]-> getSize(), name.c_str(), skybox[4]-> getColorFormat()));
        rendered.push_back(driver->addTexture(skybox[5]-> getSize(), name.c_str(), skybox[5]-> getColorFormat()));
    }


    for(unsigned i = 0; i<skybox.size(); ++i)
    {
      irr::video::SColor color;
      unsigned char *src = (unsigned char*) skybox[i]->lock(ETLM_READ_ONLY);
      unsigned char *dst = (unsigned char*) rendered[i]->lock(ETLM_WRITE_ONLY);

      u32 pitch = skybox[i]->getPitch();
      u32 bytes = video::IImage::getBitsPerPixelFromFormat(skybox[i]->getColorFormat()) / 8;


      for(unsigned x = 0; x<skybox[i]->getSize().Width; ++x)
      {
          for(unsigned y = 0; y<skybox[i]->getSize().Height; ++y)
          {
              unsigned char *in = src + (y * pitch) + (x * bytes);
              unsigned char *out = dst + (y * pitch) + (x * bytes);

              color.setData(in, skybox[i]->getColorFormat());

              
              float r = color.getRed() / 255.f;
              float g = color.getGreen() / 255.f;
              float b = color.getBlue() / 255.f;

              float rsepia = r * RedCoef.X + g * RedCoef.Y + b * RedCoef.Z;
              float gsepia = r * GreenCoef.X + g * GreenCoef.Y + b * GreenCoef.Z;
              float bsepia = r * BlueCoef.X + g * BlueCoef.Y + b * BlueCoef.Z;

              r = colorCoeff*r + (1.0-colorCoeff)*rsepia;
              g = colorCoeff*g + (1.0-colorCoeff)*gsepia;
              b = colorCoeff*g + (1.0-colorCoeff)*bsepia;

              color.setRed(std::min(r * 225.f, 255.f));
              color.setGreen(std::min(g * 225.f, 255.f));
              color.setBlue(std::min(b * 225.f, 255.f));

              color.getData(out, skybox[i]->getColorFormat());
          }
      }

    rendered[i]->unlock();
    skybox[i]->unlock();
    }
}



Utilisation :

Code c++ :


                        set_color(    skybox,
                                    vector3df(0.393, 0.769, 0.189),     //RedCoef,
                                    vector3df(0.349, 0.686, 0.168),     //GreenCoef,
                                    vector3df(0.272, 0.534, 0.131),     //BlueCoef,
                                    0.5f);        //colorCoeff

                        skyboxNode->setMaterialTexture (0, rendered[0]);
                        skyboxNode->setMaterialTexture (1, rendered[1]);
                        skyboxNode->setMaterialTexture (4, rendered[4]);
                        skyboxNode->setMaterialTexture (5, rendered[5]);
                        skyboxNode->setMaterialTexture (3, rendered[3]);
                        skyboxNode->setMaterialTexture (2, rendered[2]);



Initialisation :

Code c++ :


  irr::core::array<irr::video::ITexture*> skybox;
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_6.jpg"));
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_5.jpg"));
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_4.jpg"));
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_2.jpg"));
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_1.jpg"));
  skybox.push_back(driver->getTexture("media/map/summer_day1/matin_3.jpg"));

    set_color(    skybox,
                vector3df(0.393, 0.769, 0.189),     //RedCoef,
                vector3df(0.349, 0.686, 0.168),     //GreenCoef,
                vector3df(0.272, 0.534, 0.131),     //BlueCoef,
                0.8f);        //colorCoeff

        scene::ISceneNode* skyboxNode = smgr->addSkyBoxSceneNode(
                                                            rendered[0],
                                                            rendered[1],
                                                            rendered[4],
                                                            rendered[5],
                                                            rendered[3],
                                                            rendered[2]);



Il y a quelque chose qui m'échappe ?


... Bon je viens de ruiner tout mon code ...
Après y avoir fait fonctionné, je me suis rendu compte que çà lagait énnormément.
J'ai alors pensé charger les 24 textures x 6 textures correspondants chacune à une heure de la journée pour la coloration du ciel et là je me suis perdu et mon programme est planté.

Visiblement quand je fais le code suivant les textures ne sont pas appliquées correctement :

    skyboxNode->setMaterialTexture(0, SkyTexRender[0]);
    skyboxNode->setMaterialTexture(1, SkyTexRender[1]);
    skyboxNode->setMaterialTexture(2, SkyTexRender[2]);
    skyboxNode->setMaterialTexture(3, SkyTexRender[3]);
    skyboxNode->setMaterialTexture(4, SkyTexRender[4]);
    skyboxNode->setMaterialTexture(5, SkyTexRender[5]);

On ne peut pas réappliquer une texture existante sur une skybox ? (j'ai essayé sur un skydome çà fonctionne)

Je me demande si je devrais pas plutot créer 24 skybox et faire toutes les couleurs à la main sur Gimp parceque là je ne vois vraiment pas comment çà peut se résoudre

Dernière modification par jonath313 (11-05-2017 22:57:22)

Hors ligne


#11 

12-05-2017 13:04:52

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

ba oui surment, déjà tu crée de nouvelle texture a chaque frame qui ne sont pas nécéssaire
et puis je suis pas sur pour le setMaterialTexture

Code c++ :

#include <irrlicht.h>
#include <iostream>

using namespace irr;
using namespace irr::core;
using namespace irr::video;

void set_color(array<ITexture*> skybox, array<ITexture*> rendered, vector3df RedCoef, vector3df GreenCoef, vector3df BlueCoef, float colorCoeff)
{
    for(unsigned i = 0; i<skybox.size(); ++i)
    {
        irr::video::SColor color;
        unsigned char *src = (unsigned char*) skybox[i]->lock(ETLM_READ_ONLY);
        unsigned char *dst = (unsigned char*) rendered[i]->lock(ETLM_WRITE_ONLY);

        u32 pitch = skybox[i]->getPitch();
        u32 bytes = video::IImage::getBitsPerPixelFromFormat(skybox[i]->getColorFormat()) / 8;


        for(unsigned x = 0; x<skybox[i]->getSize().Width; ++x)
        {
            for(unsigned y = 0; y<skybox[i]->getSize().Height; ++y)
            {
                unsigned char *in = src + (y * pitch) + (x * bytes);
                unsigned char *out = dst + (y * pitch) + (x * bytes);

                color.setData(in, skybox[i]->getColorFormat());

               
                float r = color.getRed() / 255.f;
                float g = color.getGreen() / 255.f;
                float b = color.getBlue() / 255.f;

                float rsepia = r * RedCoef.X + g * RedCoef.Y + b * RedCoef.Z;
                float gsepia = r * GreenCoef.X + g * GreenCoef.Y + b * GreenCoef.Z;
                float bsepia = r * BlueCoef.X + g * BlueCoef.Y + b * BlueCoef.Z;

                r = colorCoeff*r + (1.0-colorCoeff)*rsepia;
                g = colorCoeff*g + (1.0-colorCoeff)*gsepia;
                b = colorCoeff*g + (1.0-colorCoeff)*bsepia;

                color.setRed(std::min(r * 225.f, 255.f));
                color.setGreen(std::min(g * 225.f, 255.f));
                color.setBlue(std::min(b * 225.f, 255.f));

                color.getData(out, skybox[i]->getColorFormat());
            }
        }

        rendered[i]->unlock();
        skybox[i]->unlock();
    }
}

int main()
{
    IrrlichtDevice* device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(640, 480));
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    gui::IGUIEnvironment* gui = device->getGUIEnvironment();
   
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
   
    array<ITexture*> skybox;
    array<ITexture*> rendered;
   
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_6.jpg"));
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_5.jpg"));
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_4.jpg"));
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_2.jpg"));
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_1.jpg"));
    skybox.push_back(driver->getTexture("media/map/summer_day1/matin_3.jpg"));
   
    for(int i = 0; i<skybox.size(); ++i)
    {
        irr::core::stringc name = "irrlicht2_up.jpg";
        name += i;
        rendered.push_back(driver->addTexture(skybox[i]-> getSize(), name.c_str(), skybox[i]-> getColorFormat()));
    }

    smgr->addSkyBoxSceneNode(
        rendered[0], rendered[1],
        rendered[2], rendered[3],
        rendered[4], rendered[5]
    );

    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
    cam->setPosition(core::vector3df(-100,50,100));
    cam->setTarget(core::vector3df(0,0,0));
    device->getCursorControl()->setVisible(false);
   
    irr::u32 time = device->getTimer()->getTime() / 1000;

    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(255,0,0,0));
        smgr->drawAll();
        set_color(
            skybox, rendered,
            vector3df(0.393, 0.769, 0.189),
            vector3df(0.349, 0.686, 0.168),
            vector3df(0.272, 0.534, 0.131),
            sin(device->getTimer()->getTime() / 1000.0)
        );
        driver->endScene();
    }

    device->drop();

    return 0;
}

Hors ligne


#12 

12-05-2017 22:45:02

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

Ok ton code fonctionne, effectivement çà fait énormément de calculs refaits inutilement car une fois qu'on a calculé toutes les couleurs qu'on a besoin, il faut juste les afficher.

Tu pense que faire deux fonctions du style suivant serait possible:

Code c++ :


calculate_color() // Avant la boucle while je calcule 24 textures de couleurs différentes

set_color()         // Dans la boucle while on applique uniquement la couleur déjà calculée



Du coups c'est la mémoire qu'on va blinder de couleurs de pixel, çà fait quand même 24x256x256x3 = 4,7 millions de float en mémoire ...

Bon avec cette solution visiblement soit je péte le nombre de calculs du cpu soit je péte la mémoire...

Si je fais la seconde possibilité qui est de créer 24 skybox avec 24 textures différentes et d'afficher uniquement celle que je veux a un instant t, aurais-je un gain de performance ?

C'est coi la différence ? Est-ce que le type de mémoire utilisée par le cpu est différent ? (du style solution 1 -> tout en cache et solution 2 tout en RAM ?)

Merci encore pour ton aide.

Hors ligne


#13 

13-05-2017 13:14:24

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

4718592*6*32/8/1024/1024 = 108Mo (tu as oublier un x6 -> 6 texture par skybox)
bon en terme de coup d'espace mémoire sa va (si je suis pas a coter de la plaue)
tu auras forcement une optimisation coter rendu oui

après évidemeent tu peut faire du multi-threading (6 thread) avec openmp par exemple (#pragma omp parralel for avec une synchro sur le lock/unlock)
tu peut optimiser le pipline de ton cpu avec des calcules sse (diminue le nombre de cycle necessaire par operation)

mais sa ne vaudras jamais un calcule gpu avec un shader, puisque l'architecture materiel "super-scalaire" est prévue pour ça
http://docs.nvidia.com/cuda/cuda-c-prog … second.png

sur gpu tu as ~1024 thread et beaucoup d'operation realiser en 1 cycle
sur cpu tu as ~4       thread et il faut optimiser a la main

ensuite oui tu as beaucoup de mémoire différente (registre, L1, L2, L3, L4, Ram)
sauf que les mémoires sur cpu nécéssite des codes particulier pour être utiliser correctement, sinon c'est l'os qui le fait

en général dans ton code, le system charge une petite zone mémoire que tu veut traiter, tu fait le traiement
et quand tu veut utiliser une adresse qui n'est pas en cache il remplace le cache par la nouvelle zone mémoire pour faire le traitement
c'est ce qu'on apelle un soft-miss, et ça a un cout, la plus part du temp ce cout de transfert n'est pas pris en compte par le cout théorique d'un algo,
sauf que ba en pratique un algo peut être bien plus performant que théoriquement avec ces histoires

mais toi dans ton cas tu en faite tu utilise deux caches, un en ram (image) l'autre en gpu (texture)
en gros tu as un cache en ram pour irrlicht, pourque tu puisse faire tes operations (lock)
et tu as un cache sur le gpu qui est transferer quand tu as fini (unlock)

et comme c'est ce dernier qui est utiliser pour l'affichage tu as bien une optimisation
et que tu as tout mis en cache, tu suprimme le cout calculatoire dans la boucle principal
et tu suprimme le cout de mise en cache et de transfert de tes texture de la ram vers le gpu (qui as aussi un cout non négligable)

Hors ligne


#14 

14-05-2017 19:24:15

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

ok effectivement la différence est significative. Mais du coups si je charge 24 texture et que je fais un setMaterialTexture et que je me contente d'appliquer la texture que je veux sur mon node j'utilise les ressources CPU ou GPU ?

Hors ligne


#15 

14-05-2017 22:43:50

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

ok effectivement la différence est significative. Mais du coups si je charge 24 texture et que je fais un setMaterialTexture et que je me contente d'appliquer la texture que je veux sur mon node j'utilise les ressources CPU ou GPU ?

Hors ligne


#16 

15-05-2017 00:50:25

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

pour construire la mise en cache tu utilise le cpu
apres une fois que tu las tu as 6 affectation c'est raisonable et tu n'utilise pas de ressource cpu ou gpu

Hors ligne


#17 

15-05-2017 11:14:22

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

Ok super alors j'ai modifié mon code et j'ai commencé le travail de mes 24 images sur Gimp. Je vais essayer de faire une vidéo du résultat quand çà sera fini. J'aimerai être le plus progressif possible sur les changement de couleurs, je vais voir comment je vais faire parce que seulement 24 image pour passer du jaune à un bleu ciel puis orange puis noir çà reste quand même assais violent. Sinon il faut que je crée un shader mais vue que j'y connais rien çà va me prendre du temps.

Hors ligne


#18 

15-05-2017 13:53:44

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

Hors ligne


#19 

16-05-2017 23:21:38

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

1)
Je commence tout doucement à regarder les shaders, j'ai récupéré un shader qui fait une surface water, je l'utilise sans soucis, mais par contre niveau performance avec shaders je suis à 50 fps et CPU à 50% et sans shader 60fps et CPU 1% de ressource sur mon jeu.

J'ai essayé de le paramétrer mais je ne trouve rien qui puisse lui faire moins consommer... Je t'envois du code par mail si tu veux regarder.

2)
Petite question, c'est possible de réutiliser les codes de ce site :
http://glslsandbox.com/e#39753.0


Par exemple, si je veux essayer de voir à coi ressemble les shaders de ce site sur mon prog irrlicht :
https://github.com/genekogan/Processing … aders/data
Je dois m'y prendre comment ?

Ok bon courage pour ton oral !

Dernière modification par jonath313 (17-05-2017 19:16:04)

Hors ligne


#20 

18-05-2017 15:16:24

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

Salut

1) envoie moi du code sur le forum ou par mail ce n'est pas normal la consommation smile
2) oui tu peut utiliser ce genre de shader (glslsandbox) , tu donne juste ces trois parametres:
        uniform float time;
        uniform vec2 mouse;
        uniform vec2 resolution;
    mais ici c'est du raymarching
    le but c'est de faire croire que l'interrieur est un rendu en lui meme et donc de voir un "monde"
    sur ce que tu voi il y a 2 polygones : un quad devans l'ecran -> bref ce n'est pas sa que tu cherche pour le moment

pour ce qui est du lien github, tu peut aussi les utiliser directement
ensuite encore une fois tu donne simplement les valeurs pour les differents uniforms
et si tu voie un "varying / in" la c'est un peut plus compliquer, c'est un shader "precedent" qui donne la valeur ( geometry -> vertex -> fragment )

Hors ligne


#21 

18-05-2017 15:38:01

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

Salut !

Ok je vais gratter un peut là dessus, en attendant je t'ai envoyé mon code par mail sur le mail .ovh. Je me suis acharné à changer pleins de paramétres du shader sans que rien n'y fasse, le seul moyen de baisser la conso est de virer le OnAnimate sad. Tiens moi au jus si tu as bien reçu le mail.

Encore merci.

Hors ligne


#22 

19-05-2017 12:56:52

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

Juste par curiositer, les charactéristiques de ton pc sont les quelles ?
Je suis étonner que mon pc portable donne de meilleurs performances 60fps 10% cpu c'est pourtant pas une bête

mes première impression c'est que tu utilise beaucoup trop de varaible locales et/ou global utilise d'avantage les classes !
par exemple, ta classe CMapWater n'est pas mal, mais a chaque itération:

    pourquoi ajouter et supprimer une camera ? et pas avoir une camera reserver une bonne fois pour toute ?
    pourquoi la reflection est calculer dans CMapWater et pas CMapCore ?
    pourquoi dereference le device pour avoir le driver et pas les stockers definitivement ?
    bon en terme de performances, c'est mineur

le soucis pour le moment c'est que OnAnimate est apeller pendant le smgr->drawAll or ton CMapWater fait lui même un smgr->drawAll dans le OnAnimate
c'est pour ça je pensse que tu as introduit "IsVisible && Pass", mais que ce passe t-il si tu as deux CMapWater ? tongue

    je pensse donc que tu devraient introduire une nouvelle classe pour la reflection,
    je vais me renseigner sur la docs puisque, j'ai réécris le scene manager donc je ne me souvient plus très bien ...

Cepandant avans de commencer as passer quelques heures, peut-tu m'expliquer un peu ton code ? wink

ps: pensse a utiliser des dossier pour les sources
      ainssi que des namespace et potentielement un style d'indentation plus "stricte"
      (perso j'ai un style Allman a ma sauce)

Hors ligne


#23 

20-05-2017 12:34:15

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

Alors, mon pc portable est un peut vieux :
Packard Bell EasyNote LJ65
Intel(R) core(TM)2 Duo CPU  P7450 @ 2.13 GHz   2.13 GHz
RAM 4.00 Go
Système d'exploitation 64 bits
Carte graphique GeForce GT 240M 1Go

Sur le code :
CMapCore    : Gére toutes les autres classes liées à l'envirronnement (application du splat sur le node du terrain, creation de l'ocean, ... ici on géré les taille, les positions, ...)
CMapMeteo  : S'occupe de la partie météo (changement couleur du ciel, du soleil, génération des orages ...)
CMapSplat   : Shader pour le terrain splating
CMapWater  : Shader pour l'ocean

La classe Water incluant le shader a été faite par Copland, à l'époque il m'a juste montré ce qu'était un shader. Je ne maîtrise pas du tout son code ni pourquoi il a fait comme çà.

Je ne serais pas te répondre sur le  pourquoi la reflection est calculer dans CMapWater et pas CMapCore. Visiblement c'est la reflexion qui consomme énormément de ressources.

J'aimerai améliorer ce shader pour qu'il ne consomme moins, mais je ne vois pas trop comment.

ps: en fouillant sur le net, j'ai trouvé l'origine du code :
http://irrlicht.sourceforge.net/forum/v … ;start=225

Dernière modification par jonath313 (21-05-2017 02:04:53)

Hors ligne


#24 

23-05-2017 01:37:06

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

bon c'est vrais que ton pc n'ai vraiment pas adapter pour dev surtout de la 3D

Pour ce qui est de ton code, essaye de me préparer une démo simple, minimal et propre, qui ne prend que les aspects utiles a ton problème
par ce que moi la, j'arrive dans ton code : entres les différentes erreurs de syntaxe c++ et l'organisation du code ça devient difficile à comprendre et je n'ai pas le temps de tout réécrire:

        1) ta essayer de faire du bump mapping ? pour l'instant je voie un gros "paté" au millieu de la carte avec des couleurs chelou qui ressemble a une texture de normal ... -> ????
        2) trouver pourquoi je n'ai pas d'eau -> ah ! c'est commenter dans CMapCore
        3) bon j'ai de l'eau mais le rendu est horrible  -> erreur de matrice ? mauvais shader ?
        4) pourquoi y a pas de transparence ? a quoi correspond la skydom étrange au millieu ? les particules ?

alors oui ça compile, mais même à l'execution je ne comprend pas ce que je voie, entre ce que ta essayer de faire, et le rendu final je preçois une intension,
mais je ne suis pas sur si c'est voulu, ou des erreurs, ou irrlicht, ou ma machine ...
c'est pas pratique et ça me prend du temps (par exemple un post comme celui-ci me prend environ  1h40 sans parler du code et de la doc)

mais honêtement tu ne pourras pas gagner plus de performance si tu veut garder un rendu "equivalent",
la seul solution c'est évidement d'enlever la reflexion c'est tout, et c'est très gourmant par ce que irrlicht n'est pas adapter

      le soucis vien entre autres du rendu du scenemanager en changent la camera de place
      à chaque itération il a besoin de recalculer les transformations, de retrier les objets par distance et ça deux fois, la ça va
      mais le pire, c'est le terrain, il ne met pas en caches ces informations et ne ce base que sur la distance de la caméra -> donc il doit recalculer le niveau de détail en permanance ce qui est très couteux

donc en fonction de ce que tu veut gagner -> en général on laisse le joueur choisir en fonction des performances de sont pc
    -soit tu fait pas de reflexion,
    -soit tu fait une reflexion uniquement de la skydome (ta météo)
    -soit tu desactive le shader du terrain et tu fait un rendue avec un niveau de détail très bas et tu désactive le rendu des petits objets
    -etc

premier solutions: pour faire ça, je ferais un filtre basé sur ILightManager comme ça ta différent choix (reflexion du skydome, des objets transparent, du shadow, .... etc) et pratique avec OnRenderPassPreRender/OnNodePreRender/OnNodePostRender/OnRenderPassPostRender
deuxième solution: ISceneManager est en fait un CSeneManager qui lui mếmé dérive de ISceneNode, donc du coup tu peut crée un ISceneNodeAnimator qui filtre @Children pour désactiver le rendu de certain node et faire un rendu de la reflexion avans le rendu de la scene "normal"
troixième solution: tu écrit un shader spécial que tu applique partout qui te permet de crée une caméra virtuel différente de irrlicht qui te permetra de changer la position sans impacter les performances dans le cas ici présent une frame sur deux (pour la réflexion)
tu copie donc simplement la matrice de la camera d'irrlicht que tu rebricole au besoin

il y a plien d'autres solutions possibles !

sinon ba il faut ce pencher sur des techniques beaucoup plus avancer avec des optimisations dont tu n'a pas encore le niveau et dont les limites d'irrlicht ne permet pas sans une réécriture partiel

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
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
83 invités en ligne
Aucun membre connecté
RSS Feed