Search code examples
swiftaugmented-realityscenekitarkit

Is it possible to project light on a transparent SCNFloor in ARKit?


I want to put a SCNLight node and project a light to transparent SCNFloor? This will give the effect of light projection on real surface. Similar to shadowOnly lighting model that cast shadow. Is this possible?


Solution

  • Yes, you can do that by casting a white (or bleeded color) shadow instead of a black one. For that you have to use deferred shadows type that are rendered in a post-processing pass.

    Consider, you must use two separate lights in your scene – first one for white shadows casting, and a second one for lighting objects that cast these white shadows. You're able to include and exclude objects from lighting scheme implementing categoryBitMask property.

    // SETTING A SHADOW CATCHER
    let plane = SCNPlane(width: 10, height: 10)
    plane.firstMaterial?.isDoubleSided = true
    plane.firstMaterial?.lightingModel = .shadowOnly
    let planeNode = SCNNode(geometry: plane)
    planeNode.eulerAngles.x = -.pi / 2
    scene.rootNode.addChildNode(planeNode)
    
    // SETTING A LIGHT
    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light?.type = .directional
    lightNode.light?.intensity = 50
    lightNode.light?.color = UIColor.black
    lightNode.eulerAngles.x = -.pi / 2
    scene.rootNode.addChildNode(lightNode)
        
    // DEFERRED SHADOWS
    lightNode.light?.castsShadow = true
    lightNode.light?.shadowMode = .deferred          // important
    lightNode.light?.forcesBackFaceCasters = true    // important
    lightNode.light?.shadowRadius = 10
    lightNode.light?.shadowColor = UIColor.white