Autre question, comment peut-on augmenter l'effet du bump afin d'augmenter la hauteur des vagues? Pour que les vagues soient bien visibles pour un océan par exemple.
Hors ligne
Ça par contre je ne peux pas t'aider, je ne me suis pas penché sérieusement sur la théorie, je me suis contenté de transcrire le tutoriel sur oZone3D.
Le bump mapping n'est certainement pas l'effet le plus simple, mathématiquement parlant.
Hors ligne
Merci quand même Aranoth. Je suis en train d'épluché le tuto d'ozone3d justement. Je vous fait part de mes progrès dès qu'il y a lieu.
Hors ligne
Super en effet ce tuto Aranoth, je garde cela précieusement dans un petit coin, je le mettrait en lien d'ici peu.
Johnplayer, comme le souligne Aranoth, le BumpMapping n'est pas un des effets les plus faciles à appréhender.
Pourquoi ne pars-tu pas d'un GLSL déjà existant, sur lequel tu pourrais travailler, en modifiant les valeurs et doucement le codage pour
en comprendre les mécanismes. C'est souvent une methode fort instructive...
Hors ligne
Je me demandais, pour commencer dans les shaders je devrais peut-être commencer par revoir les méthodes de texturing d'irrlicht.
Je m'explique :
si je ne m'abuse, irrlicht utilise le CPU pour effectuer le texturing, le bump mapping et tout les autres opération de texturing. Il serait bien d'alléger le CPU et de donner le travail à qui de droit c'est-à-dire le GPU. Je pense donc que je vais me créer une bibliothèque de shaders pour le texturing.
Je voudrais donc être sûr qu'irrlicht utilise bien le CPU pour le texturing. Alors si quelqu'un peut me confirmer mon hypothèse se serait sympa.
Dernière modification par johnplayer (24-10-2008 16:59:55)
Hors ligne
Qu'entends tu par 'irrlicht utilise le CPU pour effectuer le texturing' ?
En fait pour résumer, à moins qu'un pro du code d'Irrlicht infirme ce que je dis, lors d'une passe de rendu, Irrlicht
effectue ces opération de rendu globalement de la façon suivante (speudo code):
device->SetMaterial( material ); // les différentes couleurs (Amb, Dif, Spec, Em, power) liées au mesh à rendre device->SetTexture( chanel, image); // envoie sur l'un des canaux de la CG d'une texture. device->drawPrimitive( buffers...); // envoie des buffers qui vont biens vers le pipeline de rendu.
Dernière modification par tmyke (24-10-2008 17:55:31)
Hors ligne
En fait, en y réfléchissant, je me suis aperçu que ce que je disais été absurde. Il y a des moments je péte des câbles.
Paix à mes neurones...
Sinon j'ai suivi le tuto sur le displacement mapping, j'ai copié vertex et pixel shader et j'y ai ajouté l'animation pour les vagues. J'ai mis les paramètres de réglages de la vitesse des vagues, leur direction et leur hauteur.
Maintenant faut que je vois pour la réflection et la réfraction. Le plus gros morceau quoi!
Hors ligne
Je vois que tu avance bien. Attention pour ce qui est reflection et refraction, c'est souvent ce qui plombe le frame rate
car lourd en terme de rendu.
Hors ligne
Pour la réflexion et la réfraction tu aura besoin de définir un plan de clipping puis faire un rendu vers texture.
Je ne sais pas si le plan de clipping a été ajouté dans Irrlicht, mais il y a quelque temps (version 1.2) il n'y était pas
Hors ligne
Dans video driver il y a ça :
1/ setClipPlane (u32 index, const core::plane3df &plane, bool enable=false)
2/ enableClipPlane (u32 index, bool enable)
3/ setRenderTarget (video::ITexture *texture, bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=video::SColor(0, 0, 0, 0))
Donc pour les fonctions c'est ok, maintenant pour l'utilisation.
Avant la boucle de rendu :
ITexture * tex_refrac = 0; // texture de rendu pour la réfraction
plane3df refraction.setPlane(const vector3df &point1, const vector3df &point2, const vector3df &point3); // à remplacer par les valeurs.
refraction.Normal = vector3df(x,y,z); // normale du plan
//refraction.D = valeur; // ?
driver->setClipPlane(1,refraction,false); // on créé le clipping plane désactivé
// on met la texture dans le materiaux du waterscenenode
node->setMaterialTexture(2, tex_refract);
Dans la boucle de rendu :
while ( device->run() ) { if ( device->isWindowActive() ) { driver->beginScene(true, true, SColor(255,128,128,128)); // texture pour la refraction driver->enableClipPlane(1, true); driver->setRenderTarget(tex_refrac); driver->enableClipPlane(1, false); // on dessine la scene smgr->drawAll(); driver->endScene(); } }
Je t'avouerais que pour l'utilisation je ne suis pas sûr de mon coup.
Maintenant quelques questions :
1/ Pourquoi 3 points alors que 2 auraient suffit pour créer le plan ?
2/ refraction.D, je n'en comprend pas l'utilité. En ai-je besoin ? Si oui, comment la paramétrer ?
Dernière modification par johnplayer (24-10-2008 20:41:08)
Hors ligne
Pour faire les plans, c'est encore plus simple :
plane3df refraction ( vector3df( 0 , 0 , 0 ) , vector3df ( 0 , -1 , 0 ) ); plane3df reflexion ( vector3df( 0 , 0 , 0 ) , vector3df ( 0 , 1 , 0 ) );
Tu donnes un point par lequel le plan passe (l'origine par exemple) et la normale (vers le bas pour la refraction et vers le haut pour la reflexion) : ça te fait un plan horizontal
La distance D n'est pas nécessaire (surtout si le plan passe par l'origine).
Par contre ta boucle est fausse, il faudrait plutôt faire :
driver->beginScene(true, true, SColor(255,128,128,128)); // texture pour la refraction driver->enableClipPlane(1, true); driver->setRenderTarget(tex_refrac); smgr->drawAll(); driver->setRenderTarget(0, true, true, 0); driver->enableClipPlane(1, false); // on met la texture dans le materiaux du waterscenenode node->setMaterialTexture(2, tex_refract); // on dessine la scene smgr->drawAll(); driver->endScene();
Tiens ça m'intéresse tout ça, peut être que je vais essayer de l'implémenter, just for fun
Hors ligne
Merci pour la correction, j'ai plus qu'à corriger un problème. Les vertex de mon mesh apparait et disparait j'ai des bouts de texture enfin le grand n'importe quoi. Mais avec les fragments de texture que j'ai pu apercevoir, je peux voir que le render to texture est correct.
J'ai l'impression que la texture est le rendu de ce que je vois avec la camera.
Dernière modification par johnplayer (24-10-2008 21:35:53)
Hors ligne
C'est normal, c'est le cas.
Le RTT ne fait qu'écrire le contenu du back buffer dans une texture (au lieu du front buffer).
Pour l'appliquer correctement sur le plan d'eau, il faut se prendre la tête avec la projection de texture. C'est ce sur quoi je me documente en ce moment.
#include <irrlicht.h> #include <iostream> using namespace irr; #include "MyShaderCallBack.h" int main ( int argc , char** argv ) { // Initialise Irrlicht IrrlichtDevice* device = createDevice ( video::EDT_OPENGL , core::dimension2d<s32>(640, 480) ); video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); gui::IGUIEnvironment* gui = device->getGUIEnvironment(); // Verifie le support des shaders bool pixel_shader_support = ( driver->queryFeature ( video::EVDF_PIXEL_SHADER_1_1 ) || driver->queryFeature ( video::EVDF_ARB_FRAGMENT_PROGRAM_1 ) ); bool vertex_shader_support = ( driver->queryFeature ( video::EVDF_VERTEX_SHADER_1_1 ) || driver->queryFeature ( video::EVDF_ARB_VERTEX_PROGRAM_1 ) ); if ( !pixel_shader_support || !vertex_shader_support ) { std::cerr << "Les shaders 1.1 ne sont pas supportés !" << std::endl; } // Creer le shader video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); // L'ID du matériau personnalisé s32 newMaterialType = 0; if (gpu) { // On instancie notre callback MyShaderCallBack* shader_callback = new MyShaderCallBack ( device ); // On créer un nouveau matériau à partir du shader newMaterialType = gpu->addHighLevelShaderMaterialFromFiles( "vertex_shader.vert", "main", video::EVST_VS_1_1, "pixel_shader.frag", "main" , video::EPST_PS_1_1, shader_callback, video::EMT_SOLID); shader_callback->drop(); } // Ajoute un plan d'eau scene::IAnimatedMesh* water_mesh = smgr->addHillPlaneMesh("myHill", core::dimension2d<f32>(1000,1000), core::dimension2d<u32>(2,2), 0, 0, core::dimension2d<f32>(0,0), core::dimension2d<f32>(1,1)); scene::ISceneNode* water_node = smgr->addMeshSceneNode ( water_mesh->getMesh(0) ); water_node->setMaterialTexture ( 0 , driver->getTexture ( "Water2.jpg" ) ); water_node->setMaterialTexture ( 1 , driver->getTexture ( "waves.jpg" ) ); water_node->setMaterialFlag ( video::EMF_LIGHTING , false ); water_node->setMaterialType ( (video::E_MATERIAL_TYPE)newMaterialType ); // Ajoute un cube texturé et lui assigne le shader scene::ISceneNode* node = smgr->addCubeSceneNode(50); node->setPosition ( core::vector3df ( 0 , 10.0f , 0 ) ); node->setMaterialTexture ( 0 , driver->getTexture ( "chess.jpg" ) ); node->setMaterialFlag ( video::EMF_LIGHTING , false ); // Fait tourner le cube sur lui même scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator ( core::vector3df ( 1.0f , 0.3f , 1.0f ) ); node->addAnimator ( anim ); anim->drop(); // Ajoute une caméra à la scène scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f); cam->setPosition(core::vector3df(-100,50,100)); cam->setTarget(core::vector3df(0,0,0)); // Créer les textures pour le RTT (la moitié de la résolution réelle suffira) video::ITexture* refraction_texture = driver->createRenderTargetTexture ( core::dimension2d<s32>( 320 , 240 ) ); video::ITexture* reflexion_texture = driver->createRenderTargetTexture ( core::dimension2d<s32>( 320 , 240 ) ); // Créer les plans de clipping core::plane3df refraction ( core::vector3df( 0 , 0 , 0 ) , core::vector3df ( 0 , -1 , 0 ) ); core::plane3df reflexion ( core::vector3df( 0 , 0 , 0 ) , core::vector3df ( 0 , 1 , 0 ) ); driver->setClipPlane( 1 , refraction , false ); driver->setClipPlane( 2 , reflexion , false ); // Boucle du jeu while ( device->run() ) { if ( device->isWindowActive() ) { driver->beginScene(true, true, video::SColor(255,128,128,128)); // Refracion driver->enableClipPlane ( 1 , true ); driver->setRenderTarget ( refraction_texture ); water_node->setVisible ( false ); smgr->drawAll(); driver->enableClipPlane ( 1 , false ); // Reflexion driver->enableClipPlane ( 2 , true ); driver->setRenderTarget ( reflexion_texture ); smgr->drawAll(); driver->enableClipPlane ( 2 , false ); // Reel driver->setRenderTarget( 0 , true , true , 0 ); water_node->setVisible ( true ); water_node->setMaterialTexture ( 2 , refraction_texture ); water_node->setMaterialTexture ( 3 , reflexion_texture ); smgr->drawAll(); // Pour tester : affiche les deux textures en haut de l'écran //driver->draw2DImage ( refraction_texture , core::position2di ( 0 , 0 ) ); //driver->draw2DImage ( reflexion_texture , core::position2di ( 320 , 0 ) ); driver->endScene(); } } device->drop(); return 0; }
Hors ligne
Dans ce cas a quoi sert le clipping plane ?
Hors ligne
A supprimer tout ce qui est au dessus ou au dessous du plan.
Mais la vue restera celle de la caméra.
Petite capture d'écran pour voir à quoi ça ressemble concrètement :
Hors ligne
J'ai repris ton code pour essayer mais même avec ton code mon clipping plane est vertical et non horizontal. je ne comprend pas puisque ma normale est bonne.
Hors ligne
Au fait copland a déjà travailler sur un shader d'eau et il y est réussi se serait sympa qu'il nous parle de la technique qu'il a utilisé.
Hors ligne
En attendant, tu peux regarder ce qu'a fait Nils Daumann, j'ai testé certains de ces codes, et en particuliers
celui nomé 'WaterV1.rar', il est tout à fait dans la veine de ce que tu cherches à faire. C'est vraiment splendide.
Le décortiquer pourrait certainement t'apporter une partie des explications que tu cherches.
Le site ici http://www.ssmasters.de/
Par contrele shader est en HLSL, mais pour les grand principes, c'est très instructif, y compris dans le code C++.
Dernière modification par tmyke (25-10-2008 11:25:00)
Hors ligne
Il y a un probleme avec clipping plane il coupe tout les objet en deux et non pas la scene.
Hors ligne
Bizarre, chez moi cela semble fonctionner sans soucis, avec ce petit code par exemple on voie
bien les changement de clipPlane...
#include <irrlicht.h> using namespace irr; using namespace core; using namespace scene; using namespace video; /* librairies */ #ifdef _IRR_WINDOWS_ #pragma comment(lib, "Irrlicht.lib") #endif /* données globales */ bool _bExit = false; IVideoDriver* driver; ISceneNode* node1; ISceneNode* node2; ISceneNode* node3; /* 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 && !event.KeyInput.PressedDown) { switch(event.KeyInput.Key) { case KEY_ESCAPE: { _bExit = true; return true; } case KEY_KEY_S: { core::plane3df reflexion ( core::vector3df( 0 , 10 , 0 ) , core::vector3df ( 0 , 1 , 0 ) ); driver->setClipPlane( 1 , reflexion , false ); return true; } } } return false; } }; /* procedure 'main', point d'entrée du programme commun à toute les plateformes. */ int main() { static int oldTime; // définition de notre classe dérivé, pour la gestion // des entrées clavier MyEventReceiver _EventReceiver; // let user select driver type video::E_DRIVER_TYPE driverType = EDT_DIRECT3D9; IrrlichtDevice *device = createDevice( driverType, dimension2d<s32>(800, 600), 32, false, false, true, &_EventReceiver); /* video driver, SceneManager et gui. */ driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); ITimer *timer = device->getTimer(); /* mes nodes */ node1 = smgr->addCubeSceneNode(15.0f); node2 = smgr->addSphereSceneNode(7.0f); node2->setPosition( vector3df(10,20,0)); node3 = smgr->addSphereSceneNode(7.0f); node3->setPosition( vector3df(-10,10,0)); /* textures et light=false */ if (node1) { node1->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); node1->setMaterialFlag ( video::EMF_LIGHTING , false ); } if (node2) { node2->setMaterialTexture( 0, driver->getTexture("../../media/fire.bmp") ); node2->setMaterialFlag ( video::EMF_LIGHTING , false ); } if (node3) { node3->setMaterialTexture( 0, driver->getTexture("../../media/fire.bmp") ); node3->setMaterialFlag ( video::EMF_LIGHTING , false ); } /* 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}, }; /* nous définissons une camera, dans un mode FPS. Nous la positionnons et ont définit la direction vers laquelle elle va pointer. */ smgr->addCameraSceneNodeFPS( NULL , 100.0f, 310.0f, -1, keyMap, 4); smgr->getActiveCamera()->setPosition(core::vector3df(0,20,-30)); smgr->getActiveCamera()->setTarget(core::vector3df(0,5,0) ); // Créer les plans de clipping core::plane3df reflexion ( core::vector3df( 0 , 4 , 0 ) , core::vector3df ( 0 , 1 , 0 ) ); driver->setClipPlane( 1 , reflexion , false ); /* maintenant que tout les éléments sont en place, place à la boucle principale, pour dessiner tout cela. Pour quiter, deux solutions, soit un petit coups de ALT+F4, ou alors la touche ESC que nous avons définit dans notre boucle de traitement des événements (impliquant le changement d'état de notre flag _bExit). */ int lastFPS = -1; while(device->run() & !_bExit) { /* Tout ce qui doit être dessiné doit l'être entre les deux instructions beginScene() and an endScene(). L'instruction 'beginScene' effece l'ecran avec la couleur de notre choix. */ driver->beginScene(true, true, SColor(255,100,101,140)); driver->enableClipPlane ( 1 , true ); smgr->drawAll(); driver->endScene(); node1->setRotation( node1->getRotation() + vector3df(0,1.0f,0) ); // calcul du fps int fps = driver->getFPS(); if (lastFPS != fps) { lastFPS = fps; } // affichage de quelques informations dans la barre de titre // de la fenetre, avec timer pour éviter le scintillement. int time = timer->getRealTime(); if((time - oldTime) >100 ) { core::stringw str = L"Tuto 3 - Troisième essais"; str += " FPS:"; str += fps; str += " ESC=sortir"; device->setWindowCaption(str.c_str()); oldTime = time; } } /* Une fois sortie, c'est la fin, avec la libération de toutes les ressources créées par 'createDevice'. */ device->drop(); return 0; }
Dernière modification par tmyke (25-10-2008 12:16:23)
Hors ligne
j'ai télécharger waterterrain.rar et je pense que je serait en mesure de l transcrire en glsl. merci tmyke.
au fait si tu regarde bien le screenshot d'aranoth tu remarquera qu'il a le même problème que moi. c pe etre "dû" à opengl.
Toi ton test est sous directX, essai sous opengl pour voir.
Dernière modification par johnplayer (25-10-2008 12:33:10)
Hors ligne
Exact, je viens de tester, et effectivement sous OpenGL tous les mesh sont coupés en deux. Bug connu ou non ?
je vais voir sur le forum off.
Hors ligne
Ouf je ne suis pas fou ni aveugle, ca me rassure! C'est embetant parce que l'avantage d'opengl est d'être multi-plateforme et je vais peut etre devoir passer sous directX.
Hors ligne
Bon, j'ai rien trouvé sur le forum officiel de probant sur le sujet. Si j'ai le temps, avant la fin de la journée je posterais pour voir si quelqu'un a une explication sur
ce bug 'potentiel'.
johnplayer :
...C'est embêtant parce que l'avantage d'opengl est d'être multi-plateforme et je vais peut etre devoir passer sous directX.
Personnellement, pour plusieurs raison, j'ai fai le choix de DirectX. En effet, le fait de coder avec directX fait que l'on perd cet avantage du multiplateforme. Cela peut paraitre toujours embêtant.
Après tout dépends quels sont tes objectifs à terme.
Dernière modification par tmyke (25-10-2008 14:59:05)
Hors ligne
Mais attendez, où vous voyez un bug ?!
Le clipping plane marche nickel dans la capture d'écran que j'ai proposé
Je comprend pas ce qui vous gène, vous vous attendiez à quoi ?
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 14 invités en ligne Aucun membre connecté RSS Feed |