Après plusieurs bidouillage du code du shader afin de tenter d'isoler le problème, il me semble que cela provienne de "col1"
Est-ce que dans "float4 col1 = tex2D(texherbe, TexCoord);" le fait d'utiliser le même TexCoord que pour col0 ne pose pas de problème ?
Est-ce bien un "3" dans "float alphafinal = alpha * col1[3];" ?
Je pose ces questions à 100% au jugé-jeté car je ne comprend pas encore bien ce qui se passe dans le shader. Mais j'espère pouvoir te mettre sur la bonne piste...
EDIT: ligne 41: la suppression de " * col1[3];" dans "float alphafinal = alpha * col1[3];" supprime le warning de la ligne 43!
EDIT2: ligne 39: le remplacement de "texherbe" par "texsol" (donc la texture de rang 0) dans "float4 col1 = tex2D(texherbe, TexCoord);" supprime l'erreur X4515...
Ainsi le shader compile... mais s'il me blend deux fois la texture sol je ne le vois pas.
J'avance tout de même...
Dernière modification par Memorial76 (16-10-2012 20:27:23)
Hors ligne
Le shader est bon puisqu'il marche chez moi. Donc col1[3] et texherbe sont à la bonne place. A la limite, tu peux remplacer "col1[3]" par "col1.a" si tu veux.
Je suis sûr que c'est dans ta classe Hexagone qu'il y a un problème. As-tu bien mis deux textures dans le material de tes hexagones? Car si tu n'as de texture de "rang 1" (pour reprendre ton expression), l'erreur X4515 vient certainement de là.
Le fait d'utiliser le même texcoord ne pose aucun problème tant que tes 2 textures sont de même taille.
Hors ligne
Oki merci, voilà une très bonne piste que je vais vérifier asap: la taille des deux textures!
EDIT: j'ai modifié les tailles de mes textures et ça ne change pas les problèmes de compilation du shader.
J'ai bien deux textures dans mon material:
"setMaterialTexture(0..." et "setMaterialTexture(1,...)"
Mon materialType est: "setMaterialType(irr::video::EMT_SOLID);"
Je vais essayé avec un hexagone en .3ds mais hier j'ai eu un gros plantage de PC en essayant...
EDIT: après essai, toujours rien, même ton hexagone chargé avec tes lignes de code copiées de ton main() n'est pas texturé comme prévu. Le shader ne compile pas... Est-ce due à une différence de version d'IDE, ou quelque chose du genre?...
Dernière modification par Memorial76 (17-10-2012 08:49:21)
Hors ligne
J'ai trouvé! Moi aussi j'avais un probleme avec la variable alpha, il me disait qu'elle n'était pas affecté mais pourtant ça marchait correctement quand même. Voilà le correctif:
Le nouveau "dx.hlsl"
uniform float4x4 mWorldViewProj; // vertex shader output structure struct VS_OUTPUT { float4 Position : POSITION; // vertex position float2 TexCoord0 : TEXCOORD0; // tex 0 coords }; VS_OUTPUT vertexMain( in float4 vPosition : POSITION, float2 texCoord0 : TEXCOORD0 ) { VS_OUTPUT Output; Output.Position = mul(vPosition, mWorldViewProj); Output.TexCoord0 = texCoord0; return Output; } uniform sampler2D texsol : register(s0); uniform sampler2D texherbe : register(s1); uniform float alpha_herbe; // Pixel shader output structure struct PS_OUTPUT { float4 RGBColor : COLOR0; // Pixel color }; PS_OUTPUT pixelMain( VS_OUTPUT Input ) { PS_OUTPUT Output; float4 col0 = tex2D(texsol, Input.TexCoord0); float4 col1 = tex2D(texherbe, Input.TexCoord0); float alphafinal = alpha_herbe * col1.a; Output.RGBColor.rgb = col0.rgb*(1.f-alphafinal) + col1.rgb*alphafinal; Output.RGBColor.a = col0.a; return Output; }
NOTE : j'ai modifié le calcul de la couleur dans le cas que tu voudrais un hexagone transparent. La transparence de l'hexagone est générée par la valeur alpha de la texture 0.
Le nouveau "OnsetConstants()"
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) { // on récupère un pointeur sur VideoDriver IVideoDriver* driver = services->getVideoDriver(); // Matrice WorldViewProj core::matrix4 mWorldViewProj; mWorldViewProj = driver->getTransform(ETS_PROJECTION); mWorldViewProj *= driver->getTransform(ETS_VIEW); mWorldViewProj *= driver->getTransform(ETS_WORLD); // on l'envoie au GPU services->setVertexShaderConstant("mWorldViewProj", mWorldViewProj.pointer(), 16); // On envoie la valeur alpha_herbe au GPU services->setPixelShaderConstant("alpha_herbe", &alpha_herbe, 1); }
Voici un lien vers une nouvelle archive. Elle contient le nouveau shader et le callback qui va avec:
lien
Dernière modification par johnplayer (17-10-2012 08:59:09)
Hors ligne
Malheureusement, j'ai encore et toujours les même erreurs...
EDIT: nouveaux essais: j'ai remplacé la ligne <42> "Output.RGBColor.rgb = col0.rgb*(1.f-alphafinal) + col1.rgb*alphafinal;" qui pose problème par quelque chose de plus simple : "Output.RGBColor.rgb = (1.0f, 0.5f, 1.0f, 0.3f);"
j'ai alors comme message sur la console Irrlicht à chaque affichage:
"HLSL Variable to set not found: 'alpha_herbe'. Available variables are: 'texsol' Registers: [begin:0, count:1].
Mais mes hexagones sont bien gris comme on peut s'y attendre.
Je ne comprend pas trop le message d'erreur mais j'espère que ça va te donner une piste
Dernière modification par Memorial76 (17-10-2012 09:12:46)
Hors ligne
J'avais la même erreur avant mais je l'ai résolu en changeant le "alpha" du shader par "alpha_herbe" et en mettant "services->setPixelShaderConstant("alpha_herbe", &alpha_herbe, 1);" au lieu de services->setPixelShaderConstant("alpha", &alpha_herbe, 1); . Le probleme c'est qu'il n'associait pas la variable que je lui envoyais avec celle du shader.
As-tu bien changé TOUT le shader et TOUT le callback par ceux que je t'ai donné au-dessus? Je n'ai plus aucune erreur chez moi et ça marche nickel (enfin, comme avant mais sans l'erreur).
Je ne sais pas si tu as vu mais je t'ai mis une nouvelle archive avec le projet mis à jour.
Hors ligne
Voici des screens pour te montrer comment ça rend.
Avec alpha_herbe = 0.0f (totalement transparent donc pas d'herbe)
Avec alpha_herbe = 0.5f (l'herbe est visible partiellement)
Avec alpha_herbe = 1.0f (l'herbe est complétement visible)
Le rendu est celui que tu veux je pense et ça marche! Enfin chez moi.^^
Hors ligne
Oui merci, j'ai récupéré la nouvelle archive et je travaille avec mais sans succès
J'essaie en ce moment de simplifier le code du shader au maximum pour comprendre ce qui se passe: j'ai enlevé le paramètre "alpha_herbe" passé au shader et je l'ai enlevé du shader. L'erreur liée a bien entendu disparue.
En revanche, j'ai fait cet essai pour trouver le problème:
ligne <42> Output.RGBColor.rgb = col1.rgb;
cela provoque l'erreur.
Ces images sont exactement ce que je cherche à atteindre (avec alpha_herbe à 1.0). A croire qu'il me manque une fonctionnalité sur ma carte graphique.
Hors ligne
C'est vrai que tu as un chipset intégré donc pas top mais il supporte le SM4.1 donc je vois pas pourquoi il n'arrive pas à marcher correctement.
L'exe que je t'ai donné fonctionne correctement chez toi? Car si c'est le cas, c'est ton implémentation qui est en cause.
Hors ligne
En effet, ton exe fonctionne toujours nickel chez moi. Ca provient de mon implémentation du Node à tous les coups...
A la relecture du message d'erreur, il me dit qu'il ne peut pas lier l'échantillonneur au niveau spécifié par l'utilisateur et que celui-ci doit être lié au même niveau que le TEXCOORD. Est-ce qu'il ne manquerait pas un paramètre dans le material de mon node? Pourtant j'ai le même problème avec ton Octogone en .3ds.
EDIT: Je publie le code où je crée mon hexagone au cas où.
Material.Wireframe = false; Material.Lighting = false; const float d = GRANDEUR_CARACTERISTIQUE; //Centre float fx = CASE.nX * 1.5f * d; float fz; if( CASE.nX%2 == 0 ) fz = CASE.nY * sin(PI/3) * 2 *d; else fz = sin(PI/3) * d *( 1 + 2 * CASE.nY); //Vertex const float dUV = 0.5f; //Pour le calcul des coordonnées UV des vertex (entre 0.0 et 1.0) Vertices[CENTRE] = video::S3DVertex(fx, (irr::f32)CASE.fCote + 0.01f, fz, 0, 1,0, video::SColor(255,255,255,255) ,dUV,dUV*sin(PI/3)); //CENTRE Vertices[NE] = video::S3DVertex(fx + d/2, 0.01f, fz + sin(PI/3) * d, 0,1,0,video::SColor(255,255,255,255),1.5f*dUV,0); //NE Vertices[E] = video::S3DVertex(fx + d, 0.01f, fz, 0,1,0,video::SColor(255,255,255,255),2.0f*dUV,dUV*sin(PI/3)); //E Vertices[SE] = video::S3DVertex(fx + d/2, 0.01f,fz - sin(PI/3) * d, 0,1,0,video::SColor(255,255,255,255),1.5f*dUV,2*dUV*sin(PI/3)); //SE Vertices[SO] = video::S3DVertex(fx - d/2, 0.01f,fz - sin(PI/3) * d, 0,1,0,video::SColor(255,255,255,255),0.5f*dUV,2*dUV*sin(PI/3)); //SO Vertices[O] = video::S3DVertex(fx - d, 0.01f, fz, 0,1,0,video::SColor(255,255,255,255),0,dUV*sin(PI/3)); //O Vertices[NO] = video::S3DVertex(fx - d/2, 0.01f, fz + sin(PI/3) * d, 0,1,0,video::SColor(255,255,255,255),0.5f*dUV,0); //NO BoundingBox.reset(Vertices[0].Pos); for (s32 i=1; i<7; ++i) BoundingBox.addInternalPoint(Vertices[i].Pos); //TEXTURES setMaterialType(irr::video::EMT_SOLID); //SURFACE setMaterialTexture(0, pSceneMgr->getVideoDriver()->getTexture(CASE.SURFACE.sTextureFile.c_str())); //Végétation std::string sVegetationTexture = "./Textures/Vegetation/"; sVegetationTexture += m_pWorldManager->findVegetationFromThreshold(CASE.fVegetation).sTexture; if( m_pSceneMgr->getVideoDriver()->getTexture(sVegetationTexture.c_str()) ) setMaterialTexture(1, m_pSceneMgr->getVideoDriver()->getTexture(sVegetationTexture.c_str()));
il y a dedans quelques fonctions perso mais qui fonctionnent: les textures sont correctement chargées.
En espérant ne pas avoir laissé trainé une erreur à deux balles qui fait qu'on perd notre temps pour rien...
Dernière modification par Memorial76 (17-10-2012 10:03:29)
Hors ligne
Je ne vois pas de problème mais :
Ceci est inutile et potentiellement problématique puisque tu le set lorsque tu créés ton material avec le shader.
"setMaterialType(irr::video::EMT_SOLID);"
Si tu me montrais ton implémentation de la création de ton material avec le shader ce serait mieux.
Dernière modification par johnplayer (17-10-2012 10:09:32)
Hors ligne
Et voici:
video::IGPUProgrammingServices* pGPU = pDriver->getGPUProgrammingServices(); s32 newMaterialType1 = 0; s32 newMaterialType2 = 0; io::path psFileName = "./Textures/Shaders/dx.hlsl"; io::path vsFileName = "./Textures/Shaders/dx.hlsl"; CShaderCallBack* pShaderCallBack = new CShaderCallBack(pDevice); newMaterialType1 = pGPU->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psFileName, "pixelMain", video::EPST_PS_1_1, pShaderCallBack, video::EMT_SOLID); pShaderCallBack->drop(); myNode->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); myNode2->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); myNode3->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
Hors ligne
Comme je te l'ai déjà dit on ne set pas plusieurs nodes avec le même material. Créés UN node avec UN material.
Supprimes "s32 newMaterialType2 = 0;" et tout ce qui se rapporte à "myNode2" et "myNode3".
Et je pense que ton architecture de programme (à savoir la façon dont tu créés tes hexagones et les texture) est source du problème.
Ceci dit je vais quand même suivre ton architecture et créer moi-même ton hexagoneSceneNode pour voir.
Hors ligne
johnplayer :
Comme je te l'ai déjà dit on ne set pas plusieurs nodes avec le même material. Créés UN node avec UN material.
Supprimes "s32 newMaterialType2 = 0;" et tout ce qui se rapporte à "myNode2" et "myNode3".
C'est fait
Et je pense que ton architecture de programme (à savoir la façon dont tu créés tes hexagones et les texture) est source du problème.
Ceci dit je vais quand même suivre ton architecture et créer moi-même ton hexagoneSceneNode pour voir.
Ca peut en effet provenir de là:
j'ai une classe pour mon hexagone: CIrrHexagoneSceneNode
et une classe pour mon CallBack: CShaderCallBack
Hors ligne
J'ai un premier élément de solution à priori: en ajoutant dans le shader une deuxième TEXCOORD, j'arrive pratiquement au résultat escompté. Encore quelques soucis mais j'ai bien un mélange de deux textures.
Seul soucis: ma texture supérieure n'est pas à la bonne échelle, je n'ai qu'une couleur uniforme.
Dernière modification par Memorial76 (17-10-2012 12:17:39)
Hors ligne
A mon avis, rajouter une deuxième textcoord pose probleme car j'ai essayé sur mon shader et la texte herbe n'est plus à la bonne échelle. Arrêtes de t'acharner sur un shader qui marche! Le problème vient de la création du node perso. J'ai créé un node dérivé de ISceneNode et j'ai moi aussi des problème. Seul la texture sol s'affiche. Il y a un truc dans le rendu qui ne va pas, certainement la méthode onregisterscenenode() et render() à modifier.
Hors ligne
J'ai essayé de compiler ton code et uniquement ton code et le shader ne compile pas et ton octogone est tout noir.
En tout cas, j'aurai bien appris sur le fonctionnement des sahders à bidouiller comme ça. C'est aussi l'intérêt de la chose
Dernière modification par Memorial76 (17-10-2012 13:57:02)
Hors ligne
A mon avis, tu doit avoir un problème avec le répertoire d'éxécution. Quand je créé un projet, je mets "\bin" en répertoire d'éxécution. Si tu n'as pas fais ça alors il ne trouvera pas les fichiers.
Hors ligne
Non non, il compile bien le projet mais j'ai de nouveau l'erreur de shader et l'octogone apparaît tout noir.
Hors ligne
Tu compiles avec Code::Block?
Hors ligne
Si tu installais Code::Block pour voir. Tu peux prendre la bibliotheque irrlicht que j'ai mis dans l'archive, c'est la dernière SVN que j'ai compilé avec DIRECTX9. Parce que c'est un problème de ta part puisque le code marche sans erreur chez moi. Seulement je ne connais pas Visual Studio. J'ai essayé mais je trouve code::block plus pratique. Maintenant, si tu ne veux pas utiliser C::B, je te comprends très bien mais je ne pourrais pas t'aider pour la config du projet. Je t'ai donné un code complet qui marche donc j'aurai du mal à faire mieux.
Hors ligne
Tu as tout à fait raison et tu as déjà consacrer beaucoup de temps à me dépanner. Je t'en remercie.
Je ne vais pas installer code::bloc étant maintenant familier avec visual. Je vais aller exposer le problème sur le forum Irrlicht directement. Je te tiens au courant de l'évolution.
Merci à toi encore.
Hors ligne