SceneKit с использованием 2 материалов с разными текстурными координатами в одной геометрии - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь нанести два разных материала на одну и ту же геометрию.Один материал для плитки и второй для Ambient Occlusion и другие эффекты.example

Я экспортирую модель с 2 UVSet (все в порядке) в формате DAE .Когда я пытаюсь применить второй материал, он никогда не появляется.На втором материале я пытаюсь применить blendMode, прозрачность, png файл и т.д.Файл SCN : https://drive.google.com/open?id=1ddbE815hlS0VbKPsbwcJoS9cL8hOf6Mt

Что не так в моем коде? Может быть, 3D-файл ... Если у вас есть идея, предложение, решение, это здорово.

Спасибо

1 Ответ

0 голосов
/ 17 апреля 2019

Наконец, я нашел решение с shaderModifiers .

. Можно назначить разные mappingChannel для разных слотов (ambient, diffuse,зеркальный и т. д.).Справочный документ от 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

...