Question

Résumé

J'essaie d'appliquer une carte de déplacement (carte de hauteur) à un objet plutôt simple (plan hexagonal) et j'obtiens des résultats inattendus.J'utilise des niveaux de gris et, en tant que tel, j'avais l'impression que ma carte de hauteur ne devrait affecter que les valeurs Z de mon maillage.Cependant, la carte de déplacement que j'ai créée étend le maillage sur les plans X et Y.De plus, il ne semble pas utiliser le mappage UV que j'ai créé et auquel toutes les autres textures sont appliquées avec succès.

Modèle et carte UV

Voici des images de référence de mon maillage hexagonal et de sa carte UV correspondante dans Blender.

Hexagonal Model and UV Map

Textures diffuses et de déplacement

Ce sont les textures de carte diffuse et de déplacement que j'applique à mon maillage via Three.JS.

Hexagonal Diffuse and Displacement Textures

Rendus

Lorsque je restitue le plan sans carte de déplacement, vous pouvez voir que le plan hexagonal reste à l'intérieur des lignes.Cependant, lorsque j'ajoute la carte de déplacement, cela affecte clairement les positions X et Y des sommets plutôt que d'affecter uniquement le Z, élargissant ainsi le plan sur les lignes.

Hexagonal Plane Renders -- With & Without Displacement Map

Code

Voici le code Three.js pertinent :

    // Textures
    var diffuseTexture = THREE.ImageUtils.loadTexture('diffuse.png', null, loaded);
    var displacementTexture = THREE.ImageUtils.loadTexture('displacement.png', null, loaded);

    // Terrain Uniform
    var terrainShader = THREE.ShaderTerrain["terrain"];
    var uniformsTerrain = THREE.UniformsUtils.clone(terrainShader.uniforms);

  //uniformsTerrain["tNormal"].value = null;
  //uniformsTerrain["uNormalScale"].value = 1;

    uniformsTerrain["tDisplacement"].value = displacementTexture;
    uniformsTerrain["uDisplacementScale"].value = 1;

    uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture;
  //uniformsTerrain[ "tDetail" ].value = null;
    uniformsTerrain[ "enableDiffuse1" ].value = true;
  //uniformsTerrain[ "enableDiffuse2" ].value = true;
  //uniformsTerrain[ "enableSpecular" ].value = true;

  //uniformsTerrain[ "uDiffuseColor" ].value.setHex(0xcccccc);
  //uniformsTerrain[ "uSpecularColor" ].value.setHex(0xff0000);
  //uniformsTerrain[ "uAmbientColor" ].value.setHex(0x0000cc);

  //uniformsTerrain[ "uShininess" ].value = 3;
  //uniformsTerrain[ "uRepeatOverlay" ].value.set(6, 6);

    // Terrain Material
    var material = new THREE.ShaderMaterial({
        uniforms:uniformsTerrain,
        vertexShader:terrainShader.vertexShader,
        fragmentShader:terrainShader.fragmentShader,
        lights:true,
        fog:true
    });

    // Load Tile
    var loader = new THREE.JSONLoader();
    loader.load('models/hextile.js', function(g) {
      //g.computeFaceNormals();
      //g.computeVertexNormals();
        g.computeTangents();
        g.materials[0] = material;

        tile = new THREE.Mesh(g, new THREE.MeshFaceMaterial());
        scene.add(tile);
    });

Hypothèse

Je jongle actuellement avec trois possibilités pour expliquer pourquoi cela pourrait mal se passer :

  1. La carte UV ne s'applique pas à ma carte de déplacement.
  2. J'ai mal créé la carte de déplacement.
  3. J'ai raté une étape cruciale dans le processus qui verrouillerait le déplacement sur Z uniquement.

Et bien sûr, l'option secrète n°4 qui n'est rien de ce qui précède et je viens de vraiment je n'ai aucune idée de ce que je fais.Ou tout mélange de ce qui précède.

Exemple en direct

Vous pouvez voir un exemple en direct ici.

Si quelqu'un ayant plus de connaissances sur le sujet pouvait me guider, je lui en serais très reconnaissant !

Modifier 1:Conformément à la suggestion, j'ai commenté computeFaceNormals() et computeVertexNormals().Bien que cela ait apporté une légère amélioration, le maillage est toujours déformé.

Était-ce utile?

La solution

Dans votre matériel de terrain, définissez wireframe = true, et vous pourrez voir ce qui se passe.

Votre code et vos textures sont fondamentalement bonnes.Le problème se produit lorsque vous calculez les normales des sommets dans la fonction de rappel du chargeur.

Les normales de sommet calculées pour l’anneau extérieur de votre géométrie pointent quelque peu vers l’extérieur.C'est très probablement parce que dans computeVertexNormals() elles sont calculées en faisant la moyenne des normales de face de chaque face voisine, et les normales de face des "côtés" de votre modèle (la partie noire) sont moyennées dans le calcul des normales de sommet pour les sommets qui constituent l'anneau extérieur du "capuchon". ".

En conséquence, l'anneau extérieur du « capuchon » s'étend vers l'extérieur sous la carte de déplacement.

MODIFIER:Effectivement, directement à partir de votre modèle, les normales des sommets de l’anneau extérieur pointent vers l’extérieur.Les normales aux sommets des anneaux intérieurs sont toutes parallèles.Peut-être que Blender utilise la même logique pour générer des normales de sommets que computeVertexNormals() fait.

vertex normals

Autres conseils

Le problème est de savoir comment votre objet est construit car le déplacement se produit le long du vecteur normal.

le code est ici.

https://github.com/mrdoob/trois.js/blob/master/examples/js/ShaderTerrain.js#L348-350

"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",

Cela prend le vecteur RVB de la texture de déplacement.

"float df = uDisplacementScale * dv.x + uDisplacementBias;",

cela ne prend que la valeur rouge du vecteur car uDisplacementScale est normalement 1,0 et uDisplacementBias est 0,0.

"vec3 displacedPosition = normal * df + position;",

Cela déplace la position le long du vecteur normal.

donc pour résoudre, vous mettez à jour les normales ou le shader.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top