0

In three.js I load a displacement map like this

// ADD MAP
const loader = new THREE.TextureLoader();
const height = loader.load(GAME_CONTEXT.height_map_link);
const texture = loader.load(GAME_CONTEXT.texture_map_link);
const normal = loader.load(GAME_CONTEXT.normal_map_link);
const map_geometry = new THREE.PlaneBufferGeometry(GAME_CONTEXT.width, GAME_CONTEXT.height, 64, 64);
const map_material = new THREE.MeshStandardMaterial({
    color:'orange',
    //side: THREE.DoubleSide,
    map:texture,
    displacementMap: height,
    displacementScale: GAME_CONTEXT.scale,
    normalMap : normal
    //alphaMap: alpha,
    //transparent:true
});
const map_plane = new THREE.Mesh(map_geometry, map_material);
map_plane.position.x += GAME_CONTEXT.width/2;
map_plane.position.y += GAME_CONTEXT.height/2;
scene.add( map_plane );

map_geometry.computeVertexNormals();
map_geometry.computeTangents();
var normals = map_geometry.attributes.normal.array;
for(var i1 = 0, l1 = normals.length; i1 < l1; i1 += 3){
    var n = new THREE.Vector3(normals[i1], normals[i1+1], normals[i1+2]);
    console.log(n);
}

The map loads, but I am now trying to get the normals at each position on the map. Or simply calculate it at any abstract (x,y) position. I am looking through the normals, but they are all (0,0,1). How can I get the actual normals?

omega
  • 40,311
  • 81
  • 251
  • 474
  • The answer is: you can't. A `displacementMap` moves the vertices via shader, but the Javascript geometry data remains untouched. So when you try to compute the normals via JS, the geometry doesn't know about the displacement that takes place in the GPU. You would have to draw your displacementMap onto a ``, then read the color data (from `[0, 255]`) to change the vertex height of the `PlaneGeometry`. Similar to the approach [in this post](https://discourse.threejs.org/t/calculating-normals-from-heightmap-in-vertex-shader/13014). – M - Jan 22 '22 at 06:26
  • 2
    This issue has already been discussed 2 days ago in this duplicate post: [How to get vector perpendicular to the displacement map plane in three.js?](https://stackoverflow.com/questions/70779366/how-to-get-vector-perpendicular-to-the-displacement-map-plane-in-three-js) – M - Jan 22 '22 at 06:26
  • That doesn't make sense, the map is actually drawing with dark shadows where light doesn't touch. Normals would need to be calculated for that to happen. – omega Jan 22 '22 at 06:44
  • Yes, there are 2 ways of changing the shape of objects. 1: By modifying the vertex positions via JavaScript in the `geometry` object, or 2: By modifying the vertex shader in the GPU during render. `DisplacementMap` uses method 2. The demo you're seeing modifies the vertex in the shader, and also calculates normals in the shader, that's how it has shadows. But if you want to have the normal data in JavaScript side, so you can view it via `console.log(normal)`, then you'll need to take approach 1, and manually update the vertex positions. – M - Jan 22 '22 at 08:21
  • _"the map is actually drawing with dark shadows"_, as you use `normalMap` in the material. – prisoner849 Jan 22 '22 at 12:53

0 Answers0