question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Since r132, I can't replicate MeshPhongMaterial’s new displacementMap-based self-shadowing using ShaderMaterial (with ShaderLib.phong)

See original GitHub issue

Describe the bug

Since r132, it seems to be possible to have self-shadowing in geometry that has a displacementMap applied (see DisplacementMap with Shadow - Three.js Tutorials 1).

Using MeshPhongMaterial in r132, I get the following (correct) result: the shadow casts from the grid structures – please ignore the block structures in the front): Bildschirmfoto 2021-11-23 um 21 27 19

Up to r131, I had a custom depth material that enabled the same functionality (customized to an RGBA elevation texture that I’m decoding in the shader – which is why I can’t work with out-of-the-box MeshPhongMaterial), which now stopped working since r132. In one of many attempts to fix this, I tried to get a custom ShaderMaterial up and running, based on ShaderLib.phong. While the displacement mapping happens (displaced geometry can be seen in the following screenshot’s grid lines), there is no shadowing: Bildschirmfoto 2021-11-23 um 21 26 37

Up to now, I tried out various defines, I’m setting the textures at “material level”, etc. – but I can’t get self-shadowing to work. It seems that there’s some define missing or some other flag off. I feel like I’m almost there but I’m not.

To Reproduce

In Three.js >= 132, create a ShaderMaterial with ShaderLib.phong. Set a displacementMap. While the mesh geometry gets distorted accordingly, there is no self-shadowing.

Code

this.mesh.receiveShadow = true;
this.mesh.castShadow = true;

const terrainMaterial = new THREE.ShaderMaterial(THREE.ShaderLib.phong);
//I maxed out on defines in an attempt to get this to work:
terrainMaterial.defines = {
    USE_UV: "",
    USE_MAP: "",
    USE_BUMPMAP: "",
    USE_DISPLACEMENTMAP: "",
    VERTEX_TEXTURES: "",
};
terrainMaterial.lights = true;
terrainMaterial.fog = true;
terrainMaterial.extensions.derivatives = true;
terrainMaterial.extensions.fragDepth = true;

terrainMaterial.map = TerrainTile.TextureLoader.load("img/grid512.png");
terrainMaterial.uniforms.map.value = TerrainTile.TextureLoader.load("img/grid512.png");
terrainMaterial.displacementMap = TerrainTile.TextureLoader.load("img/grid512.png");
terrainMaterial.uniforms.displacementMap.value = TerrainTile.TextureLoader.load("img/grid512.png");

this.mesh.material = terrainMaterial;
this.mesh.material.needsUpdate = true;

Expected behavior

As self-shadowing got integrated into displacement mapped materials in r132, this should work with ShaderMaterial as well.

Platform:

  • Device: Desktop, Mobile
  • OS: MacOS
  • Browser: Chrome, Firefox, Safari
  • Three.js version: since r132

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7

github_iconTop GitHub Comments

4reactions
Mugen87commented, Nov 26, 2021

The renderer works with both material properties and uniform values.

I’m not sure but I don’t think the approach of the fiddle is the recommended way of the project to enhance built-in materials. IMO, the OP should use onBeforeCompile() instead.

Thankfully, this will become more clean with a node material…

2reactions
molzercommented, Nov 25, 2021

Thank you @Mugen87 for the general advice and making this work! 🙏

To my defense 😅, it started as a help request (https://discourse.threejs.org/t/cannot-replicate-meshphongmaterials-new-displacementmap-based-self-shadowing-using-custom-shadermaterial-with-shaderlib-phong/32027) and the boss asked me to create an issue here.

I want to emphasize that the change that made the difference was to set all displacement properties – beside the displacementMap – explicitly (i.e., my laymen intuition was, that that’s not required since these are default values – but they are required to toggle defines, I assume?):

customShaderMaterial.displacementScale = 1;
customShaderMaterial.uniforms.displacementScale.value = 1;
customShaderMaterial.displacementBias = 0;
customShaderMaterial.uniforms.displacementBias.value = 0

Anyways, hallelujah!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot replicate MeshPhongMaterial's new displacementMap ...
Since r132, it seems to be possible to have self-shadowing in geometry that has a displacementMap applied (see DisplacementMap with Shadow - Three.js...
Read more >
three.js - What is the difference between MeshPhongMaterial ...
I have a piece of code which uses MeshPhongMaterial and how do i convert to ShaderMaterial with THREE.ShaderLib.phong.
Read more >
Extending the Built-in Phong Material Shader in Three.js
When working on a recent Three.js project, I wanted to extend one of the standard, built-in shaders like the MeshPhongMaterial shader.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found