Broken self-shadows for NodeMaterial

Hey! In my TSL learning i stumbled on a weird behaviour, could i be missing something?
So, i distort object with vertex shader, and i want it to cast-receive shadows.
I made two examples:

  1. with WebGPU and TSL, + YELLOW object distorted by geometry on CPU
    https://webgpushadows.netlify.app
  2. With WebGL and onbeforecompile, + RED mesh distorted on CPU
    https://webglshadows.netlify.app
    All the lighting-distortion-size - similar.
    Both full codes are here WebGL vs WebGPU self shadows · GitHub

Yet note how only self-shadow on Node material is different out of those 4 cases.
Animated GIF Maker

What could i have done wrong to get this? Or could it be a bug?
I might have done a stupid mistake somewhere. Help appreciated!

This is the most important bit, on how i do distortion with Nodes:

// NODES DISTORTION
    let mat = new THREE.MeshPhysicalNodeMaterial({
      side: THREE.DoubleSide,
      color: 0xffffff,
    })
    mat.positionNode = Fn( ()=>{
      const position = positionLocal.xyz.toVar();
      const elevation = sin( positionWorld.x.mul(10)).mul(0.2);
      position.y.addAssign( elevation );
      return position;
    } )();
    this.geometry = new THREE.PlaneGeometry(5,1, 300,30).rotateX(-Math.PI / 2);

    this.sine = new THREE.Mesh(this.geometry, mat);
    this.sine.receiveShadow = true;
    this.sine.castShadow = true;

When switching from WebGL to WebGPU and NodeMaterials, I found that I had to make changes to shadow.bias. Perhaps that is what is happening.

The values that seemed to work best for me ranged from -0.00001 to -0.0005. Check the WebGPU shadow examples.

1 Like

Tried all the values, unfortunately no change =( They just seem to have different shape or projection angle.

And also we would expect it to be the same(broken) as in CPU version of distortion then, on yellow mesh? If it was just bias.

WebGPU is under development, so there is always the chance that you will find some lingering bug.

While this may not be part of your question, you are experiencing a problem that I had with r170 WebGPU (w/ NodeMaterials). If you look at the overall gray area you on that example will notice that the corners appear to be a lighter gray. I think you will find that these mark the boundary of your shadowbox and that WebGPU is creating a darker rectangle and a moire effect. I have always had to use a different shadow.bias for WebGPU. But the only way I could get rid of the moire effect and the dark area was to further change my shadow.bias from -0.00001 to -0.0005.

I was hoping that this change would get rid of your problem as well.

For what it is worth, in my case, the shadow was cast on a regular Material - part of a glb import.

This shouldn’t make a difference, but does removing cast.shadow from the floor change things? My glb import was also set to cast a shadow.

1 Like

Yes, you are correct! changing bias fixes that particular issue with floor.
And its also helpful to know that we might want to use different bias in different renderers. kind of expected same results with same values, thought i broke something else =)

But that being said, it still doesnt change the difference in shapes of self-shadows =(

@sunag helped me to figure out my problem, all credits and HUGE THANKS goes to him!
so, it was my mistake: using positionWorld inside positionNode.
This Node actually sets this variable, and im kind of using it inside already.
Corrected code would look like this:

 mat.positionNode = Fn( ()=>{
      const position = positionLocal.xyz.toVar();
      // calculate World Position here
      **const positionW =  modelWorldMatrix.mul( positionLocal ).xyz;**
// rest is the same
      const elevation = sin( positionW.x.mul(10)).mul(0.2);
      position.y.addAssign( elevation );
      return position;
    } )();
6 Likes

Yep, that did it.

I had converted your example to my programming style and was playing around with it. I was thinking that the normals were off and was digging into some three.js examples for guidance. I’m sure I never would have thought of the modelWorldMatrix. (I am still learning about all these matrices.) So be sure to give sunag credit for answering your question!

1 Like