自定义默认照明
我相信,在 SceneKit 中,默认场景照明是没有任何阴影的定向光,直接附加到默认相机节点(即 pointOfView 节点)。要模拟与 .autoenablesDefaultLighting 属性为 true 时相同的照明条件,请使用以下代码:
委托的渲染器方法——光的位置方向将每秒更新 60 次:
import SceneKit
extension GameViewController: SCNSceneRendererDelegate {
func renderer(_ renderer: SCNSceneRenderer,
updateAtTime time: TimeInterval) {
sunNode.transform = (sceneView?.pointOfView?.worldTransform)!
let cameraAngles = (self.sceneView?.pointOfView?.eulerAngles)!
let lightAngles = self.sunNode.eulerAngles
print("Camera: " + String(format: "%.2f, %.2f, %.2f", cameraAngles.x,
cameraAngles.y,
cameraAngles.z))
print("Light: " + String(format: "%.2f, %.2f, %.2f", lightAngles.x,
lightAngles.y,
lightAngles.z))
}
}
这是 GameViewController 类:
class GameViewController: NSViewController {
var sceneView: SCNView? = nil
let sunNode = SCNNode()
override func viewDidLoad() {
super.viewDidLoad()
sceneView = self.view as? SCNView
sceneView?.delegate = self
let scene = SCNScene(named: "ship.scn")!
sceneView?.scene = scene
sceneView?.scene?.lightingEnvironment.contents = .none
sceneView?.scene?.background.contents = .none
sceneView?.backgroundColor = .black
sceneView?.allowsCameraControl = true
// sceneView?.autoenablesDefaultLighting = true
sunNode.light = SCNLight()
sunNode.light?.type = .directional
sceneView?.scene?.rootNode.addChildNode(sunNode)
}
}
说明
我想补充一点,如果场景中根本没有光(包括autoenablesDefaultLighting参数),那么场景中唯一无法控制的光源将是不可切换的环境光。
除了上述之外,基于物理的着色器始终需要额外的环境光灯具(否则基于物理的表面将是黑色的)。该光源的位置和方向无关紧要。
如果 Directional Light 垂直照亮表面,则表面以 100% 强度照亮(默认强度为 1000 流明),但如果光源的光线与表面平行,则表面不会被此光源照亮。
如您所见,第一张和最后一张图像具有相同的照明环境。