Bonjour,
J'ai possibilité d'exporter les materiaux de 3ds max sous forme de fichiers *.FX. Est-il possible d'utiliser ces fichiers dans irrlicht ou faut-il les convertir en fichier style *.hlsl ou autre ?
Hors ligne
En règle générale les fichier 'fx' sont des fichiers HLSL, ceux générés par 3DSMax ne devraient pas déroger à la règle je suppose.
Maintenant de la à dire que tu puisses les employer directement dans tes codages Irrlicht, là je ne peux te répondre... plus qu'a attendre qu'un spécialiste passe par là .
Hors ligne
ok, merci. j'ai télécharger fxcompositor2.5 de nvidia et lui aussi me sort des *.fx alors si je pouvais les utiliser cà m'aiderais beaucoup.
Hors ligne
C'est bon pour les fichiers, j'ai trouver un petit logiciel fourni avec fxcompositor qui permet de sortir les fichier en hlsl et glsl.
Maintenant le probleme réside dans l'utilisation. Malgré le tuto d'irrlicht, j'éprouve quelques problèmes à intégrer les shaders dans ma scene.
Il me dit :
vertex info
-----------
(0) : error C5052: gl_FragColor is not accessible in this profile
Fragment info
-------------
(0) : error C5052: gl_BackColor is not accessible in this profile
(0) : error C5052: gl_FrontColor is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord5 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord3 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord1 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord4 is not accessible in this profile
(0) : error C5052: gl_Vertex is not accessible in this profile
(0) : error C5052: gl_Position is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord0 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord2 is not accessible in this profile
(0) : error C5052: gl_Normal is not accessible in this profile
Ma carte le supporte il n'y a pas de problème à ce niveau là. Si quelqu'un a une idée qu'il ne se gène pas. Et j'utilise GLSL.
Dernière modification par johnplayer (21-10-2008 17:53:59)
Hors ligne
Si cela peut t'aider, voici un code de base qui utilise le GLSL, c'est basic, mais c'est son but, si cela
peut te permettre d'y voir plus clair. Ce code fonctionne sans soucis
la partie code C++ Irrlicht:
#include <irrlicht.h> using namespace irr; using namespace core; using namespace scene; using namespace video; #ifdef _IRR_WINDOWS_ #pragma comment(lib, "Irrlicht.lib") #endif /* données globales */ bool _bExit = false; ISceneNode* cube1; //============================================================================================= // surcharge de la classe IEventReceiver, pour la gestion des entrés clavier dans notre cas. class MyEventReceiver : public IEventReceiver { public: virtual bool OnEvent(const SEvent& event) { if (event.EventType == irr::EET_KEY_INPUT_EVENT ) { switch(event.KeyInput.Key) { case KEY_ESCAPE: { _bExit = true; return true; } } } return false; } }; //============================================================================================= //============================================================================================= //procedure 'main', point d'entrée du programme commun à toute les plateformes. int main() { // définition de notre classe dérivé, pour la gestion // des entrées clavier MyEventReceiver _EventReceiver; // Ici driver OGL car emploi de GLSL, donc uniquement OpenGL video::E_DRIVER_TYPE driverType; driverType = video::EDT_OPENGL; IrrlichtDevice *device = createDevice( driverType, dimension2d<s32>(800, 600), 32, false, false, true, &_EventReceiver); // petite redifinition du titre de la fenetre. device->setWindowCaption(L"Tuto_Shader1 - Premier shader GLSL"); /* une fois le device créé, on va récupérer un certain nombre de pointeur qui vont nous être utile pour la suite. Entre-autre: video driver, SceneManager et gui. */ IVideoDriver* driver = device->getVideoDriver(); ISceneManager* scenegraph = device->getSceneManager(); IGPUProgrammingServices *gpu= driver->getGPUProgrammingServices(); s32 matid = video::EMT_SOLID; matid = gpu->addHighLevelShaderMaterialFromFiles( "../shaders/exemple1.vs", "main", video::EVST_VS_2_0, "../shaders/exemple1.ps", "main", video::EPST_PS_2_0, NULL, video::EMT_SOLID, 0); // notre petit mesh, tranquille // cube 1 cube1 = scenegraph->addCubeSceneNode(2.0f, scenegraph->getRootSceneNode()); // si notre petit cube est créé comme il s doit, alors on applique quelques // menu intialisation if (cube1) { SMaterial *mat = &cube1->getMaterial(0); mat->setFlag(EMF_LIGHTING , false); mat->setTexture( 0, driver->getTexture("../../../media/stones.jpg") ); // instruction clé, c'est là que l'on stipule au moteur3D que le rendu de notre cube1 ne vas // pas passer par le pipeline fixe, mais à travers un shader cube1->setMaterialType( (video::E_MATERIAL_TYPE) matid ); } /* creation de notre camera, ici une camera un peu particulière, il s'agit d'une camera de type FPS, qui simule une vue à la première personne. */ // définition des touches de controle de notre futur camera. SKeyMap keyMap[4] = { {EKA_MOVE_FORWARD, KEY_UP}, {EKA_MOVE_BACKWARD, KEY_DOWN}, {EKA_STRAFE_LEFT, KEY_LEFT}, {EKA_STRAFE_RIGHT, KEY_RIGHT}, }; /* phase de creation et de positionnement. */ ICameraSceneNode* cam = scenegraph->addCameraSceneNodeFPS( scenegraph->getRootSceneNode() , 100.0f, 50.0f, -1, keyMap, 4); cam->setPosition(core::vector3df(0,3,-5)); cam->setRotation( core::vector3df(20,0,0) ); // boucle principale de rendu int lastFPS = -1; while(device->run() & !_bExit) { driver->beginScene(true, true, SColor(255,100,101,140)); scenegraph->drawAll(); driver->endScene(); // affichage dans le titre de quelques info int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Tuto_Shader1 - Premier shader"; str += " FPS:"; str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } /* Une fois sortie, c'est la fin, avec la libération de toutes les ressources créées par 'createDevice'. */ device->drop(); return 0; } //=============================================================================================
maintenant le fichier exemple1.vs
varying vec3 normal; void main() { normal = gl_NormalMatrix * gl_Normal; gl_Position = ftransform(); }
et le fichier exemple1.ps
varying vec3 normal; void main() { float intensity; vec4 color; vec3 n = normalize(normal); intensity = dot(vec3(gl_LightSource[0].position),n); if (intensity > 0.95) color = vec4(1.0,0.5,0.5,1.0); else if (intensity > 0.5) color = vec4(0.6,0.3,0.3,1.0); else if (intensity > 0.25) color = vec4(0.4,0.2,0.2,1.0); else color = vec4(0.2,0.1,0.1,1.0); gl_FragColor = color; }
Voila, le media pour la texture n'a pas vraiment d'importance.
Hors ligne
1/ Etant donné que j'utilise deux fichiers *.glsl (fichier_v.glsl et fichier_p.glsl) cela ne change t'il rien pour irrlicht par rapport à un *.ps et un *.vs ?
2/ De plus, d'après mes recherches il faut que je lui passe des paramètres comme les textures qu'il va utiliser, des nombres, ect... Comment puis-je lui transmettre ?
Je m'explique dans un autre code, j'ai vu ceci :
services->setVertexShaderConstant("AlphaAdjust", &AlphaAdjust, 1); // un simple float pour l'alpha int TexAddress = 0; ITexture * RTTexture = driver->getTexture("texture.png"); services->setPixelShaderConstant("RTTexture", (float*)(&TexAddress), 1); // transmission d'une texture SColor TintColour = SColorf(1.0f,1.0f,1.0f,1.0f); services->setPixelShaderConstant("TintColour", (float*)(&TintColour.r), 4); // transmission d'une couleur
Sachant que dans son pixel shader, il y a :
uniform sampler2D RTTexture; uniform sampler2D NormalMap; uniform vec4 TintColour; varying vec4 GlassPos; varying vec2 TexCoord; varying float VAlpha;
En fait, en rééditant mon post je crois que j'ai trouver ma réponse, reste plus qu'à essayer!
PS : Merci pour le code tmyke, il est très clair et bien expliqué.
Dernière modification par johnplayer (22-10-2008 10:31:46)
Hors ligne
J'suis pas encore un pro des shaders, mais si tu à effectivement trouvé, alors la solution serait en effet interessante...
Hors ligne
Si j'arrive à quelque chose, j'essairai de te faire un tuto en guise de remerciement. Parce que c'est peut-être une impression mais en règle générale, il n'y a que nous deux de connectés et puis tu m'aides sur chaque question que je pose ce que je trouve sympa.
Hors ligne
C'est vrai que c'est calme en ce moment, et comme je suis en vacances, j'essaie dans la mesure de mes moyens d'aider un petit peu quand je le peu.
Pour le tuto, ce serait cool, pour moi déjà, mais aussi je pense que cela sera aussi utile pour d'autres qui seront certainement confronté à ces problèmes à partir du moment
ou ils voudront se coller aux shaders avec Irrlicht.
Hors ligne
Moi je veux bien essayer de répondre mais je ne suis pas sûr de toutes les questions alors je vais répondre à ce que je comprends.
Pour tes problèmes de "is not accessible in this profile", le code d'exemple de tmyke utilise video::EVST_VS_2_0 et video::EVST_PS_2_0 qui permettent au compilateur des shaders de s'adapter au profil de ta carte graphique (ici en l'ocurence le support de shaders 2.0). Si tu as l'erreur "is not accessible in this profile" c'est que le profil donné ne permet pas d'utiliser les méthodes utilisées dans ton shader(gl_FragColor etc.)
Sinon pour alimenter les variables déclarées dans ton shader et utiliser le bout de code que tu as trouvé "services->setPixelShaderConstant("TintColour", etc.", il faut brancher une callback lors de la création du shader, regarde la doc des méthodes telles que addHighLevelShaderMaterialFromFiles() ou asimilées. Une fois ta callback branchée, celle ci sera appellée à chaque fois que l'on va rendre à l'écran un material utilisant le shader, tu pourras alors, à l'aides des méthodes setPixelShaderConstant et assimilées, jouer sur les variables déclarées dans le shader.
Pour les textures, le moteur utilise celles qui sont dans le SMaterial auquel tu as attaché le shader avec la méthode cube1->setMaterialType( (video::E_MATERIAL_TYPE) matid ); dans le code de tmyke. Normalement si ce SMaterial est bien configuré tu n'as pas à te soucier des textures.
Voilà, enjoy !
Je guette ce thread si tu as d'autres problèmes ou plus de questions.
Dernière modification par Piraaate (22-10-2008 16:36:59)
Hors ligne
Merci Piraate pour tes explications même si mes recherches m'ont menées au même point. Sinon, en glsl il faut transmettre les variables déclarées avec uniform (uniform type_variable nom_de_la_variable), les autres sont internes au shader.
Pour la transmettre :
Dans fichier_f.glsl, on a :
uniform sampler2D RTTexture; // texture extérieure utilisée par le shader car uniform
Dans Irrlicht main :
ITexture * texture1 = driver->getTexture("fichier");
node->setMaterialTexture(0, "texture1");
Dans Irrlicht fonction appelante shader :
services->setPixelShaderConstant("RTTexture", 0, 1); // transmission d'une texture avec 0 l'id de la layer et 1 le nombre de variables // transmises.
Voilà pour le moment.
Hors ligne
Je suis confronté au même genre de soucis, mais avec les HLSL.
- dans un premier temps, lorsque je tente de passer un pointeur de texture, il me met un message d'erreur
comme celui-ci:
HLSL Variable not found to set not found: 'Main'.
alors que dans mon shader j'ai bien la ligne suivante:
texture Main;
je ne comprend donc pas vraiment, en sachant qu'en compilant ce shader directement par DirectX, il n'y a aucun soucis,
cela fonctionne très bien.
- deuxième point, et pour rejoindre johnplayer, je comprends toujours pas vraiment comment passer justement en paramètre
a mon shader un pointeur de texture, émanant d'un material d'un mesh . En DirectX sela s'écrirait 'effect->setTexture( "Main", IDirect3DBaseTexture9* ptr);'
mais là, je bloque. J'ai parcouru le forum off, mais sans réponse réél...
Hors ligne
Content de lire que tu t'en es sorti !
johnplayer :
Sinon, en glsl il faut transmettre les variables déclarées avec uniform (uniform type_variable nom_de_la_variable), les autres sont internes au shader.
Tu as raison, c'est valable en hlsl aussi.
johnplayer :
Dans Irrlicht fonction appelante shader :
Code:
services->setPixelShaderConstant("RTTexture", 0, 1); // transmission d'une texture avec 0 l'id de la layer et 1 le nombre de variables // transmises.
Par contre je suis étonné de voir le code précédent, mais après tout pourquoi pas c'est peut être une différence d'utilisation entre glsl et hlsl (je n'ai vraiment utilisé que hlsl).
Car en hlsl tu déclares ta texture comme ça:
uniform sampler2D baseMap : register(s0);
Et du coup pas besoin de rappeller lors de la callback car D3D sera "setté" comme il faut lors du rendu du mesh... Ceci devrait répondre à ta question tmyke car le settexture dont tu parles est fait à ce moment là, me trompe-je ?
Dernière modification par Piraaate (22-10-2008 18:04:03)
Hors ligne
Pour les hlsl je ne pourrais pas vous aidez car je ne me suis pas penché a fond dessus. Pour l'instant j'essaie d'utiliser les glsl car il m'ont l'air plus facile à comprendre.
Mais si je vois quelque chose sur les hlsl d'intéressant je vous le fait savoir.
Hors ligne
Au fait pour la fonction appelante elle se trouve dans la doc d'irrlicht :
namespace video >> IShaderConstantSetCallBack >> OnSetConstants (IMaterialRendererServices *services, s32 userData); Pour celui que cà intéresse.
Hors ligne
Piraaate :
Car en hlsl tu déclares ta texture comme ça:
Code:
uniform sampler2D baseMap : register(s0);Et du coup pas besoin de rappeller lors de la callback car D3D sera "setté" comme il faut lors du rendu du mesh... Ceci devrait répondre à ta question tmyke car le settexture dont tu parles est fait à ce moment là, me trompe-je ?
Hmmm, en fait la syntaxe varie d'un fichier HLSL à l'autre si je voie bien le truc. Dis moi si je me trompe, mais si dans mon shader, j'ai la
sequence suivante:
texture Main; sampler MainSamp = sample_state { Texture = (Main) MipFilter = LINEAR; };
cela sera pas exploitable à travers des instructions Irrlicht ?
Hors ligne
En hlsl pas besoin de donner la texture avec irrlicht il suffit de la déclarer dans le hlsl de cette facon:
En tout cas c'est ce que j'ai dans mon hlsl. J'espère que ca resoudra ton probleme tmyke.
Hors ligne
Merci johnplayer. En fait j'ai cet syntaxe aussi au départ. Le soucis, c'est que cela d'initialise tes valeur ,je dirais, par defaut.
Le soucis vient quand tu souhaite les adapter à chaque mesh en particulier, et en fonction de leurs textures propres..
Hors ligne
A je n'avais pas vu cà sous cet angle. Je n'arrive pas a trouver d'exemple de hlsl avec des variables declarer en externes. Donc je ne peux rien tester. Mais comme je l'ai dit plus haut si j'ai du nouveau je vous le fait savoir. Par contre j'ai remarqué que beaucoup utilise les glsl donc on trouve plus facilement de l'aide et des exemples.
Hors ligne
Oui, c'est vrai que le GLSL semble beaucoups répendu, dommage pour moi. Mais je vais continuer à chercher, petit à petit je devrais bien arriver à trouver
des solutions. Comme toi, dès que j'ai du concret je fais signe...
Hors ligne
J'ai vu ton mail johnplayer, mais entre temps la discussion à bien avancée à ce que je vois, du coup je suis un peu perdu : quel est le problème maintenant ?
Mais en passant :
vertex info
-----------
(0) : error C5052: gl_FragColor is not accessible in this profile
Fragment info
-------------
(0) : error C5052: gl_BackColor is not accessible in this profile
(0) : error C5052: gl_FrontColor is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord5 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord3 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord1 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord4 is not accessible in this profile
(0) : error C5052: gl_Vertex is not accessible in this profile
(0) : error C5052: gl_Position is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord0 is not accessible in this profile
(0) : error C5052: gl_MultiTexCoord2 is not accessible in this profile
(0) : error C5052: gl_Normal is not accessible in this profile
Ma carte le supporte il n'y a pas de problème à ce niveau là. Si quelqu'un a une idée qu'il ne se gène pas. Et j'utilise GLSL.
Ces fonctions sont utilisés pour les pixels shaders, or là tu les utilise pour un vertex shader (et vice versa par la suite). D'où le fait que ce ne soit pas "accessible dans ce profil".
Tu as surement du inverser ton pixel shader et ton vertex shader.
Hors ligne
Merci Aranoth d'avoir répondu. Le problème venait du fait que je n'avais pas appelé OnSetConstants. Donc il ne trouvait pas les textures ni leurs coordonnées d'où les erreurs.
Sinon Anaroth, il me semble que c'est toi qui a commené un projet du nom de AEREVEN énoncé sur planet-Dev. Si c'est le cas tu as déjà bien manipulé les shaders. Serait-il possible de savoir ou trouver de la bonne doc (en francais de préférence car je n'ai fait qu'un an d'anglais alors...) ou m'aider à comprendre comment se programme les shaders glsl ou hlsl si tu te sent plus à l'aise avec ce dernier. Parce que j'ai trouvé de la doc et des tutos mais rien de ce que j'ai ne répond à mes attentes.
Parce que je voudrais faire un shader (en glsl de préférence) qui simule l'eau pour avoir un rendu plus réaliste qu'irrlicht et en déchargeant le processeur de quelques calculs. Mais le problème c'est que la seule chose que j'ai réussi à faire est un simple texturing.
Mon idée pour l'eau c'est d'avoir 2 textures (une normalemap et une texture couleur) de faire un bump mapping, puis de translater à chaque frames la normalemap (la matrice tout du moins). De cette facon la surface est plus fluide plus lisse que le rendu d'irrlicht.
Pour le bump mapping je vais peut-être y arriver (je dis bien peut-être) mais pour ce qui est de translater la matrice de la normalmap je ne sais pas comment m'y prendre.
Hors ligne
Hop, un petit tuto qui j'espère sera utile : video/les-shaders-glsl-avec-irrlicht">http://www.planet-dev.com/developpement … c-irrlicht
Hors ligne
Tout simplement magnifique! En plus, il est fait sur mesure. Grand merci Aranoth!
Juste quelques coins d'ombres, tu as écrit :
core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD); invWorld.makeInverse(); services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16); // Set clip matrix core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); worldViewProj *= driver->getTransform(video::ETS_VIEW); worldViewProj *= driver->getTransform(video::ETS_WORLD); services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
Au final, que représente invWorld et WorldViewproject.
Pour WorldViewproject, je dirais que c'est ce que voit la camera mais j'en doute fortement. Mais bon, j'attends la réponse du connaisseurc'est plus sûr.
Autres remarques, d'après ce que j'ai pu lire sur le Net, le shader est appelé autant de fois que de texel à calculer d'où la nécessité d'avoir (et de toute façon de devoir) une variable externe pour l'animation.
Parce que pour produire mes propres shaders j'ai besoin de le savoir afin de savoir ce que je manipule. Par la suite, j'aimerai rajouter la réflection et la réfraction, du moins quand j'en aurais le niveau.
En tout cas, tuto nickel et super rapide à comprendre. Encore une fois merci. Et au fait, ton tuto est utile, il y a pas mal de monde qui vas aller le voir tu peux en être sûr.
Dernière modification par johnplayer (23-10-2008 18:40:57)
Hors ligne
Ça c'est directement lié au fonctionnement même de la 3D.
Je l'ai repris du tuto officiel, mais ce n'est pas pas obligatoire (GLSL permet d'accèder aux différentes matrices via ses propres instructions)
invWorld est la matrice inverse de la matrice du monde et worldViewProj le produit des trois matrices.
World = la matrice de transformation du monde (la scène), donc la transformation en cours pour l'objet dessiné
View = la matrice de vue, donc la transformation de la caméra (position, inclinaison, ...)
Proj = la matrice de projection, comprendre par là la perspective (orthogonale pour la 2D)
C'est cette matrice qu'on utilise pour faire le passage de la 3D (la scène) à la 2D (l'écran)
Mais tout ça c'est vraiment inhérent à la 3D, pas à Irrlicht, ni aux shaders. Au même titre que le pipeline de rendu fixe.
A la limite s'initier directement à OpenGL est un bon moyen de comprendre les transformations et tout ce qui est un peu "bas niveau" comme ça.
Hors ligne
Options | Liens officiels | Caractéristiques | Statistiques | Communauté |
---|---|---|---|---|
Corrections |
|
xhtml 1.0 css 2.1 Propulsé par FluxBB Traduit par FluxBB.fr |
882 membres 1429 sujets 11119 messages |
Dernier membre inscrit: LiseBuisson96 36 invités en ligne Aucun membre connecté RSS Feed |