My goal is to enhance the precision of the displacement map by using an rgba texture to display displacement values with 32 bits accuracy instead of the default 8 bits in three.js. I am working on visualizing a flooding scenario and need to observe minute differences in terrain height.
After making adjustments to the displacement map shader function in the Three.js package, particularly in the file_three.js-master\src\renderers\shaders\ShaderChunk\displacementmap_vertex.glsl, I modified the code as follows:
transformed += normalize( objectNormal ) * ((texture2D( displacementMap, uv ).r*256.0*256.0*256.0)+(texture2D( displacementMap, uv ).g*256.0*256.0)+(texture2D( displacementMap, uv ).b*256.0)+(texture2D( displacementMap, uv ).a)) * displacementScale + displacementBias;
However, the result appears distorted when compared to the 8-bit displacement map. The 8-bit version shows smooth transitions, while the 32-bit map creates unexpected bumps and holes. It seems like some information from the 32-bit height data has been lost or altered. How can I encode displacement across all four channels rather than just red?
The input textures for my displacement map are:
1. PNG with height encoded in the red channel: https://i.sstatic.net/cP2Ff.png
2. PNG with height encoded in all four channels: https://i.sstatic.net/fwPNN.png
The segment of code where I create the mesh with a displacement map looks like this:
displacementMap0 = textureLoader.load(list_depth_images[0], function(mt0) {
displacementMap0.wrapS = displacementMap0.wrapT = THREE.ClampToEdgeWrapping;
addPlanes();
});
function addPlanes() {
// MeshPhongMaterial properties
material = new THREE.MeshPhongMaterial({
color: 0x88ffaa,
normalMap: normalMap,
normalScale: new THREE.Vector2(1, 1),
aoMap: aoMap,
aoMapIntensity: 0.5,
specularMap: specularMap,
specular: 0x222222,
displacementMap: displacementMap0,
displacementScale: ((settings.displacementScale) * overall_scale) / (256.0*256.0*256.0),
displacementBias: 0.0,
side: THREE.DoubleSide
});
var planeGeo = new THREE.PlaneBufferGeometry(2000*2*overall_scale, 2000*2*overall_scale, 1000, 1000);
THREE.BufferGeometryUtils.computeTangents(planeGeo);
plane = new THREE.Mesh(planeGeo, material);
plane.rotation.x = -Math.PI / 2;
plane.position.y = -400.0 * overall_scale;
scene.add(plane);
}
I have provided a downloadable zip file containing a functioning example of both the 8-bit and faulty 32-bit displacement maps: downloadable .zip