【问题标题】:SceneKit using 2 materials with different Texture Coordinates on same geometrySceneKit 在同一几何体上使用具有不同纹理坐标的 2 种材质
【发布时间】:2019-04-16 14:52:53
【问题描述】:

我尝试在同一个几何体上应用两种不同的材质。 一种材质用于平铺,第二种材质用于Ambient Occlusion 和其他效果。

我以 DAE 格式导出具有 2 个 UVSet(没关系)的模型。当我尝试应用第二种材料时,它永远不会出现。在第二种材料上,我尝试应用 blendMode、transparencyMode、png 文件等。没有任何效果:(( 如果我在第一个材质上更改 mappingChannel,映射就可以了!

let mat1 = SCNMaterial()
mat1.name = "Mat1"
mat1.diffuse.mappingChannel = 0
mat1.diffuse.contents = UIImage(named: "somePNGFile.png")


let mat2 = SCNMaterial()
mat2.name = "Mat2"
mat2.diffuse.mappingChannel = 1
mat2.diffuse.contents = UIImage(named: "otherPNGFile.png")

cube.geometry!.materials = [mat1, mat2]

这是我的 SCN 文件https://drive.google.com/open?id=1ddbE815hlS0VbKPsbwcJoS9cL8hOf6Mt

我的代码有什么问题?也许是 3D 文件... 如果您有想法、建议、解决方案,那就太好了。

谢谢

【问题讨论】:

    标签: swift scenekit texture-mapping


    【解决方案1】:

    最后,我找到了使用 shaderModifiers 的解决方案。

    可以在不同的slots(环境、漫反射、镜面反射等)上分配不同的ma​​ppingChannel。 来自 Apple 的参考文档:https://developer.apple.com/documentation/scenekit/scnshadermodifierentrypointsurface?language=objc

    这是我的代码:

        var mat:SCNMaterial!
        var model:SCNReferenceNode!
    
        override init() {
            super.init()
    
            // INIT
            initModel()
            initShader()
            assignTextures()
        }
    
        func initModel() {
            let url = Bundle.main.url(forResource: "Test_MixMaterials", withExtension: "scn", subdirectory: "Test.scnassets")!
            model = SCNReferenceNode(url: url)!
            model.load()
            self.addChildNode(model)
    
            if let cube = model.childNode(withName: "pCube1", recursively: true) {
                mat = SCNMaterial()
                // Define mapping Channel 0 on diffuse slot
                mat.diffuse.mappingChannel = 0
                // Define mapping Channel 1 on ambient slot
                mat.ambient.mappingChannel = 1
                // Assign material
                cube.geometry!.firstMaterial = mat
            }
        }
    
        func initShader() {
            let shader = """
    
            // Samplers 2D.
            uniform sampler2D texture_UV1;
            uniform sampler2D texture_UV2;
    
            // Directives
            #pragma transparent
            #pragma body
    
            // Source Diffuse  ------------------------------------------------------------------------------------------------------------
            vec4 source = texture2D(texture_UV1, _surface.diffuseTexcoord);
    
            // Destination Diffuse --------------------------------------------------------------------------------------------------------
            vec4 dest = texture2D(texture_UV2, _surface.ambientTexcoord);
    
            // MULTIPLY Diffuses ---------------------------------------------------------------------------------------------------------------
            _surface.diffuse = source * dest;
            """
    
            mat.shaderModifiers = [
                .surface:shader
            ]
        }
    
        func assignTextures() {
            let setTexture_1 = SCNMaterialProperty(contents: UIImage(named: "someImage.png")!)
            let setTexture_2 = SCNMaterialProperty(contents: UIImage(named: "otherImage.png")!)
    
            mat.setValue(setTexture_1, forKey: "texture_UV1")
            mat.setValue(setTexture_2, forKey: "texture_UV2")
        }
    

    这就是工作......

    如果你想测试,这里是我使用的模型https://drive.google.com/open?id=1ddbE815hlS0VbKPsbwcJoS9cL8hOf6Mt

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 2014-11-25
      • 2017-12-09
      • 2019-04-06
      • 1970-01-01
      • 2018-07-06
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多