Shadow for instances

I have instanced an object, but somehow the instances do not receive or cast any shadow.

I have created a simplified demo here: https://codepen.io/fedorvaneldijk/pen/eaoKbJ

How do I get shadows here?

Have you read this? https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow

…a thousand times, but in this demo I did forget to enable shadowmap in the renderer - so thanks.

But after correcting that omission, I still have no shadows for the instance. I think I see one single shadow of the original cube.

The vertex shader of the depth material has to be patched with the instancing code.

1 Like

I’ve found that using material.onBeforeCompile and utilizing Mesh.customerDepthMaterial in a certain way is the solution. Works great for me. Works with alpha as well.

Something like:

mesh.customDepthMaterial = new THREE.MeshDepthMaterial( {

	depthPacking: THREE.RGBADepthPacking,
	map: mesh.material.map,
	alphaTest: 0.5

} );

mesh.customDepthMaterial.onBeforeCompile = shader => {

	// app specific instancing shader code
	shader.vertexShader = '#define DEPTH_PACKING 3201'+"\n"+_SHADERCHUNKS.instance_pars_vertex + "\n" + shader.vertexShader;
	shader.vertexShader = shader.vertexShader.replace('#include <begin_vertex>','#include <begin_vertex>'+_SHADERCHUNKS.instance_vertex);

	shader.fragmentShader = '#define DEPTH_PACKING 3201'+"\n" + shader.fragmentShader;

};
2 Likes

Have a look at this example to see how to adapt the built in materials to cast shadows for instanced meshes

https://threejs.org/examples/?q=ins#webgl_buffergeometry_instancing_lambert

3 Likes

@looeee and @titansoftime: I have added a custom depthMaterial, but that did nothing extra. Then I took the onBeforeCompile aproach for the Mesh material, but that does not bring me shadows either:

https://codepen.io/fedorvaneldijk/pen/KLLdyz

I really can’t see what I am doing differently from the example…

Seems like something is wrong in the PointLight shadow setup. I changed it to DirectionalLight and I get shadows.

https://codepen.io/anon/pen/gJJPRr

You need the distance material for point lights https://codepen.io/Fyrestar/pen/JqqGZQ

Edit: the cut off shadows were caused since the mesh didn’t had frustumCulled set to false

3 Likes

I think we’ve got it! Thanks guys!

I took my first Pen and tempered a bit with it to see what does and what does not help to get those shadows. Let’s summerize all findings:

  1. When using Directional Light, you do need a customDepthMaterial
  2. When using PointLight, you do need a customDistanceMaterial
  3. It does not matter if you modify a material using onBeforeCompile, or take the shaders from THREE.ShaderLib, modify them and feed them to ShaderMaterial.
  4. The light.shadow settings are very important and can break your shadows.

Here is the pen I used to test some combinations: https://codepen.io/fedorvaneldijk/pen/OYYNow

One more question remains: the cubes now cast shadows, but they are not receiving shadows. To me this is a lesser issue, but while we are at it… any ideas?

I wanted to add, I’m pretty sure that depth packing stuff I added is only needed if your object has transparency (tree foliage in my case). You may be able to get rid of that and the alpha test stuff.

I also increased the far distance of the camera, and frustumCulled is required to set to false if you dont manually set a bounding or perform culling.

The self-shadowing is missing since you need to update the transformed variable which is used by the worldPosition set in the next include (for both, the depth/distance material and your original instancedMaterial)

https://codepen.io/Fyrestar/pen/mYYEbK

2 Likes

If you’re using npm you can give this a shot:

1 Like

Shadows (cast) are now working in my project:

With two noteworthy issues:

  • shadows do not take into account the transparency of the bush textures
  • shadows are not waving in the wind like the bushes do

For transparency add the alphaTest property to your customDistanceMaterial. The glsl code you added to your bushes material for the waving has to be added to the custom distance material too.

Is your light source supposed to be a sun?

2 Likes

See this examples for shadows with alpha cutout:
https://threejs.org/examples/#webgl_animation_cloth

1 Like

Thanks…

For the waving: of cause I used the same vertex shader code, but I did not update the timer uniform.

To change uniforms, I could not use MeshDepthMaterial but I had to build it with ShaderMaterial. That will give me a material with a uniforms-property that I can than alter.

The alpha worked too, after I added the map to the depthMaterial.

The light source is supposed to be a sun, why asking?

2 Likes