Как объяснялось в моем предыдущем ответе, принятый ответ не является оптимальным и работает правильно только для рекламных щитов, хаусов и других вообще плоских объектов (не обязательно полностью 2D). При использовании 3D-объектов и отключении чтения из буфера глубины и объектов, подобных изображению выше, оно не будет отображаться правильно со всех сторон. Я.e 3D-объект нуждается в для чтения из буфера глубины для определения собственных пикселей и глубины. Это все сказанное, я представляю правильный ответ:
SCNTechnique
Короче говоря, делают 2 дополнительных проходов. Один для контрольной гизмо (DRAW_NODE) и один для смешивания вместе со сценой другим проходом (DRAW_QUAD с шейдером, который использует предыдущие проходы в качестве входов).
Ниже scntec.plist содержимое techique в:
<?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;
}
Быстрый код:
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;
Установить имя узла гизмо:
theGizmo.name = @"movegizmo";
Это соответствует [документации Apple] (https://developer.apple.com/library/prerelease/ios/documentation/SceneKit/Reference/SCNMaterial_Class/index.html#//apple_ref/occ/instp/ SCNMaterial/writeToDepthBuffer) для 'writeToDepthBuffer' и' readsFromDepthBuffer'. Основной вариант использования 'writeToDepthBuffer', по-видимому, предназначен для обработки прозрачности. Я обнаружил, что объект с прозрачностью может привести к тому, что объекты за ним исчезнут с некоторых углов, если для параметра 'writeToDepthBuffer' установлено значение false для SCNMaterial прозрачного объекта. Даже тогда я видел несколько сбоев, но это определенно помогло. –
Возможно, это немного походит на тему, чтобы добавить к моему предыдущему комментарию, но оказывается, что установка 'renderingOrder' в -1 на моем прозрачном объекте фиксирует оставшиеся проблемы с рендерингом. –
Это немного бессмысленно для меня, я имею в виду, что документация предполагает, что просто установка «renderOrder» объекта на большее число и объединение его с правильной настройкой буфера глубины будет работать, но, по-видимому, объект с набором свойств 'readFromDepthBuffer' своего материала false будет только перед другими объектами, если указанные объекты имеют отрицательный 'renderOrder'. –