As you explicitly put meshes in the render list of the shadow generator, the system assumes that you will manage the list of shadow casters yourself, so it does not check the layer mask of the meshes against the layer mask of the camera. The layer masks are checked only if you set
shadowGenerator.getShadowMap().renderList = null.
If you want to make the shadow disappear when the mesh is not rendered by the camera, you are responsible to remove the mesh from the render list.
Now, on the opposite, if you keep the mesh in the list because you want it to cast a shadow even if not rendered by the camera, it does work as expected (see your cube) EXCEPT for a small detail when your mesh has a skeleton: the skeleton is not initialized properly because the linked mesh has not been rendered a single time, and the initializing function is called when the mesh is rendered (more precisely, it is called when a mesh is deemed to be an “active mesh”, but a mesh not rendered because of incompatible layer mask is not an “active mesh”).
If you set the layer mask of the robot after a timeout of say 500ms, you will see that its shadow is displayed because you let time to the system to run the initializing function of the skeleton.
To do it in a cleaner way, you can call
mesh.skeleton.prepare() yourself, which will initialize the skeleton properly. If you want your shadow to follow the animation of the robot, you will need to make the animation run by calling
prepare at each frame. The easiest way is to do it in