使用SCNNode作为渲染“遮罩”?

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

是否可以使节点呈现“清晰”,以便在绘制 in 时,场景视图下方的任何视图都显示在通常显示该节点的位置?

例如,假设我们的SCNView后面有一个红色的UIView。以球体为例,您会在场景视图中看到一个圆形“洞”,红色视图将通过该洞显示出来。

有什么想法吗?这会涉及某种着色器吗?

ios shader scenekit
1个回答
-1
投票

如果您完全在 SceneKit/Metal 上下文中尝试此操作,我可以为您提供着色器可能是什么样子的基本概念。请注意,这是一个简化的示例,实际实现可能会根据您的具体要求和应用程序上下文而有很大差异。

您需要在 .metal 文件中设置一个金属着色器,如下所示:

#include <metal_stdlib>
using namespace metal;

struct NodeVertex
{
    float4 position [[position]];
};

vertex NodeVertex vertex_main(constant packed_float4 * vertex_array [[buffer(0)]], unsigned int vid [[vertex_id]])
{
    NodeVertex out;
    out.position = vertex_array[vid];
    return out;
}

fragment float4 fragment_mask()
{
    return float4(1, 1, 1, 0);
}
#include <metal_stdlib>
using namespace metal;

struct NodeVertex
{
    float4 position [[position]];
};

vertex NodeVertex vertex_main(constant packed_float4 * vertex_array [[buffer(0)]], unsigned int vid [[vertex_id]])
{
    NodeVertex out;
    out.position = vertex_array[vid];
    return out;
}

fragment float4 fragment_mask()
{
    return float4(1, 1, 1, 0);
}

上面的着色器创建了一个不可见的球体,用作“遮罩”。

然后,您需要创建一个SCNProgram并将其设置到您的球体节点:

let program = SCNProgram()
program.vertexFunctionName = "vertex_main"
program.fragmentFunctionName = "fragment_mask"

let sphere = SCNSphere(radius: 1.0)
let node = SCNNode(geometry: sphere)
node.geometry?.program = program

此着色器程序会将您的球体渲染为完全透明,使其在场景中显示为“洞”。

但是请记住,由于 iOS 中渲染的分层方式,这个“洞”不会显示放置在 SceneKit 视图后面的 UIKit 元素。要真正看到这个“洞”后面的内容,该内容必须是 3D 场景本身的一部分,例如 SCNScene 中的另一个 SCNNode。

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