Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Showing a shadow on a transparent floor/plane in scenekit

Tags:

trying to figure out how I can render a shadow on an invisible plane, so the background of my sceneView shows through.

THREE.js has a ShadowMaterial which does exactly this - only the shadow is rendered.

Current thinking is to make a custom Metal shader which looks straightforward, but i'm unsure how to go about knocking out the floor to show everything aside from the shadow.

Here's an example of a shadow catcher: https://knowledge.autodesk.com/search-result/caas/sfdcarticles/sfdcarticles/Maya-2015-Shadow-Catching-with-Use-Background-material.html

like image 991
jfisk Avatar asked May 14 '17 00:05

jfisk


1 Answers

Ok, so check out this example project on Github:

https://github.com/carolight/Metal-Shadow-Map/blob/master/Shadows/Shader.metal#L67

That link is to the shader that performs the shadow map testing. Basically, it normalizes the Z position of the fragment being rendered and compares it to the Z-Buffer of the shadow map. If it is less than the shadow-Z, the pixel is fully lit (line 67) else it is tinted slightly (line 69).

What you want to do instead is write (0,0,0, shadow_opacity) for line 69 and (0,0,0,0) for line 67. This should emit transparent pixels. Set shadow_opacity as a uniform from [0.0..1.0].

The rest of the setup is shown in the example. Tilt the plane/camera to the desired setting, skip drawing the cube/vase/whatever in the main pass if you don't really want it in the scene (line 279). (However, note the shadow pass and keep it there).

like image 68
James Poag Avatar answered Sep 22 '22 11:09

James Poag