正如我在之前的回答中所解释的那样,接受的答案并不是最佳的,并且仅适用于广告牌、hud 和其他通常平坦的物体(不一定完全是 2D)。当使用 3D 对象并禁用从深度缓冲区和上图中的对象读取时,它不会从每个角度正确渲染。即一个 3D 对象需要从深度缓冲区中读取来检测它自己的像素和深度。综上所述,我给出了正确的答案:
SCN技术
简而言之,渲染 2 个额外的通道。一个用于控制 Gizmo (DRAW_NODE),另一个通过另一个通道 (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
}
}
Objective-C 代码:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"scntec" withExtension:@"plist"];
SCNTechnique *technique = [SCNTechnique techniqueWithDictionary:[NSDictionary dictionaryWithContentsOfURL:url]];
self.myView.technique = technique;
设置 Gizmo 节点的名称:
theGizmo.name = @"movegizmo";