How to Fix Broken Shadows After Using a Vertex Shader
Displacing vertices with a GLSL vertex shader can make for fantastic results but it's very easy to leave out a crucial step to ensure shadows remain correct.
If you forget to define a custom depth and distance material on a mesh after applying a vertex shader its shadow won't look correct.
Tools needed for the fix
- The same GLSL vertex shader used previously
- The THREE-CustomShaderMaterial library for Three.js which heavily reduces boilerplate code
- Custom depth and distance materials
Applying the missing materials
Depth and distance materials are used to create shadow maps for spot lights and point lights respectively. The fix is a matter of adding custom ones to the mesh using the same vertex shader used previously.
<mesh position={[0, 0.2, 3]} castShadow receiveShadow>
<sphereGeometry args={[0.75, 100, 100]} />
<CustomShaderMaterial
baseMaterial={MeshStandardMaterial}
vertexShader={vertexShader}
color="red"
/>
+ <CustomShaderMaterial
+ attach="customDistanceMaterial"
+ baseMaterial={MeshDistanceMaterial}
+ vertexShader={vertexShader}
+ />
+ <CustomShaderMaterial
+ attach="customDepthMaterial"
+ baseMaterial={MeshDepthMaterial}
+ vertexShader={vertexShader}
+ />
</mesh>
The shadow looks like a tear drop just like the mesh.