Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2982 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [GLSL-OSG] probleme avec les shaders GLSL sous osg

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[GLSL-OSG] probleme avec les shaders GLSL sous osg

n°1566609
nmantelier
Posté le 29-05-2007 à 12:11:08  profilanswer
 

Bonjour!  
 
je suis entrain de réaliser un application permetant de charger un model 3D et de le visualiser dans un viewer a l'aide de QT et d'osg.
Et certain model on des normal inverser qui sont donc rendu noir par le rendu openGL de base.
 
Donc Premiere question:
- je voulais passer par les shader GLSL pour calculer moi meme l'éclairage et paré ce problème cela est t'il une bonne idée ? ou puis je faire plus simple avec les parametre de GL_LIGHT et les GL_FRONT and BACK et dans ce cas que faut t'il faire
 
Deuxieme question :
-Je me suis déja pas mal pencher sur les shader GLSL avant de venir vous embeter, mais j'ai aussi quelque probleme qui rende rallentise enormement mon programme.
-J'ai donc définie mon vertex shader  

Code :
  1. varying vec3 normal, eyeVec;
  2. void main(void)
  3. {
  4. normal = gl_NormalMatrix * gl_Normal;
  5. vec3 vVertex = vec3 ( gl_ModelViewMatrix*gl_Vertex);
  6. eyeVec = -vVertex;
  7.  gl_Position = ftransform();
  8. }

 
 
ainsi que mon fragment shader

Code :
  1. varying vec3 normal , eyeVec;
  2. void main()
  3. {
  4. vec4 diffuse = vec4 (0.0);
  5. vec4 specular = vec4 (0.0);
  6. float att = 0.0;
  7. vec3 norm = normalize ( normal );
  8. vec3  light = vec3( gl_LightSource[0].position.xyz + eyeVec );
  9.   light = normalize(light);
  10. vec4 ambient = gl_FrontMaterial.ambient ;// * gl_LightSource[0].ambient;
  11. ambient = normalize ( ambient );
  12. float NdotL = abs(dot ( norm , light ));
  13. diffuse = (gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * NdotL);// + gl_FrontMaterial.emission;
  14. diffuse = (diffuse + gl_FrontMaterial.emission)/2.0;
  15. vec3 eye = normalize (eyeVec);
  16. vec3 refl = reflect ( -light, norm);
  17. float spec = max( dot ( refl , eye ), 0.0 );
  18. spec = pow( spec , gl_FrontMaterial.shininess );
  19. specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * spec;
  20. float dist = length ( light );
  21. att = 1.0 / (gl_LightSource[0].constantAttenuation + (gl_LightSource[0].linearAttenuation*dist) + (gl_LightSource[0].quadraticAttenuation*dist*dist) );
  22. gl_FragColor = ambient + ( diffuse + specular) * att;
  23. gl_FragColor[3] = gl_FragColor[3]/2.0;
  24. //gl_FragColor = diffuse ;
  25. }


 
si j'applique mon shader a mon model sur le node racine je me retrouve avec le meme materiau sur tout mon object
ce qui fait que pour parer a ce probleme je fait mon appel de shader sur tout les node avec un materiau.
Mais je pense que normalement je ne devrai pas faire ca.  
Et evidament cette methode reduit considérablement ma vitesse d'execution.
 
je l'appel donc dans mon code (pour le moment) de cette facon

Code :
  1. bool MyOptimizer::ShaderVisitor::loadShaderSource(osg::Shader* obj, const std::string& fileName )
  2. {
  3. std::string fqFileName = osgDB::findDataFile(fileName);
  4.    if( fqFileName.length() == 0 )
  5.    {
  6.   // std::count << "File \"" << fileName << "\" not found." << std::endl;
  7.       return false;
  8.    }
  9.    bool success = obj->loadShaderSourceFromFile( fqFileName.c_str());
  10.    if ( !success  )
  11.    {
  12.       //std::count << "Couldn't load file: " << fileName << std::endl;
  13.       return false;
  14.    }
  15.    else
  16.    {
  17.       return true;
  18.    }
  19. }
  20. void MyOptimizer::ShaderVisitor::applyShader(osg::StateSet* pstate)
  21. {
  22. osg::StateAttribute * pstatsAtt;
  23. osg::StateAttribute* stateAtt;
  24. osg::Material* poMat;
  25. bool ok = false;
  26. {
  27.  pstatsAtt = pstate->getAttribute(osg::StateAttribute::MATERIAL);
  28.  if (pstatsAtt ) // si il y a un materiau
  29.  {
  30.   stateAtt = pstate->getAttribute(osg::StateAttribute::PROGRAM);
  31.   if ( stateAtt )// si il y a déja un program
  32.    m_pEclairageProgram = (osg::Program*) stateAtt;
  33.   else
  34.    m_pEclairageProgram = new osg::Program();
  35.   m_pEclairageProgram->setDataVariance(osg::Object::DYNAMIC);
  36.   m_pEclairageProgram->setName( "eclairage" );
  37.   m_pEclairageVertObj = new osg::Shader( osg::Shader::VERTEX );
  38.   m_pEclairageFragObj = new osg::Shader( osg::Shader::FRAGMENT );
  39.   ok = loadShaderSource( m_pEclairageVertObj, QFileInfo(qApp->argv()[0]).dir().filePath("data/shaders/MyVertexShader.vert" ).latin1())
  40.  && loadShaderSource( m_pEclairageFragObj, QFileInfo(qApp->argv()[0]).dir().filePath("data/shaders/MyFragmentShader.frag" ).latin1()) ;
  41.  }
  42. }
  43. if(ok)
  44. {
  45.   m_pEclairageProgram->addShader( m_pEclairageFragObj );
  46.   m_pEclairageProgram->addShader( m_pEclairageVertObj );
  47.   pstate->setAttributeAndModes(m_pEclairageProgram, osg::StateAttribute::ON); 
  48. }
  49. }


 
