我在 SceneKit 中使用 SCNFloor 制作了两个镜子。 但是当我运行代码时,两个镜像中只有一个随机工作。为什么会这样?
希望有人能赐教。
//创建第一个镜像
func mirror() {
let floor = SCNFloor()
floor.length = 30
floor.width = 15
floor.reflectivity = 0.8
floor.reflectionResolutionScaleFactor = 1
mirrorNode.geometry = floor
mirrorNode.eulerAngles.x = GLKMathDegreesToRadians(90)
mirrorNode.eulerAngles.y = GLKMathDegreesToRadians(30)
mirrorNode.position = SCNVector3( -15 , 0 , 0)
scnScene.rootNode.addChildNode(mirrorNode)
}
//创建第二个镜像
func mirror1() {
let floor1 = SCNFloor()
floor1.length = 30
floor1.width = 15
floor1.reflectivity = 0.8
floor1.reflectionResolutionScaleFactor = 1
mirrorNode1.geometry = floor1
mirrorNode1.eulerAngles.x = GLKMathDegreesToRadians(90)
mirrorNode1.eulerAngles.y = GLKMathDegreesToRadians(-30.0)
mirrorNode1.position = SCNVector3( 15 , 0 , 0)
scnScene.rootNode.addChildNode(mirrorNode1)
}
//使用2个聚光灯照亮场景
func spotLight () {
spotlightNode.light = SCNLight()
spotlightNode.light?.type = .spot
spotlightNode.light?.intensity = 800
spotlightNode.light?.spotInnerAngle = 80
spotlightNode.light?.spotOuterAngle = 120
spotlightNode.position = SCNVector3 (0 , 0 , 50 )
scnScene.rootNode.addChildNode(spotlightNode)
}
func spotLight1 () {
spotlightNode1.light = SCNLight()
spotlightNode1.light?.type = .spot
spotlightNode1.light?.intensity = 800
spotlightNode1.light?.spotInnerAngle = 80
spotlightNode1.light?.spotOuterAngle = 120
spotlightNode1.position = SCNVector3 (0 , 0 , -50 )
spotlightNode1.eulerAngles.y = GLKMathDegreesToRadians(180)
scnScene.rootNode.addChildNode(spotlightNode1)
}
class GameViewController : UIViewController {
override public func viewDidLoad() {
super.viewDidLoad()
setupCamera()
mirror()
mirror1()
spotLight()
spotLight1()
pyramid()
scnView.backgroundColor = UIColor(red: 0.0,
green: 0.05,
blue: 0.2,
alpha: 0.7)
scnView.scene = scnScene
view = scnView
scnView.allowsCameraControl = true
scnView.autoenablesDefaultLighting = false
scnView.showsStatistics = true
}
}
我在 iPad 上使用 SwiftPlayground。非常感谢。
最佳答案
对于屏幕空间反射 (SSR) 效果,使用两个 SCNPlane
节点而不是 SCNFloor。试试我的 macOS 代码作为起点。我希望您可以轻松地将其改编为您的 Swift Playgrounds 应用程序。
import SceneKit
class GameViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let sceneView = self.view as! SCNView
sceneView.scene = SCNScene()
sceneView.allowsCameraControl = true
sceneView.backgroundColor = .lightGray
sceneView.autoenablesDefaultLighting = true
sceneView.scene?.wantsScreenSpaceReflection = true
sceneView.scene?.screenSpaceReflectionMaximumDistance = 100
sceneView.scene?.screenSpaceReflectionSampleCount = 256
sceneView.scene?.screenSpaceReflectionStride = 16
let mirrorLeft = SCNNode(geometry: SCNPlane(width: 1, height: 1))
mirrorLeft.geometry?.firstMaterial?.lightingModel = .physicallyBased
mirrorLeft.geometry?.firstMaterial?.diffuse.contents = 1
mirrorLeft.geometry?.firstMaterial?.metalness.contents = 1
mirrorLeft.geometry?.firstMaterial?.isDoubleSided = true
mirrorLeft.eulerAngles.y = .pi/4
mirrorLeft.position.x = -0.5
sceneView.scene?.rootNode.addChildNode(mirrorLeft)
let mirrorRight = SCNNode(geometry: SCNPlane(width: 1, height: 1))
mirrorRight.geometry?.firstMaterial?.lightingModel = .physicallyBased
mirrorRight.geometry?.firstMaterial?.diffuse.contents = 1
mirrorRight.geometry?.firstMaterial?.metalness.contents = 1
mirrorRight.geometry?.firstMaterial?.isDoubleSided = true
mirrorRight.eulerAngles.y = -.pi/4
mirrorRight.position.x = 0.5
sceneView.scene?.rootNode.addChildNode(mirrorRight)
let model = SCNNode(geometry: SCNPyramid())
model.geometry?.firstMaterial?.diffuse.contents = NSColor.red
model.geometry?.firstMaterial?.lightingModel = .physicallyBased
model.scale = SCNVector3(0.5, 0.5, 0.5)
model.position.z = 0.2
sceneView.scene?.rootNode.addChildNode(model)
}
}
要消除模糊,请使用以下值:
sceneView.scene?.screenSpaceReflectionSampleCount = 2048
sceneView.scene?.screenSpaceReflectionStride = 1
然后关闭粗糙度:
mirrorLeft.geometry?.firstMaterial?.roughness.contents = 0
关于swift - SceneKit——一个场景中的两个 SCNFloor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71952944/