从远处的灯光投射阴影

时间:2018-10-04 11:09:46

标签: swift scenekit augmented-reality arkit shadow

我有一个AR应用,其中我已经从用户那里计算了当前的太阳位置。我将此位置减小为10,000 meters的距离,因此当我在场景内移动时,它会“停留”在适当的位置。现在,我想从场景中其他节点上的该节点投射阴影。我尝试了几种闪电,但都没有成功。有些根本没有投下阴影,有些则表现得很奇怪。从这样远的节点创建光源以在不可见的floor node上投射阴影的最佳方法是什么?我还应该在场景中添加ambient灯光吗?可以将其添加到相机节点,还是应该放置在其他位置?

1 个答案:

答案 0 :(得分:2)

使用directional光进行Sun模拟(太阳具有平行光线,对我们来说,它们是来自很远光源的主光线),并使用ambient光模拟假的次级光线(如果您不使用,全球照明)。

// DIRECTIONAL LIGHT for `primary light rays` simulation
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = .directional
lightNode.light!.castsShadow = true
lightNode.light!.shadowMode = .deferred
lightNode.light!.categoryBitMask = -1
lightNode.light!.automaticallyAdjustsShadowProjection = true
//lightNode.light!.maximumShadowDistance = 11000
lightNode.position = SCNVector3(x: 0, y: -5000, z: 0)
lightNode.rotation = SCNVector4(x: -1, y: 0, z: 0, w: .pi/2)
scene.rootNode.addChildNode(lightNode)
  

提示directional灯的位置可以是任意位置(在以下代码中,它甚至位于平面y:-5000下方),最重要的是 directional的方向

     

directional灯也没有falloff参数,也没有quadratic light decay参数。

// AMBIENT LIGHT for `fake secondary light rays` simulation
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.intensity = 1000
ambientLightNode.light!.color = NSColor.white
scene.rootNode.addChildNode(ambientLightNode)

请勿错误使用此布尔值:

lightNode.castsShadow = true

代替这个:

lightNode.light!.castsShadow = true

布尔值lightNode.castsShadow确定SceneKit是否将节点的内容渲染到阴影贴图中。

如果您希望在手动创建的directional灯光中启用阴影,请参见以下屏幕截图:

enter image description here

有时候,如果在相机上安装灯,您会获得一些好处。在这种情况下,法线平行于光线的物体表面会被照亮。