'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        
    }
}

a screenshot of the scene

I am using SwiftPlayground on iPad. Many thanks in advance.



Solution 1:[1]

enter image description here

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