3
votes

The Issue

I've set up a minimal SceneKit project with a scene that contains the default airplane with a transparent plane that acts as a shadow receiver. I've duplicated this setup so there are two airplanes and two transparent shadow planes.

There is a directional light that cast shadows and has its shadowMode property set to .deferred. When the two shadow planes overlap, the plane that is closer to the camera 'cuts out' the shadow on the plane that is further away from the camera.

I know this is due to the fact that the plane's material has its .writesToDepthBuffer property set to true. However, without this the deferred shadows don't work.

Missing Shadow

The Question

Is there a way to show shadows on multiple overlapping planes? I know I can use SCNFloor to show multiple shadows but I specifically want shadows on multiple planes with a different Y position. Think of a scenario in ARKit where multiple planes are detected.

The Code

I've set up a minimal project on GitHub here.

2
If you move ship or ship2 instead of either shipMesh, you will always see two shadows. Is this answering your question?E.Coms
@E.Coms the issue is that the second shadow is clipped by the shadow plane that is closest to the camera. You can see it has a partial shadow but with a corner cut out.MasDennis
How about make a slight difference between Y values of both shadow planes?E.Coms

2 Answers

0
votes

Making both Y values of shadow planes closer enough will solve the cutoff issue.

0
votes

In SceneKit it's a regular behaviour of two different planes that have a shadow projections. For getting a robust shadows use just one 3d object (plane or custom-shape geometry if you need different floor levels) as a shadow catcher.

enter image description here

If you have several 3D objects with Writes depth option turned On use Rendering order properties for each object. Nodes with greater rendering orders are rendered last. Default value of Rendering order is zero.

For instance:

geoNodeOne.renderingOrder = -1    /* Rendered first */
geoNodeTwo.renderingOrder = 50    /* Rendered last */

enter image description here

enter image description here

But in your case Rendering order property is useless because one shadow-projected plane blocks the other one.

To model a custom-shape geometry use Extrude Tool in 3D modelling app (like Maya or 3dsMax):

enter image description here