iOS SceneKit SCNTechnique Metal顶点和片段方法在iOS12中不起作用

时间:2018-11-20 09:50:59

标签: shader metal xcode10 ios12 scntechnique

我有一个SCNSceneView.technique的字典文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>targets</key>
    <dict>
        <key>rt_0</key>
        <dict>
            <key>size</key>
            <string>128x256</string>
            <key>type</key>
            <string>color</string>
        </dict>
        <key>rt_1</key>
        <dict>
            <key>size</key>
            <string>128x256</string>
            <key>type</key>
            <string>color</string>
        </dict>
    </dict>
    <key>passes</key>
    <dict>
        <key>pass_final</key>
        <dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>program</key>
            <string>doesntexist</string>
            <key>metalVertexShader</key>
            <string>pass_through_vertex</string>
            <key>metalFragmentShader</key>
            <string>pass_through_fragment_final</string>
            <key>inputs</key>
            <dict>
                <key>colorSampler</key>
                <string>COLOR</string>
                <key>blurSampler</key>
                <string>rt_1</string>
                <key>aPos</key>
                <string>vertexSymbol</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>COLOR</string>
            </dict>
        </dict>
        <key>pass_vert</key>
        <dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>program</key>
            <string>doesntexist</string>
            <key>metalVertexShader</key>
            <string>pass_through_vertex</string>
            <key>metalFragmentShader</key>
            <string>pass_through_fragment_vert</string>
            <key>inputs</key>
            <dict>
                <key>colorSampler</key>
                <string>COLOR</string>
                <key>aPos</key>
                <string>vertexSymbol</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>rt_0</string>
            </dict>
        </dict>
        <key>pass_hori</key>
        <dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>program</key>
            <string>doesntexist</string>
            <key>metalVertexShader</key>
            <string>pass_through_vertex</string>
            <key>metalFragmentShader</key>
            <string>pass_through_fragment_hori</string>
            <key>inputs</key>
            <dict>
                <key>colorSampler</key>
                <string>rt_0</string>
                <key>aPos</key>
                <string>vertexSymbol</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>rt_1</string>
            </dict>
        </dict>
    </dict>
    <key>sequence</key>
    <array>
        <string>pass_vert</string>
        <string>pass_hori</string>
        <string>pass_vert</string>
        <string>pass_hori</string>
        <string>pass_final</string>
    </array>
    <key>symbols</key>
    <dict>
        <key>vertexSymbol</key>
        <dict>
            <key>semantic</key>
            <string>vertex</string>
        </dict>
    </dict>
    <key>reflectionResolutionScaleFactor</key>
    <string>0.5</string>
</dict>
</plist>

技术文件中通过的金属文件如下:

#include <metal_stdlib>
using namespace metal;
#include <SceneKit/scn_metal>

struct custom_vertex_t
{
    float4 position [[attribute(SCNVertexSemanticPosition)]];
};

constexpr sampler s = sampler(coord::normalized,
                              address::repeat,
                              filter::linear);

constexpr sampler sClamp = sampler(coord::normalized,
                              filter::linear);

struct out_vertex_t
{
    float4 position [[position]];
    float2 uv;
};

vertex out_vertex_t pass_through_vertex(custom_vertex_t in [[stage_in]])
{
    out_vertex_t out;
    out.position = in.position;
    out.uv = float2((in.position.x + 1.0) * 0.5 , (in.position.y + 1.0) * -0.5 + 1.0);
    return out;
};

// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
constant float offset[] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
constant float weight[] = { 0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162 };

fragment half4 pass_through_fragment_hori(out_vertex_t vert [[stage_in]],
                                          texture2d<float, access::sample> colorSampler [[texture(0)]])
{

    float4 FragmentColor = colorSampler.sample( s, vert.uv) * weight[0];
    for (int i=1; i<5; i++) {
        FragmentColor += colorSampler.sample( sClamp, ( vert.uv + float2(offset[i], 0.0)/224.0 ) ) * weight[i];
        FragmentColor += colorSampler.sample( sClamp, ( vert.uv - float2(offset[i], 0.0)/224.0 ) ) * weight[i];
    }

    return half4(FragmentColor);
}

fragment half4 pass_through_fragment_vert(out_vertex_t vert [[stage_in]],
                                     texture2d<float, access::sample> colorSampler [[texture(0)]])
{

    float4 FragmentColor = colorSampler.sample( s, vert.uv) * weight[0];
    for (int i=1; i<5; i++) {
        FragmentColor += colorSampler.sample( sClamp, ( vert.uv + float2(0.0, offset[i])/224.0 ) ) * weight[i];
        FragmentColor += colorSampler.sample( sClamp, ( vert.uv - float2(0.0, offset[i])/224.0 ) ) * weight[i];
    }


    return half4(FragmentColor);

};
fragment half4 pass_through_fragment_final(out_vertex_t vert [[stage_in]],
                                          texture2d<float, access::sample> colorSampler [[texture(0)]],
                                           texture2d<float, access::sample> blurSampler [[texture(1)]])
{

    float4 FragmentColor = colorSampler.sample( s, vert.uv);
    float4 BlurColor = blurSampler.sample( s, vert.uv) * 0.5;
    FragmentColor.xyz += BlurColor.xyz;
    return half4(FragmentColor);
}

基本上,该技术是一个后处理模糊滤镜,具有针对SceneView的链接传递,在iOS11和Xcode9之前,它可以正常工作。 但是在iOS12之后,我收到了以下错误代码:

[SceneKit] Error: Pass XXX(all passes included) is not linked to the rendering graph and will be ignored check it's input/output

似乎顶点和片段金属方法尚未链接。但是我不知道在iOS 12和Xcode10下发生了什么变化。

有人知道如何修复代码吗?

0 个答案:

没有答案