[SCNTechnique管道在我使用DRAW_SCENE时几乎立即崩溃

问题描述 投票:0回答:1

我是Metal(和一般着色器)的新手。我一直在尝试使用ARSCNViewMSL spec创建一个SCNTechnique docs应用程序以应用着色器。

我想要一个着色器管道,它将使我仅更改摄影机提要视图(sceneView.scene.background),但允许所有SCNNodes与重叠的未更改摄影机提要混合。这是我的计划:

我的计划

[1)第一遍将我的第一个样式化着色器应用于场景(它只是调整颜色/亮度,我已经用DRAW_QUAD对其进行了测试并且可以正常工作)到DRAW_SCENE,并使用excludeCategoryMask排除所有节点。

着色器应包括某种统一的数据结构,该结构包含场景中的所有其他节点(当前为空,因为尚未渲染节点),并使用其屏幕空间坐标在滤色器中剪切适当大小/位置的形状节点重叠的位置。

[2)第二遍使用标准/默认SCNKit着色器使用DRAW_NODE渲染其余节点(球体等)。

问题

我不知道这是否是一种有效的方法,因为我的应用几乎在com.apple.scenekit.scnview-renderer (15): EXC_BAD_ACCESS (code=1, address=0xeb52be860)下崩溃。当我从DRAW_QUAD切换到DRAW_SCENE时,着色器崩溃。我想我缺少深度缓冲之类的东西。

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

struct VertexInput_0 {
    float4 position [[ attribute(SCNVertexSemanticPosition) ]];
    float2 texcoord [[ attribute(SCNVertexSemanticTexcoord0) ]];
};

struct VertexOutput_0 {
    float4 position [[position]];
    float2 texcoord;
};

// metalVertexShader
vertex VertexOutput_0 scene_filter_vertex_0(VertexInput_0 in [[stage_in]])
{
    VertexOutput_0 out;
    out.position = in.position;
    out.texcoord = float2((in.position.x + 1.0) * 0.5 , (in.position.y + 1.0) * -0.5);
    return out;
}

// metalFragmentShader
fragment half4 scene_filter_fragment_0(VertexOutput_0 vert [[stage_in]],
                                     texture2d<half, access::sample> scene [[texture(0)]])
{
    constexpr sampler samp = sampler(coord::normalized, address::repeat, filter::nearest);
    half4 color = scene.sample(samp, vert.texcoord);

    constexpr half3 weights = half3(2, 0.7152, 0.0722);
    color.rgb = half3(dot(color.rgb, weights));


    return color;
}

// Doesn't reach here, crashes before second pass below

struct VertexInput_1 {
    float4 position [[ attribute(SCNVertexSemanticPosition) ]];
    float2 texcoord [[ attribute(SCNVertexSemanticTexcoord0) ]];
};

struct VertexOutput_1 {
    float4 position [[position]];
    float2 texcoord;
};

// metalVertexShader
vertex VertexOutput_1 scene_filter_vertex_1(VertexInput_1 in [[stage_in]])
{
    VertexOutput_1 out;
    out.position = in.position;
    out.texcoord = float2((in.position.x + 1.0) * 0.5 , (in.position.y + 1.0) * -0.5);
    return out;
}

// metalFragmentShader
fragment half4 scene_filter_fragment_1(VertexOutput_1 vert [[stage_in]],
                                     texture2d<half, access::sample> scene [[texture(0)]])
{
    constexpr sampler samp = sampler(coord::normalized, address::repeat, filter::nearest);
    half4 color = scene.sample(samp, vert.texcoord);

    return color;
}

shaders.metal

<plist version="1.0">
<dict>
    <key>sequence</key>
    <array>
        <string>filter_0</string>
        <string>filter_1</string>
    </array>
    <key>passes</key>
    <dict>
        <key>filter_1</key>
        <dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>COLOR</string>
            </dict>
            <key>inputs</key>
            <dict>
                <key>scene</key>
                <string>COLOR</string>
            </dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>metalVertexShader</key>
            <string>scene_filter_vertex_2</string>
            <key>metalFragmentShader</key>
            <string>scene_filter_fragment_2</string>
        </dict>
        <key>filter_0</key>
        <dict>
            <key>metalFragmentShader</key>
            <string>scene_filter_fragment_0</string>
            <key>metalVertexShader</key>
            <string>scene_filter_vertex_0</string>
            <key>excludeCategoryMask</key>
            <integer>2</integer>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>COLOR</string>
            </dict>
            <key>inputs</key>
            <dict>
                <key>scene</key>
                <string>COLOR</string>
            </dict>
            <key>draw</key>
            <string>DRAW_SCENE</string>
        </dict>
    </dict>
</dict>
</plist>

为什么会崩溃?我在某处缺少参数吗?

ios shader scenekit arkit metal
1个回答
0
投票

可能是scene_filter_vertex_2,并且scene_filter_fragment_2需要重命名scene_filter_vertex_1scene_filter_fragment_1

© www.soinside.com 2019 - 2024. All rights reserved.