UV Offset Map?

Summary

I'm trying to apply an offset map (elevation map) to a fairly simple object (hexagonal plane), and I get unexpected results. I use shades of gray and as such, I was impressed that my height map should only affect the Z values โ€‹โ€‹of my grid. However, the displacement map that I created stretches the grid through the X and Y planes. Also, it looks like I did not use the UV mapping that was created for all the other textures.

Model and UV Card

Here are the reference images of my hexagonal grid and its corresponding UV map in Blender.

Hexagonal Model and UV Map

Diffuse and offset textures

These are the textures of the diffuse and offset maps, which I apply to my grid through Three.JS.

Hexagonal Diffuse and Displacement Textures

Visualizes

When I draw a plane without a displacement map, you can see that the hexagonal plane remains inside the lines. However, when I add a displacement map, it clearly affects the positions of the X and Y vertices, and does not affect only Z, expanding the plane well along the lines.

Hexagonal Plane Renders - With & Without Displacement Map

code

Here is the corresponding .ru code:

// 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); }); 

Hypotheses

I am currently juggling in three ways why this might go wrong:

  • The UV map does not apply to my displacement map.
  • I did the wrong displacement map.
  • I missed an important step in this process that would only block the offset Z.

And, of course, the secret option number 4, which is none of the above, and I just really don't know what I'm doing. Or any mixture of the above.

Living example

You can view a live example here .

If anyone with more knowledge on this subject can guide me, I would be very grateful!

Change 1 . As suggested, I commented on computeFaceNormals() and computeVertexNormals() . Although this made a slight improvement, the mesh is still deformed.

+4
source share
2 answers

In the material of your landscape, set wireframe = true , and you can see what happens.

Your code and textures are mostly beautiful. The problem arises when calculating vertex normals in the loader callback function.

The calculated vertex normals for the outer ring of your geometry point somewhat outward. This is most likely because in computeVertexNormals() they are calculated by averaging the face normals of each neighboring face, and the face normals of the "sides" of your model (black part) are averaged over the normal vertex calculation for those vertices that make up the outer cap ring.

As a result, the outer ring of the โ€œcapโ€ expands outward with the displacement map.

EDIT: Of course, right from your model, the vertex normals of the outer ring point outward. The vertical normals for the inner rings are all parallel. Perhaps Blender uses the same logic to generate vertex normals, as computeVertexNormals() does.

vertex normals

+4
source

The problem is how your object is created, because the displacement occurs along the normal vector.

the code is here.

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

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

This takes the rgb vector of the offset texture.

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

this takes only the red value of the vector, because uDisplacementScale is usually 1.0 and uDisplacementBias is 0.0.

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

This shifts the position along the normal vector.

so you can either update the normals or shaders.

+1
source

Source: https://habr.com/ru/post/1437663/


All Articles