Why don't I see any gradient shadowing on the PlaneGeomentry with a displacementMap

Hi!
This is my floor

const floor = new THREE.Mesh(
    new THREE.PlaneGeometry(200, 200, 100, 100),
    new THREE.MeshStandardMaterial({
        color: 'aqua',
        displacementMap: new TextureLoader().load('/height-map-landscape.jpeg'),
        displacementScale: 10,
    })
)
floor.receiveShadow = true
floor.castShadow = true
floor.rotation.x = - Math.PI * 0.5
scene.add(floor)

I also have a point and ambient light.
My scene looks like this…


How can I see a more realistic render? I’m not talking about the burger shadow on the plane, but just the plane to be generated with some gradient.

Thanks

Which version of three.js are you using? There has been some changes regarding this topic with r132, see WebGLShadowMaps: Add support for rendering shadows with displacement maps by gkjohnson · Pull Request #22287 · mrdoob/three.js · GitHub.

The PR enables objects with a displacement map to correctly cast shadows without using a custom depth/distance material. I’m not sure if objects correctly receive shadow if vertices are displaced with a respective map.

I use 0.130.0

Then please try it with r132.

Will do, thanks! But again I saw the PR, I’m not looking to display burger shadow on the plane with displacement but just to see the plane itself in the way I can understand what’s going on with some gradient. I hope I’m explaining it well.

P.S upgraded. Looks the same

One thing to check here, if you remove the ambient light what result do you get? It’s a large scene, perhaps the point light needs to be more intense, or a higher distance cutoff… Ambient lights have no distance limit.

2 Likes

Here I’ve added some texture, so it’s easy to understand the landscape but still no shadows.
I set the ambient light on 0.1

ambientLight doesn’t cast shadows or cause shading since it casts the same colour in all directions. it ignores position.

comment out your ambientLight code and try a different type of light,
e.g, a point light

const light = new THREE.PointLight()
light.position.set(10, 10, 10)  //position it somewhere
scene.add(light)
1 Like

I have the point light on the scene as well. :confused:

One solution is to add a normal map to your material.

I also found it looked better if I used a meshPhongMaterial rather than a meshStandardMaterial

On my example, slide the GUI → Light → position.x

https://sbcode.net/extra_html/displacement_and_normal_maps.html

There are other options, i’m sure.

Source code is there under the <> button in the example.
It uses Three r132

1 Like

Here is another example.
It uses shadow with MeshStandardMaterial and Three r132.
No normalMap used in this example.
The plane is both casting and receiving shadow so you will need to manage the lights shadow.bias.
This is new in r132 and it looks really good. :slight_smile:
Also, I am using a directionalLight

https://sbcode.net/extra_html/displacement_and_shadow.html

4 Likes

Thank you for this example! So If I understand correctly, the displacement doesn’t work well with shadows , the workaround is to have a normal map that has the shadow pattern so the scene will look more realistic.

the displacement map works fine with shadows by default since Three r132. I.e.,you don’t need to create a specific THREE.ShadowMaterial anymore.
The displacement map is more about changing vertices than changing the normals that are used when calculating lighting effects. Bumpmap and Normalmap are good for that.
However, you can avoid a displacement map by displacing your geometry in blender and exporting it as obj or gltf. That way it should contain normals already and gradient shading will work if you use a light and material that supports it. eg, pointLight with meshStandardMaterial.