Merci d'avance

mood
Publicité
Posté le 29-05-2007 à 12:11:08  profilanswer
 

n°1566994
IrmatDen
Posté le 30-05-2007 à 01:58:31  profilanswer
 

Salut,
 

nmantelier a écrit :

Donc Premiere question:
- je voulais passer par les shader GLSL pour calculer moi meme l'éclairage et paré ce problème cela est t'il une bonne idée ? ou puis je faire plus simple avec les parametre de GL_LIGHT et les GL_FRONT and BACK et dans ce cas que faut t'il faire


GLSL ne te sera pas d'une grande aide dans ce cas. Il n'est apellé que pour ce qui est actuellement dessiné, et si le modèle et/ou le noeud est mal préparé tu ne pourras rien faire. Le plus propre est assurément de t'assurer que les modèles ont les bonnes normales... Sinon, tout dépend de l'usage; tu peux fournir un paramètre flipNormal dans ton code de chargement, et inverser les normales à la mano si ce flag est activé. Tu peux peut-être détecter les modèles dont les normales sont inversées par programmation?
Si aucune de ces solutions ne peut convenir, alors il faudra que tu désactives GL_CULL_FACE, au détriment du temps de rendu...
 
Pour ta 2nde question, je ne connais pas osg, donc je m'abstiendrais de partir sur n'importe quelle supposition (en espérant déjà ne pas me planter sur ta première question :D)

n°1567100
nmantelier
Posté le 30-05-2007 à 10:47:16  profilanswer
 

Citation :

Le plus propre est assurément de t'assurer que les modèles ont les bonnes normales...


 
Oui ca aurai ete le plus simple mais le probleme c que je fait un filer de choix de model pour des utilisateur non experimenter qui peuvent charger nimporte quel model. Donc je ne peu pas controler les model d'entrer.
 
 

Citation :

Sinon, tout dépend de l'usage; tu peux fournir un paramètre flipNormal dans ton code de chargement, et inverser les normales à la mano si ce flag est activé. Tu peux peut-être détecter les modèles dont les normales sont inversées par programmation?


 
Cette methode j'ai deja essayer de retourner les normals ( enfin avec osg et non flipnormal) mais le resultat est le meme.
C'est a dire que je ne peu pas définir une normal comme dans le mauvais sens puisque tout dépend de la position de l'obs ;'(.
ce qui fait que j'ai fait une methode automatique qui test les normals sur tout les intersection entre le vecteur de vue et mon model pour ensuite retourner les normals qui sont orienter dans la mauvaise direction.
Pb depend du point de vue (donc corrige que partielement l'objet) et de plus tres tres long puisque il calcul une intersection par pixel donc sur une fenetre 400 300 (voir plus resize) ca fait un certain nombre de calcul.
 

Citation :

Si aucune de ces solutions ne peut convenir, alors il faudra que tu désactives GL_CULL_FACE, au détriment du temps de rendu...


 
Cette option est deja active (avec posibilite de la désactiver ou non) mais le résultat ne va pas puisque si je désactive le culling je me retrouve avec des faces noires o milieu de certain model du au calcul d'eclairage OpenGL. D'ou mon idée de partir sur les shader pour parer a ce probleme.

n°1567184
IrmatDen
Posté le 30-05-2007 à 12:50:23  profilanswer
 

As-tu un éclairage ambiant ou uniquement des éclairages directionnels? Si le pixel est noir en sortie, il n'est pas éclairé, si? Tu peux peut-être essayer vite fait d'ajouter un spot en direction de la face (enfin, orienté vers la normale de la face).


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [GLSL-OSG] probleme avec les shaders GLSL sous osg

 

Sujets relatifs
problème avec flash et Internet explorer [RESOLU]probleme: ajouter une valeur taper dans un formulaire dans une table
Problème de connection à site web[Résolu] problème avec Switch et MySQL
Problème de requetes imbriquéesProbleme de configuration PHP pour fonction exec("")
[RESOLU] Problème avec la fonction mail()probleme egalité de deux double
Problème d'ajout dans un arrayProbleme d'utilisation de l'API C de mysql sous linux
Plus de sujets relatifs à : [GLSL-OSG] probleme avec les shaders GLSL sous osg


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR