如何在 SceneKit 中显示金属和透明纹理?

Posted

技术标签:

【中文标题】如何在 SceneKit 中显示金属和透明纹理?【英文标题】:How to show metallic and transparent textures in SceneKit? 【发布时间】:2020-07-22 06:39:25 【问题描述】:

我无法在 SceneKit 中显示一些纹理,这是我想使用的模型:

Sketchfab 中的模型:https://skfb.ly/6QVTQ

模型应该在使用 Scene Kit 的 AR 环境中以这些颜色和纹理出现。但是金色的尖端看起来是黑色的,透明的镜片根本没有出现。有解决这个问题的建议吗?

模型为 .scn 格式。这是模型材料属性: https://drive.google.com/file/d/1HIHEsyONLXyL95dcSy9xWMGX89udMPND/view?usp=sharing

https://drive.google.com/file/d/1ndrZfcjqIQ4d2OfG6ZNvwyfDXnihJbnH/view?usp=sharing

如果您需要任何其他信息,请告诉我。 提前谢谢你。

【问题讨论】:

【参考方案1】:

SceneKit 中没有具有真实折射率 (IoR) 的逼真玻璃,但您可以使用 phong 着色器轻松创建假玻璃。 Phong 着色器还具有玻璃的三个重要属性 - specularityreflectivityfresnelExponent

对于金属材质,使用physicallyBased 着色模型。

这是一个代码:

import SceneKit

class ViewController: NSViewController 

    override func viewDidLoad() 
        super.viewDidLoad()

        let sceneView = self.view as! SCNView
        sceneView.scene = SCNScene(named: "glasses.scn")!
        sceneView.allowsCameraControl = true
        sceneView.pointOfView?.position.z = 20

        let glassesFrame = sceneView.scene?.rootNode.childNode(withName: "glassesFrame", 
                                                            recursively: true)

        glassesFrame?.geometry?.firstMaterial?.lightingModel = .physicallyBased
        glassesFrame?.geometry?.firstMaterial?.metalness.intensity = 1
        glassesFrame?.geometry?.firstMaterial?.diffuse.contents = NSColor.systemBrown

        let lens1 = sceneView.scene?.rootNode.childNode(withName: "rightLens", 
                                                     recursively: true)

        let lens2 = sceneView.scene?.rootNode.childNode(withName: "leftLens", 
                                                     recursively: true)

        let material = SCNMaterial()
        material.lightingModel = .phong
        material.diffuse.contents = NSColor(white: 0.2,
                                            alpha: 1)
        material.diffuse.intensity = 0.9
        material.specular.contents = NSColor(white: 1,
                                             alpha: 1)
        material.specular.intensity = 1.0
        material.reflective.contents = NSImage.Name("art.scnassets/texture.png")
        material.reflective.intensity = 2.0
        material.transparencyMode = .dualLayer
        material.fresnelExponent = 2.2
        material.isDoubleSided = true
        material.blendMode = .alpha
        material.shininess = 100
        material.transparency.native = 0.7
        material.cullMode = .back

        lens1?.geometry?.firstMaterial = material
        lens2?.geometry?.firstMaterial = material
    

【讨论】:

嗨,安迪,谢谢您的回答。事实上,我有很多模型,我会通过服务器上传它们。这段代码可以成为所有这些模型的标准吗? 嗨@shahad! “标准”是什么意思? 嗨,Andy,我有大约 60 个眼镜型号,它们将从服务器下载到应用程序。可以将此代码应用于所有这些吗? (我的意思是“眼镜框”的名称,眼镜的颜色可能会有所不同) 是的,您可以将这 2 个着色器用作您所有眼镜型号的原型(仅更改一种颜色)。 您有多少问题,您打算花多少时间进行咨询?

以上是关于如何在 SceneKit 中显示金属和透明纹理?的主要内容,如果未能解决你的问题,请参考以下文章

使用 3D 类型初始化金属纹理

如何从代码在 SceneKit 中设置基于物理的渲染?

如何使用 SceneKit iOS 将背面图像添加为纹理

SceneKit:增加用于 SCNNode 材质的纹理的清晰度?

带有 SceneKit SCNProgram 的金属着色器

在 SceneKit 中,如何在不同大小的对象上平铺纹理,同时保持最小的绘制调用?