【问题标题】:ARKit Rendering an object silhouette when behind other objects using SCNTechniqueARKit 使用 SCNTechnique 在其他对象后面时渲染对象轮廓
【发布时间】:2020-12-19 06:18:28
【问题描述】:

我想在我的 ARKit 应用程序中渲染一个 Gizmo 对象,以便它在其他几何体后面仍然可见,但作为一个变暗的轮廓。我发现 here 的 Unity 着色器产生了我试图在 SceneKit/ARKit 中重现的效果。

我一直在研究使用 SCNTechnique,并且一直在使用here 中描述的示例。我稍微修改了这个例子,但大体上是一个 3 pass 着色器:

  1. 第一遍渲染整个场景(绘制:DRAW_SCENE
  2. 第二遍仅渲染 Gizmo 深度大于场景深度的部分 Gizmo(绘制:DRAW_SCENE 和 Gizmo 的 includeCategoryMask)。
  3. 混合第一个和第二个通道的输出,以便在通道 2 中渲染的隐藏部分使通道 1 变暗。

Pass 1 工作正常,因为整个场景按预期渲染为黑色背景(在colorStates 中设置)。但是,无论我尝试什么,在第 2 步中,colorStates 的“clear”属性总是被忽略。我希望 pass 2 有一个像 pass 1 一样的黑色背景,但它总是从 ARKit 输出相机馈送。这会导致第 3 遍出现问题,我无法正确混合颜色,因为第 2 遍包含所有相机馈送细节,它应该是黑色的。我不确定这是否是 ARKit 中的错误,或者我误解了 SCNTechniques,但我们将不胜感激。

这是我的 SCN 技术:

<?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>passes</key>
    <dict>
        <key>pass_scene</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clearColor</key>
                <string>0 0 0 1</string>
                <key>clear</key>
                <true/>
            </dict>
            <key>draw</key>
            <string>DRAW_SCENE</string>
            <key>inputs</key>
            <dict/>
            <key>outputs</key>
            <dict>
                <key>depth</key>
                <string>DEPTH</string>
                <key>color</key>
                <string>color_scene</string>
            </dict>
        </dict>
        <key>pass_gizmo</key>
        <dict>
            <key>includeCategoryMask</key>
            <integer>2</integer>
            <key>colorStates</key>
            <dict>
                <key>clearColor</key>
                <string>0 0 0 1</string>
                <key>clear</key>
                <true/>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>func</key>
                <string>greater</string>
                <key>enableWrite</key>
                <false/>
                <key>clear</key>
                <false/>
            </dict>
            <key>outputs</key>
            <dict>
                <key>depth</key>
                <string>DEPTH</string>
                <key>color</key>
                <string>color_gizmo</string>
            </dict>
            <key>inputs</key>
            <dict>
                <key>color</key>
                <string>color_gizmo</string>
            </dict>
            <key>draw</key>
            <string>DRAW_SCENE</string>
        </dict>
        <key>mix</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>clear</key>
                <false/>
            </dict>
            <key>inputs</key>
            <dict>
                <key>totalSampler</key>
                <string>color_scene</string>
                <key>gizmoSampler</key>
                <string>color_gizmo</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>COLOR</string>
            </dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>program</key>
            <string>doesntexist</string>
            <key>metalFragmentShader</key>
            <string>gizmo_fragment</string>
            <key>metalVertexShader</key>
            <string>gizmo_vertex</string>
        </dict>
    </dict>
    <key>sequence</key>
    <array>
        <string>pass_scene</string>
        <string>pass_gizmo</string>
        <string>mix</string>
    </array>
    <key>targets</key>
    <dict>
        <key>color_scene</key>
        <dict>
            <key>type</key>
            <string>color</string>
        </dict>
        <key>color_gizmo</key>
        <dict>
            <key>type</key>
            <string>color</string>
        </dict>
    </dict>
    <key>symbols</key>
    <dict>
        <key>vertexSymbol</key>
        <dict>
            <key>semantic</key>
            <string>vertex</string>
        </dict>
    </dict>
</dict>
</plist>

主要感兴趣的区域是pass_gizmo 传递的colorStates 属性从未真正清除/无论如何总是渲染相机馈送;

<key>colorStates</key>
<dict>
<key>clearColor</key>
    <string>0 0 0 1</string>
    <key>clear</key>
    <true/>
</dict>

【问题讨论】:

    标签: ios swift scenekit arkit metal


    【解决方案1】:

    我最终设法找到了一种方法来创建我想要的对象轮廓着色器。它不像我希望的那样优雅,但它是我可以在 ARKit 中工作的唯一解决方案。

    我从未设法解决我最初的问题,但我怀疑这与我的通行证上的输入/输出组合不正确有关。

    如果以后有人偶然发现这个想要创建类似的效果,我使用下面描述的 3 pass SCNTechnique 实现了它:

    • 通过 1,DRAW_SCENE 照常绘制场景。颜色输出到 COLOR,深度输出到 DEPTH
    • 通过 2,DRAW_SCENE + category mask 将我的 Gizmo 的深度绘制到深度目标:gizmo_depth
    • 通过 3,DRAW_QUAD 自定义金属片段着色器,它比较场景深度和 Gizmo 深度以找到隐藏的几何体,然后将场景的颜色相乘以创建轮廓效果。

    很遗憾SCNTechnique 使用起来很麻烦,因为我通常非常喜欢这种格式。尽管我确信它们在目标中被正确定义,但我在连续传递不共享目标方面遇到了很多困难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-21
      • 2019-02-07
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 2019-01-14
      相关资源
      最近更新 更多