Reputation: 3197
I'm using Three.js to apply a displacement map to a simple plane. The displacement applies successfully, but the lighting is wrong, as if all the normals remain unchanged. The result is a surface with the right shape that's lit as if it were flat.
displacement map:
result:
How can I fix this to properly change the lighting?
Here is the relevant bit of code:
// shortened from actual code - please excuse any small typos
var renderer = new THREE.WebGLRenderer();
renderer.setSize(500, 250);
var scene = new THREE.Scene();
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(100, 100, 100);
var ambient = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(light);
scene.add(ambient);
var camera = new THREE.PerspectiveCamera(60, 2, 1, 20000);
var geometry = new THREE.PlaneBufferGeometry(100, 100, 1000, 1000);
geometry.rotateX(-Math.PI / 2);
var material = new THREE.MeshPhongMaterial();
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('circlemap.png');
material.displacementScale = 20;
material.displacementMap = texture;
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// ... later
renderer.render(scene, camera)
edit: when I set flatShading: true
in the material, the normals are updated correctly, but look bad (because of the flat shading):
Upvotes: 3
Views: 839
Reputation: 28462
You're going to have to pass a normalMap
along with your displacementMap
.
See this demo, when normalScale = 0
it's the equivalent of having no normalMap, and you can see that the reflections don't follow the displacement, only the default topography. However, when normalMap is 1, then the reflections do respect the displacement.
You need to generate a normalMap.
Upvotes: 4