Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 有没有办法总是在别人面前画一个SCNNode?_Swift_Scenekit_Scnnode - Fatal编程技术网

Swift 有没有办法总是在别人面前画一个SCNNode?

Swift 有没有办法总是在别人面前画一个SCNNode?,swift,scenekit,scnnode,Swift,Scenekit,Scnnode,我一直在尝试用scene kit制作一个场景,其中一个指定的对象始终位于其他对象的前面,尽管它实际上位于其他对象的后面。在中使用了与此类似的效果 显然,blender使用GUI和大量数学来转换其他2D对象,但我需要在具有SCN度量的SCN节点中使用这种效果,换句话说,当前位于场景中的3D对象 我曾考虑过使用分类掩码,但在阅读了苹果的文档后,我意识到这对我想要的效果不起作用 有人知道在SceneKit做这件事的方法吗?或者更好的是,有可能做到这一点吗 提前非常感谢大家,现在以及我从StackExc

我一直在尝试用scene kit制作一个场景,其中一个指定的对象始终位于其他对象的前面,尽管它实际上位于其他对象的后面。在中使用了与此类似的效果

显然,blender使用GUI和大量数学来转换其他2D对象,但我需要在具有SCN度量的SCN节点中使用这种效果,换句话说,当前位于场景中的3D对象

我曾考虑过使用分类掩码,但在阅读了苹果的文档后,我意识到这对我想要的效果不起作用

有人知道在SceneKit做这件事的方法吗?或者更好的是,有可能做到这一点吗


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

SCNMaterial
公开了
writesToDepthBuffer
readsFromDepthBuffer
,这将允许您这样做(与
SCNNode
渲染顺序
结合使用,如果需要)

因此,我找到了我问题的答案(在mnuages的帮助下)。我只是想发布一个完整的答案


就像mnuages建议的那样,我尝试将
readsFromDepthBuffer
writesDepthBuffer
设置为false,并将节点的
renderingOrder
设置为一个较高的数字。它以错误的方式工作。它不是总是在前面,而是总是在每个物体后面。获取图片中显示的结果的方法是将only
readsFromDepthBuffer
设置为false,并将多维数据集的
renderingOrder
设置为-1,否则将无法在其上绘制

由于多维数据集和其他节点的材质已将
readsFromDepthBuffer
writesDepthBuffer
设置为默认值
true
,因此它仍将位于其后面的对象前面,而在其前面的对象后面,换句话说,这是正常的,只有箭头的行为符合我们的要求

如图所示,立方体前面的线条部分是可见的。对于它背后的部分,情况并非如此


编辑:这只适用于我,因为在我的情况下,相机不必围绕对象旋转。如果无论摄影机角度如何,都需要gizmo始终位于前方,则该选项将不起作用。检查已接受的答案,了解如何实现此目的的说明,此外,simeon针对金属实现的答案。

readsFromDepthBuffer答案可能适用于所示图像中的角度,但如果要旋转并查看不同角度,您将看到gizmo的轴从某些角度错误重叠。换句话说,当某个轴应位于另一个轴的前面时,该轴将位于另一个轴的后面,这取决于面渲染的顺序。这显然是因为对象(材质)不读取深度缓冲区,包括其自身已渲染的部分


通常,在主场景前面渲染SCNNode的简单解决方案是在场景的叠加场景中使用SK3DNode(具有自己的场景和depthbuffer)。对于回答中图片所示的场景,这将需要额外的代码来准确旋转和定位SK3DNode,因此这可能不是OP想要的,但这可能会对发现此问题的其他人有所帮助。

如我在之前的回答中所述,公认的答案不是最佳答案,仅适用于广告牌、HUD和其他一般平面对象(不一定完全是2D)。当使用3D对象并禁用从深度缓冲区读取以及上面图像中的对象时,它不会从每个角度正确渲染。即,3D对象需要从深度缓冲区读取以检测其自身的像素和深度。综上所述,我给出了正确的答案:

