有没有办法在其他人面前绘制SCNNode?

Mat*_*cha 7 scenekit swift scnnode

我一直在尝试使用场景工具包创建一个场景,其中指定的对象始终位于其他对象的前面,尽管事实上它实际上位于其他对象的后面.与搅拌机中使用的效果类似.

显然,blender使用GUI和大量数学来转换2D对象,但我需要在具有SCNGeometry的SCNNode中使用此效果,换句话说,当前位于场景中的3D对象.

我考虑使用类别掩码,但在阅读Apple的文档后,我意识到这对我正在寻找的效果不起作用.

有没有人知道在SceneKit中做这个的方法?或者更好的是,甚至可以这样做吗?

非常感谢大家,现在以及我从StackExchange获得的所有其他帮助!

Mat*_*cha 6

所以,结果我找到了我的问题的答案(在mnuages的帮助下).我只想发一个完整的答案.

最后结果
像由mnuages建议,我试图同时设置readsFromDepthBufferwritesToDepthBuffer为false,并设置节点renderingOrder,以大量的.它的工作方式不对.它总是落后于每个物体,而不是总是在前面.获得图片中显示的结果的方法是仅设置readsFromDepthBuffer为false,并将立方体设置renderingOrder为-1,否则将无法绘制它.

由于立方体和其他节点的材料具有readsFromDepthBufferwritesToDepthBuffer设置为默认值true,它仍然位于其后面的对象前面,并且在它前面的对象后面,换句话说,它将是正常的,只有箭头将按照我们想要的方式运作.

从图像中可以看出,立方体前面的线条部分是可见的.对于背后的部分,不能说同样的事情.


Xar*_*tec 6

正如我在之前的回答中所解释的那样,接受的答案不是最佳的,仅适用于广告牌、平显和其他通常为平面的物体(不一定完全是 2D 的)。当使用 3D 对象并禁用从深度缓冲区读取和上面图像中的对象时,它不会从每个角度正确渲染。即 3D 对象需要从深度缓冲区读取以检测其自身的像素和深度。说了这么多,我给出了正确的答案:

SCN技术

简而言之,渲染 2 个额外的通道。一个用于控制 Gizmo (DRAW_NODE),另一个用于通过另一个通道(DRAW_QUAD,使用使用前一个通道作为输入的着色器)将其与场景混合在一起。

以下是技术的 scntec.plist 内容:

<?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>gizmoonly</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
                <key>clearColor</key>
                <string>0.5 0.5 0.5 0.0</string>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>inputs</key>
            <dict>
                <key>colorSampler</key>
                <string>COLOR</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>gizmonode</string>
            </dict>
            <key>draw</key>
            <string>DRAW_NODE</string>
            <key>node</key>
            <string>movegizmo</string>
        </dict>
        <key>quadscene</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
                <key>clearColor</key>
                <string>sceneBackground</string>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>inputs</key>
            <dict>
                <key>totalSceneO</key>
                <string>COLOR</string>
                <key>a_texcoord</key>
                <string>a_texcoord-symbol</string>
                <key>gizmoNodeO</key>
                <string>gizmonode</string>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>COLOR</string>
            </dict>
            <key>draw</key>
            <string>DRAW_QUAD</string>
            <key>program</key>
            <string>gizmo</string>
        </dict>
    </dict>
    <key>sequence</key>
    <array>
        <string>gizmoonly</string>
        <string>quadscene</string>
    </array>
    <key>targets</key>
    <dict>
        <key>totalscene</key>
        <dict>
            <key>type</key>
            <string>color</string>
        </dict>
        <key>gizmonode</key>
        <dict>
            <key>type</key>
            <string>color</string>
        </dict>
    </dict>
    <key>symbols</key>
    <dict>
        <key>a_texcoord-symbol</key>
        <dict>
            <key>semantic</key>
            <string>texcoord</string>
        </dict>
        <key>vertexSymbol</key>
        <dict>
            <key>semantic</key>
            <string>vertex</string>
        </dict>
    </dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)

以下是第二遍的顶点着色器:

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = (a_position.xy + 1.0) * 0.5;
}
Run Code Online (Sandbox Code Playgroud)

第二遍的片段着色器:

uniform sampler2D totalSceneO;
uniform sampler2D gizmoNodeO;

varying vec2 uv;

void main() {
    vec4 t0 = texture2D(totalSceneO, uv);
    vec4 t1 = texture2D(gizmoNodeO, uv);
    gl_FragColor = (1.0 - t1.a) * t0 + t1.a * t1;
}
Run Code Online (Sandbox Code Playgroud)

SWIFT代码:

if let path = NSBundle.mainBundle().pathForResource("scntec", ofType: "plist") {
            if let dico1 = NSDictionary(contentsOfFile: path)  {
                let dico = dico1 as! [String : AnyObject]

                let technique = SCNTechnique(dictionary:dico)
                scnView.technique = technique
            }
}
Run Code Online (Sandbox Code Playgroud)

目标 C 代码:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"scntec" withExtension:@"plist"];
SCNTechnique *technique = [SCNTechnique techniqueWithDictionary:[NSDictionary dictionaryWithContentsOfURL:url]];
    self.myView.technique = technique;
Run Code Online (Sandbox Code Playgroud)

设置 Gizmo 节点的名称:

theGizmo.name = @"movegizmo";
Run Code Online (Sandbox Code Playgroud)