ShaderMaterial, vertex shader and shadows

So I have a mesh using a custom vertex shader (with some basic noise animation), but the shadow is basically frozen in time and does not react to what happens in the vertex shader. How can I get my shadow to update properly? Is it even possible or do I have to reimplement all shadow handling manually for my ShaderMaterial mesh?

Hi!
Depends on the type of light source, you need to use .customDepthMaterial or .customDistanceMaterial of your mesh, where you have to repeat the same code in vertex shader, that you used in material’s vertex shader.

1 Like

Thanks for the feedback!

So I’m using a directional light, and I saw that I should add a MeshDepthMaterial to my mesh, but I cannot find any documentation mentioning anything about shaders, how that fits in with mesh.customDepthMaterial, or even what the different parts expect. Adding a simple new MeshDepthMaterial() did not make any difference.

What exactly does the customDepthMaterial expect? Can I simply copy/paste my shader code from my actual ShaderMaterial?

Here is an example with .customDepthMaterial: Mesh points to the camera on only 2 axis with shaders - #10 by prisoner849

So I managed to figured it out, leaving my (jsx) solution here for posterity. Solved it by pulling out the vertex transform as a reusable function (grassTransform) and reusing that in the customDepthMaterial by assign the transformed vec3 to the transformed variable.

<mesh
    geometry={grass?.geometry}
    position={[0, 0, 0]}
    castShadow
    receiveShadow
>
    <meshDepthMaterial
        attach="customDepthMaterial"
        args={[{
            depthPacking: RGBADepthPacking,
            alphaTest: .5,
            onBeforeCompile(shader) {
                const chunk = `
                   #include <begin_vertex> 

                    transformed = grassTransform(position);
                ` 

                shader.uniforms = {
                    ...shader.uniforms,
                    ...uniforms
                }

                shader.vertexShader = ` 
                    uniform float time;
                    uniform float height;
                    uniform float cutHeight;
                    uniform sampler2D cut;
                    uniform sampler2D playerPosition;
                    uniform sampler2D gap; 
                    
                    ${grassTransform}
                    ${shader.vertexShader}
                `.replace("#include <begin_vertex>", chunk)
            },
        }]}
    />
    <shaderMaterial
        attach="material"
        side={DoubleSide}
        transparent
        args={[{
            vertexShader,
            fragmentShader,
            uniforms,
        }]}
    />
</mesh>
1 Like

I have the same problem here :smiling_face_with_tear:

Are you using 2 material in one mesh?

Not many customDepthMaterial examples can be found :sweat_smile:

Are you passing shaderMaterial data to meshDepthMaterial?

Thank you! I was wondering why PointLight shadows were not working. For the record, PointLight shadows need a customDistanceMaterial and SpotLight shadows need a customDepthMaterial.

1 Like