Search code examples
swiftaugmented-realityscenekitarkitvirtual-reality

Occlusion Material or Hold-Out Shader in ARKit and SceneKit


I have seen some examples demo of ARKit where material A is blocking material B, kind of creating occlusion effect, or black hole, or masking. But all of them seems to be using Unity engine (I might be wrong). I wanted to do this using what Apple provide already. Or maybe using Metal Shader.

Wondering if anyone knows a trick that allows this for ARKit or even in SceneKit term, when 2 objects are overlapping, but wanting one object to occlude the other object, leaving the other object empty. It cannot be CSG right, because that would be too expensive?


Solution

  • To generate a hold-out mask, also known as Occlusion Material, use.colorBufferWriteMask, instance property that writes depth data when rendering the material.

    sphere.geometry?.firstMaterial?.colorBufferWriteMask = []
    

    Then assign an appropriate object's rendering order:

    sphere.renderingOrder = -100  
    

    And, at last, allow SceneKit to read from / write to depth buffer when rendering the material:

    sphere.geometry?.firstMaterial?.writesToDepthBuffer = true
    sphere.geometry?.firstMaterial?.readsFromDepthBuffer = true
    
    sphere.geometry?.firstMaterial?.isDoubleSided = true
    

    enter image description here