Bonsoir,
Je viens à vous pour un problème mainte fois soulevé dans les forums sous des formes diverses mais auquel je ne trouve pas la solution qui me satisfait pleinement.
Le problème est le suivant: je veux faire pousser de l'herbe à la surface d'un SceneNode (en l’occurrence un hexagone créé comme customSceneNode).
Deux solutions sont pour l'instant envisageables:
* Créer un shader qui mélange deux textures (celle du sol et une d'herbe avec des zones de transparence)
* Utiliser un système de particule (apparemment comme le GrassSceneNode existant.
Dans le premier cas, j'ai consulté pas mal de tutoriels et la question à l'aire vraiment complexe. C'est tout un nouvel outils (voir langage) à apprendre pour un petit problème. Je sais qu'il est possible de faire de même en créant une image à partir des deux précédentes mais je ne sais pas si cette solution (sorte de shader CPU) est vraiment bonne.
Dans le second, j'ai juste un problème: est-il possible de créer des particules fixes et de durée de vie infinie (en gros sans émetteur). Je ne compte pas utiliser le grassSceneNode qui me parraît un peu gros pour mon projet.
Qu'en pensez vous? Y aurait-il une tierce solution à laquelle je n'aurai pas pensé?
Merci d'avance
Hors ligne
Serait-il possible de faire une image pour explication parce que j'ai vraiment compris ton problème.
Tu veux créer de l'herbe en 3D ou juste modifier la texture du sol pour qu'elle passe de de la "couleur terre" à la "couleur herbe", si c'est ce dernier cas avec les shaders c'est simple.
Tu prends 3 textures : 1 pour le sol originel, 1 pour l'herbe et la 3ème indiquant la texture à prendre en compte. Les shaders ne sont pas compliqués pour des rendus de base.
Il te suffit de mettre les 3 textures dans le matériau de ton node, de les récupérer dans ton shader (j'avais fait un topic sur les shaders qui montrer un exemple). Ensuite, tu teste le texel sur la 3ème texture et tu en déduis le texel de quelle texture (entre la 1 et la 2) affichée. Ton shader devrait faire 25 lignes à tout casser (PS et VS).
Je pense que les particules serait trop gourmandes en ressources, enfin, tout dépends tes attentes. Mais saches qu'une particule c'est 2 triangles sur 1 node et Irrlicht est fait pour afficher peu de node avec beaucoup de triangles. Si tu veux faire de l'herbe en 3D, il serait mieux de faire ton propre SceneNode (dérivé de ISceneNode). Tu peux ainsi accéder au buffer et créer des triangles et les texturer afin de faire pousser de l'herbe. Pour la gestion, tu peux faire un truc simple, genre tu créés une structure pour une touffe d'herbe par exemple :
Ensuite, afin de gérer tes touffes d'herbe, tu créés un array<TouffeHerbe> ce qui te permet de créer, supprimer ou modifier la taille de ton herbe. Après ce n'est qu'un principe de base, il te faudra l'accorder à ta vision des choses.
Edit : Si tu choisis la solution du ISceneNode, il serait bien de créer un nouveau topic dans la section "Meshs" (afin de respecter le système de section que le webmaster à mis en place) et de mettre le lien vers ce nouveau topic dans celui-ci (afin de faire le lien entre les 2 discussions).
Dernière modification par johnplayer (22-09-2012 21:32:36)
Hors ligne
Merci pour cette réponse et cette dernière solution. Je vais creuser cette piste.
Hors ligne
Bon, le problème est résolu: je crée un deuxième hexagone 0.01 unité au dessus du premier que je texture avec mon herbe semi transparente. le résultat est convenable. Merci pour votre aide.
A l'occasion, je publierai des images, ce sera plus parlant.
Hors ligne
je comprend pas pourquoi ne pas appliquer ta texture d'herbe comme seconde texture sur l'hexagone existant dans ce cas ? tu gagnerais en performance...
Hors ligne
Parceque Irrlicht ne gère pas la transparence dans ce cas: ma texture de base est pleine mais celle de l'herbe présente des trous (fonctions de la densité d'herbe) qui sont des points de transparence Alpha dans la texture de l'herbe.
J'ai eu beau essayer tous les video::EMT_..., je n'ai pas réussi à voir celle de dessous à travers
J'ai lu dans les forums que cela n'était pas possible avec Irrlicht sans passer par les shaders.
A moins que je n'ai loupé quelque chose... (?)
Hors ligne
Dans ce cas, si tu ne veux vraiment pas utiliser les shaders, il y a une méthode.
Comme ça tu ne touches pas au shaders mais tu gardes des performances, à conditions de ne pas modifier sans arrêt ta texture bien sûr.
Hors ligne
J'avais vu cette technique sur un forum, ça revenait un peu à faire du shader avec le CPU comme disais un intervenant. Mon problème en l’occurrence est que cette texture de végétation est remise à jour régulièrement.
En tout cas merci pour vos interventions instructives
Hors ligne
Salut,
j'arrive après la bataille comme d'hab, mais post un screen de ce que tu veux faire, et je pourrais ptêtre t'aider pour un vrai shader qui sera nettement plus optimisé à mon avis
Hors ligne
je voie pas ou ça pose probleme ?
pour rester simple dans le cas ou tu veut que l'alpha soit primaire t'utilise ta texture d'herbe sur le layer 0
la second texture va ce blitter en fonction de l'apha de la premier
sinon au mieux tu passe par irr::video::pack_texureBlendFunc
tout du moin si j'ai bien comprit ce que tout souhaitais, nehanmoin il est clair qu'un screen explicite serais le bien venue
Hors ligne
Oui ça c'est vrai j'avais aussi demandé une illustration dans mon premier post. Parce que l'on ne sait pas exactement quel rendu tu attends pour ton herbe.
Hors ligne
Bonsoir à tous,
Je suis désolé de ne pas donner suite à cette discussion pour l'instant, mais, venant de reprendre le boulot, je vais devoir laisser quelques temps le projet de côté. J'espère pouvoir rapidement reprendre le fil de cette discussion et publier quelques screens. Cela dit, ne vous attendez pas à un grand projet, il ne s'agit que de quelques bidouillages perso pour le plaisir.
Merci encore à vous pour votre aide et à bientôt
Hors ligne
Bon, je profite d'avoir un peu de temps de retrouvé pour revenir sur ce problème.
Concernant l'illustration, j'ai commencé un petit blog pour me mettre à plat l'avancée du projet. Vous y trouverez quelques images.
http://memorial76-project-one.blogspot.fr/
En particulier, le point qui m'intéresse en ce moment:
En effet, la solution consistant à superposer deux scenesNodes, dont celui du dessus porte la texture de la végétation semi transparente, n'est pas idéale. Notamment pour retrouver le node de texture pour la changer au cours de l’exécution.
Question bonus: comment savoir à quoi va correspondre la coordonnée UV de mon vertex dans l'image de la texture. J'aurai pensé à première vue que ce serait en nombre de pixels mais il doit y avoir plusieurs facteurs d'échelle qui entrent en jeu à divers moment dans le processus de plaquage et je n'arrive pas à ajuster mes coordonnées UV à ma texture.
Hors ligne
Pourquoi ne pas prendre la méthode de texturing utilisée dans le tutorial sur l'eau (tuto officiel irrlicht), tu auras une sperposition des deux textures, ensuite tu n'as qu'à modifier l'opacité de ta texture d'herbe.
Pour les coordonnées de textures :
coordonnées de texture
x 0 1
y _________
0 | |
| image |
| |
1 |________|
Si tu veux un quad texturé exactement de la taille de la texture (chaque coin du quad correspondent à un coin de la texture), tu obtiens ces vertex :
v1(0.0f,0.0f)
v2(1.0f,0.0f)
v3(1.0f,1.0f)
v4(0.0f,1.0f)
ou plus généralement, avec k étant un entier relatif:
v1(k,k)
v2(k+1.0f,k)
v3(k+1.0f,k+1.0f)
v4(k,k+1.0f)
attention : Les sommets d'un triangle se dessinent dans le sens horaire pour une normale positive et dans le sens anti-horaire pour faire un "flip surface".
Si tu tu coupes (virtuellement) ta texture en 4 et que tu veux que ton quad soit texturé avec le quart inférieur gauche de ta texture, tu obtiens ces vertex :
v1(0.0f,0.5f)
v2(0.5f,0.5f)
v3(0.5f,1.0f)
v4(0.0f,1.0f)
En résumé, x et y sont des coordonnées sont comprises entre 0.0f et 1.0f mais les multiples sont possibles!
Si tu veux un quad texturé de manière à avoir un "tableau" de 2x2 texture, tu obtiens ces vertex :
v1(0.0f,0.0f)
v2(2.0f,0.0f)
v3(2.0f,2.0f)
v4(0.0f,2.0f)
Pour texturé tes hexagones correctement, il faut que ton hexagone soit inscrit dans le carré définit par ta texture, c'est-à-dire x0y0(0.0f,0.0f), x1y1(1.0f,1.0f).
Tu peux, par exemple, dessiné un carré (10x10cm) sur une feuille, ensuite tu traces ton hexagone de façon à ce que tout les sommets soit sur la périphérie du carré et tu mesures la position (x;y) de tes sommets. Tu n'as plus qu'à diviser par 100 tes résultats pour convertir tes coordonnées en coordonnées de textures.
Je n'ai pas vraiment le temps de faire des illustrations mais je pense que c'est compréhensible comme ça.
Dernière modification par johnplayer (06-10-2012 12:16:08)
Hors ligne
johnplayer :
Pourquoi ne pas prendre la méthode de texturing utilisée dans le tutorial sur l'eau (tuto officiel irrlicht), tu auras une sperposition des deux textures, ensuite tu n'as qu'à modifier l'opacité de ta texture d'herbe.
Je vais jeter un oeil la dessus mais il me semble avoir déjà essayé sans succès... à suivre
johnplayer :
Pour les coordonnées de textures :
coordonnées de texture
x 0 1
y _________
0 | |
| image |
| |
1 |________|
Si tu veux un quad texturé exactement de la taille de la texture (chaque coin du quad correspondent à un coin de la texture), tu obtiens ces vertex :
v1(0.0f,0.0f)
v2(1.0f,0.0f)
v3(1.0f,1.0f)
v4(0.0f,1.0f)
ou plus généralement, avec k étant un entier relatif:
v1(k,k)
v2(k+1.0f,k)
v3(k+1.0f,k+1.0f)
v4(k,k+1.0f)
attention : Les sommets d'un triangle se dessinent dans le sens horaire pour une normale positive et dans le sens anti-horaire pour faire un "flip surface".
Si tu tu coupes (virtuellement) ta texture en 4 et que tu veux que ton quad soit texturé avec le quart inférieur gauche de ta texture, tu obtiens ces vertex :
v1(0.0f,0.5f)
v2(0.5f,0.5f)
v3(0.5f,1.0f)
v4(0.0f,1.0f)
En résumé, x et y sont des coordonnées sont comprises entre 0.0f et 1.0f mais les multiples sont possibles!
Si tu veux un quad texturé de manière à avoir un "tableau" de 2x2 texture, tu obtiens ces vertex :
v1(0.0f,0.0f)
v2(2.0f,0.0f)
v3(2.0f,2.0f)
v4(0.0f,2.0f)
merci pour le tuto, je n'avais pas essayé avec des floats.
johnplayer :
Pour texturé tes hexagones correctement, il faut que ton hexagone soit inscrit dans le carré définit par ta texture, c'est-à-dire x0y0(0.0f,0.0f), x1y1(1.0f,1.0f).
Tu peux, par exemple, dessiné un carré (10x10cm) sur une feuille, ensuite tu traces ton hexagone de façon à ce que tout les sommets soit sur la périphérie du carré et tu mesures la position (x;y) de tes sommets. Tu n'as plus qu'à diviser par 100 tes résultats pour convertir tes coordonnées en coordonnées de textures.
Je n'ai pas vraiment le temps de faire des illustrations mais je pense que c'est compréhensible comme ça.
Pas de problèmes pour le calcul des UV de l'hexagone, je l'avais déjà fait: c'est très simple. D'ailleurs, je pense faire un poste sur mon blog au sujet de la construction de l'hexagone...
Plus qu'à ramener ça à 1 est ça devrait coller.
Merci pour ta réponse. Je teste ça de suite...
Hors ligne
Une fois les tests faits:
La mise à l'échelle correspond tout à fait à ce que je voulais, c'est parfait merci.
Pour la superposition des deux textures, le résultat ne correspond pas. Je voudrais qu'il fusionne mes deux textures en ne laissant voir de celle du dessous que ce qui est derrière un pixel transparent de celle du dessus. Et pour cela, il faut que je me plonge dans les shaders
Hors ligne
Le shader ne devrait pas être compliqué.
fichier "shader.vert"
uniform mat4 mWorldViewProj; void main(void) { gl_Position = mWorldViewProj * gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; }
fichier "shader.frag"
uniform sampler2D texture_sol; uniform sampler2D texture_herbe; uniform float alpha; // permet de modifier l'alpha de l'herbe pour chaque hexagone indépendamment void main (void) { vec4 col0 = texture2D(texture_sol, vec2(gl_TexCoord[0])); vec4 col1 = texture2D(texture_herbe, vec2(gl_TexCoord[0])); gl_FragColor = col0*(1-alpha) + col1*alpha; }
Je n'ai pas testé mais quelques retouches et tu auras ton shader. Il ne gère pas les lumières.
Pour le tuto, c'est ici : tuto
Penses à mettre la texture herbe avec l'ID 1 et à envoyer les shaders constantes dont il a besoin.
Hors ligne
Merci, j'ai déjà parcouru le tuto une paire de fois mais je n'ai pas encore eu le temps ni le courage de m'y plonger réellement. Je comprend bien les principes de base mais de là à coder...
Mais y'a bien un moment où il faudra se remonter les manches
Hors ligne
Chose promise, chose due, j'ai posté ce soir une petite explication (que j'espère compréhensible) sur la construction et le mapping de mes hexagones.
a se trouve ici
Hors ligne
Je voudrais juste poser une question. Pourquoi des hexagones? Des carrés sont plus faciles à agencer.
Hors ligne
le nombre de polygone pourrais être optimisé pour t'est hexagone !
tu pourrais passer de 6 polygone a 4 polygone ou 2 quad
mais bon a ce nivaux la c'est du détail
il n'y a pas beaucoup d'info sur le concept art s'il y a en n'a
étant donner que tu utilise un moteur 3d ne serait-il pas judicieux de matérialiser t'est hexagone en cylindre à 6 face ? qui te permettrais par la suite de matérialisé t-on terrain sur différent niveaux, ca serait sympas
le fait de découper ton terrain en N² node, en intéressant pour le coter simpliste de développement, toujours par un soucis de performance, tu seras vite limiter
tu devrait plutôt coder un terrain sur un seul mesh
d'après ce que tu souhaite faire si j'ai bien comprit tu a la possibilité de faire ton terrain optimisé pour le rendu et ton utilisation:
tu crée une classe qui inclue 6 vertex (de l'hexagone x,y), la boundingbox de ces vertices, un pointeur vers la second class
+une fonctions pour définir les coordonné de la texture que tu souhaite (tu veras après)
et crée une second class qui inclue un array de cette class représentant ton terrain de la taille que tu veut, le pointer vers ton irr::video::SMesh
+une fonctions qui crée/edit le SMesh buffer avec les vertices comprit dans chaque élément de l'array de la class précédante et leur indices respectifs
+une fonction de raycast qui parcour l'array de la class précédante et test dans un premier temps la boundingbox si le test est positif tu fait un double test sur deux plan (les quads du l'hexagonne) qui retourne l'élément de l'array 'toucher'
après il ne te suffi que d'appeler la fonction qui set la texture en fonctions de ça coordonée qui elle même avec appeler via le pointeur vers la second class la méthode qui mettra a jour le mesh.
tu peut optimiser le raycast en groupent les élément dans une boundingbox un peut plus grande qui permetrais ce viré un certain nombre de test
pourquoi je parle de texture en fonction de coordonné ? pour la simple raison qu'au lieux d'avoir x texture pour x node tu a au maximum 4 texture qui contiendrons d'autres texture sous forme d'array
Hors ligne
Le choix des hexagones est essentiellement un clin d’œil aux bon vieux wargames et surtout un petit exercice de géométrie pour moi. Et pour devancer la question, je n'utilise pas de terrain à base de heightmap car je préfère avoir des cases nettes et franches pour agencer mon terrain (textures, végétation, bâtiments etc...).
Edit: @Magun: Je n'ai pas bien compris tout ton poste...
Dernière modification par Memorial76 (07-10-2012 10:17:24)
Hors ligne
je n'est pas pu répondre plutot, je suis prit par mes études
en espérant que la traduction de mon poste précédant en code t'éclaireras dévantage sur mes propos !
Hors ligne
@Magun: merci pour ton intérêt. J'ai déjà ma classe Hexagone héritée de ISceneNode ainsi que ma classe "conteneur". Je ne rentre pas dans les détails ici, j'en parle un peu sur ce Blog dans lequel je reviendrai, sur demande, sur ces classes.
A PROPOS DES SHADERS:
J'ai pris mon courage à deux mains et j'ai attaqué le tutoriel Irrlicht correspondant. Je n'ai, pour l'instant, eu que le temps de faire ma classe héritée de IShaderConstantSetCallBack et de l'adapter à mon programme de test. Mais j'ai déjà une tonne de questions:
Que font CONCRÈTEMENT ces lignes?
et celles-ci
J'ai bien quelques loitains souvenirs de cours de maths sur les matrices mais j'aimerai bien connaître les tenants et les aboutissants de ces paramètres?
Merci d'avance.
Hors ligne
crée un scene node par hexagone n'est pas une bonne méthode et tu auras de gros problèmes de performances sur des maps un petit peut conséquante
car cella induit a de nombreuse modifications de matrice et de matériaux
un hexagone ne reprèsente casiment rien en terme de performance, le faite que tu les rende séparément deviendras un problème
au lieux d'avoire 750fps sur une map tu peut te retrouver a 3fps ne seraice qu'avec 1M de node, a toi de voire
pour ce qui est des matrices dans le premier cas sa définie la matrice de l'object que tu renderas après la transformations, en gros sa bouge l'obj en fonctions de la camera (qui est virtuelle en ogl)
dans le second cas <<transposing a matrix is the act of turning it on its side- swapping the columns and rows.>> ça doit faire un flip du world je pensse (surment utiliser pour une refractions ??)
mais normalement pour le rendue tu n'utilise que << driver>setTransform(video::ETS_WORLD, AbsoluteTransformation); >>
Hors ligne