swift - SceneKit——一个场景中的两个 SCNFloor

标签 swift scenekit virtual-reality

我在 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        
    }
}

a screenshot of the scene

我在 iPad 上使用 SwiftPlayground。非常感谢。

最佳答案

enter image description here

对于屏幕空间反射 (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/

相关文章:

ios - 具有自定义 URLSessionConfiguration 的 Google map iOS SDK

ios - 如何将相机外部矩阵转换为 SCNCamera 位置和旋转

android - 如何将 android 小部件添加到 ViroCore 场景?

ios - Swift 使用 'as' 运算符将 Bool 转换为 NSNumber

arrays - 如何在 Swift 中从数组设置多个 UILabel?

ios - 如何排除模型自身的阴影?

ios - SceneKit Material 中的玻璃效果

ios - 多个SCNView音频错误

ios - 使用 Gaze Input 持续时间在 Google Cardboard 中选择 UI 文本

swift - Alamofire 是否在 HTTPS 网络上工作?