【问题标题】:Metal Shader with SceneKit SCNProgram带有 SceneKit SCNProgram 的金属着色器
【发布时间】:2016-10-08 10:51:37
【问题描述】:

我正在寻找一个可以在带有 SCNProgram 的 SceneKit 中工作的金属着色器。

谁能告诉我正确的方法声明/如何连接它?

let program = SCNProgram()
program.vertexFunctionName = "myVertex"
program.fragmentFunctionName = "myFragment"
material.program = program

然后是着色器

//MyShader.metal

vertex something myVertex(something)
{
    return something;
}

fragment float4 myFragment(something)
{
    return something
}

我只是在寻找最基本的例子。

【问题讨论】:

    标签: shader scenekit metal


    【解决方案1】:

    我剪掉了所有“不必要”的东西,这是最基本的,几乎就是我的第一个金属着色器。

    接下来我将开始研究连接其他顶点属性(颜色、法线),并可能进行一些基本的光照计算。

    #include <metal_stdlib>
    using namespace metal;
    #include <SceneKit/scn_metal>
    
    struct MyNodeBuffer {
        float4x4 modelTransform;
        float4x4 modelViewTransform;
        float4x4 normalTransform;
        float4x4 modelViewProjectionTransform;
    };
    
    typedef struct {
        float3 position [[ attribute(SCNVertexSemanticPosition) ]];
    } MyVertexInput;
    
    struct SimpleVertex
    {
        float4 position [[position]];
    };
    
    
    vertex SimpleVertex myVertex(MyVertexInput in [[ stage_in ]],
                                 constant SCNSceneBuffer& scn_frame [[buffer(0)]],
                                 constant MyNodeBuffer& scn_node [[buffer(1)]])
    {
        SimpleVertex vert;
        vert.position = scn_node.modelViewProjectionTransform * float4(in.position, 1.0);
    
        return vert;
    }
    
    fragment half4 myFragment(SimpleVertex in [[stage_in]])
    {
        half4 color;
        color = half4(1.0 ,0.0 ,0.0, 1.0);
    
        return color;
    }
    

    抱歉任何错别字,在我的手机上编辑了它......

    【讨论】:

    • 这真是太棒了,有没有通过SCNNode的材质设置的纹理的例子? - 目前可以理解,它只是将我的对象涂成红色。
    【解决方案2】:

    @lock 上面的回答很棒,所以我想通过提供一个纹理示例来扩展它,正如 OP 在 cmets 中要求的那样。

    以下是您如何配置材质以使用着色器并连接自定义纹理:

    let program = SCNProgram()
    program.fragmentFunctionName = "myFragment"
    program.vertexFunctionName = "myVertex"
    
    material.program = program
    
    let image = UIImage(named: "diffuse")!
    let imageProperty = SCNMaterialProperty(contents: image)
    // The name you supply here should match the texture parameter name in the fragment shader
    material.setValue(imageProperty, forKey: "diffuseTexture")
    

    这是从纹理中采样的修改后的着色器:

    #include <metal_stdlib>
    
    using namespace metal;
    
    #include <SceneKit/scn_metal>
    
    struct MyNodeBuffer {
        float4x4 modelTransform;
        float4x4 modelViewTransform;
        float4x4 normalTransform;
        float4x4 modelViewProjectionTransform;
    };
    
    typedef struct {
        float3 position [[ attribute(SCNVertexSemanticPosition) ]];
        float2 texCoords [[ attribute(SCNVertexSemanticTexcoord0) ]];
    } MyVertexInput;
    
    struct SimpleVertex
    {
        float4 position [[position]];
        float2 texCoords;
    };
    
    vertex SimpleVertex myVertex(MyVertexInput in [[ stage_in ]],
                                 constant SCNSceneBuffer& scn_frame [[buffer(0)]],
                                 constant MyNodeBuffer& scn_node [[buffer(1)]])
    {
        SimpleVertex vert;
        vert.position = scn_node.modelViewProjectionTransform * float4(in.position, 1.0);
        vert.texCoords = in.texCoords;
    
        return vert;
    }
    
    fragment half4 myFragment(SimpleVertex in [[stage_in]],
                              texture2d<float, access::sample> diffuseTexture [[texture(0)]])
    {
        constexpr sampler sampler2d(coord::normalized, filter::linear, address::repeat);
        float4 color = diffuseTexture.sample(sampler2d, in.texCoords);
        return half4(color);
    }
    

    【讨论】:

    • 谢谢谢谢谢谢!我会为此给你小费。我已经把你的书沃伦带来了,这正是我需要的!
    • 哈哈,乐于助人。感谢您对本书的支持:)
    • @Chris 是的,您引用的功能已打包在 SCNTechnique 类中。您也许可以依赖默认的 SceneKit 着色器,但最终可能会自己编写。
    • @Chris 当然可以。将对象材质设置为包含“MTLTexture”,然后通过计算着色器进行修改。运行良好,性能良好(没有 CPU 往返),并且比整理“SCNTechnique”更容易。虽然“SCNTechnique”是实现屏幕空间效果(模糊、光晕等)的方法。
    • 虽然理论上看起来不错,但我得到的只是没有阴影或纹理的纯白色轮廓。知道我做错了什么吗?最近的 iOS 版本可能发生了一些变化?
    猜你喜欢
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2017-10-17
    • 2016-11-13
    • 2019-04-23
    • 1970-01-01
    相关资源
    最近更新 更多