'SceneKit – Two SCNFloor in a single scene
I have made two mirrors using SCNFloor in SceneKit. But when I run the code, only one of the two mirrors work randomly. Why is that so?
Hope someone can enlighten me.
// creation of the first mirror
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)
}
// creation of the second mirror
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)
}
// use 2 spotlight to illuminate the scene
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
}
}
I am using SwiftPlayground on iPad. Many thanks in advance.
Solution 1:[1]
For screen-space reflection (SSR) effect use two SCNPlane nodes instead of SCNFloor. Try my macOS code as a starting point. I hope you can easily adapt it for your Swift Playgrounds app.
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)
}
}
To get rid of the blurriness use the following values:
sceneView.scene?.screenSpaceReflectionSampleCount = 2048
sceneView.scene?.screenSpaceReflectionStride = 1
And turn a roughness off:
mirrorLeft.geometry?.firstMaterial?.roughness.contents = 0
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