简而言之,渲染2个附加过程。一个用于控制gizmo(DRAW_节点),另一个用于通过另一个过程将其与场景混合(DRAW_QUAD,具有使用前一个过程作为输入的着色器)

以下是techique的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>
第二遍的片段着色器:

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = (a_position.xy + 1.0) * 0.5;
}
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;
}
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
            }
}
目标C代码:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"scntec" withExtension:@"plist"];
SCNTechnique *technique = [SCNTechnique techniqueWithDictionary:[NSDictionary dictionaryWithContentsOfURL:url]];
    self.myView.technique = technique;
设置gizmo节点的名称:

theGizmo.name = @"movegizmo";

@Xartec的答案是正确的。基本上,在透明背景上单独渲染gizmo,然后使用简单着色器将其与场景混合。这是金属的相同设置

金属小发明

#include <metal_stdlib>
using namespace metal;

#include <SceneKit/scn_metal>

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

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

vertex out_vertex_t gizmo_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);

    return out;
};

constexpr sampler s = sampler(coord::normalized,
                              r_address::clamp_to_edge,
                              t_address::repeat,
                              filter::linear);

fragment half4 gizmo_fragment(out_vertex_t vert [[stage_in]],
                              texture2d<float, access::sample> totalSampler [[texture(0)]],
                              texture2d<float, access::sample> gizmoSampler [[texture(1)]])
{

    float4 t0 = totalSampler.sample(s, vert.uv);
    float4 t1 = gizmoSampler.sample(s, vert.uv);

    return half4((1.0 - t1.a) * t0 + t1.a * t1);
}
#包括
使用金属;
#包括
结构自定义顶点
{
float4位置[[属性(SCNVertexSemanticPosition)];
float4 normal[[属性(SCNVertexSemanticNormal)];
};
构造出顶点
{
浮动4位[[位]];
2紫外线;
};
顶点输出顶点小控件顶点(自定义顶点输入[[阶段输入])
{
out\u vertex\u t out;
out.position=in.position;
out.uv=float2((in.position.x+1.0)*0.5,(in.position.y+1.0)*-0.5);
返回;
};
constexpr采样器s=采样器(坐标::标准化,
r_地址::将_夹紧到_边缘,
地址::重复,
滤波器(线性);
fragment half4 gizmo_fragment(外顶点[stage_in]],
texture2d totalSampler[[纹理(0)],
纹理2D gizmoSampler[[纹理(1)])
{
float4 t0=总取样器样品(s,垂直uv);
float4 t1=gizmoSampler.样品(s,垂直uv);
返回半4((1.0-t1.a)*t0+t1.a*t1);
}
GizmoTechnique.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>pass_scene</key>
        <dict>
            <key>draw</key>
            <string>DRAW_SCENE</string>
            <key>inputs</key>
            <dict/>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>color_scene</string>
            </dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
                <key>clearColor</key>
                <string>sceneBackground</string>
            </dict>
        </dict>
        <key>pass_gizmo</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
                <key>clearColor</key>
                <string>0 0 0 0</string>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>outputs</key>
            <dict>
                <key>color</key>
                <string>color_gizmo</string>
            </dict>
            <key>inputs</key>
            <dict/>
            <key>draw</key>
            <string>DRAW_NODE</string>
            <key>node</key>
            <string>transformGizmo</string>
        </dict>
        <key>mix</key>
        <dict>
            <key>colorStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>depthStates</key>
            <dict>
                <key>clear</key>
                <true/>
            </dict>
            <key>inputs</key>
            <dict>
                <key>totalSampler</key>
                <string>COLOR</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_gizmo</string>
        <string>mix</string>
    </array>
    <key>targets</key>
    <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>

通行证
路过现场
画
绘制场景
投入
输出
颜色
彩色场景
色态
清楚的
透明色
场景背景
传递小发明
色态