SceneKit - примененный CIFilter на SCNNode скрывает SCNTorus - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть следующая настройка узла на моей сцене: Контейнерный узел с дочерними узлами: земля, тор и луна. Я применил к свойству фильтра земного узла следующий пользовательский HighlightFilter с фильтром CIBloom и CISourceOverCompositing для эффекта свечения:

Класс CIFilter (код из потрясающего блога: Подсветка SCNNode с Glow )

class HighlightFilter: CIFilter {

static let filterName = "highlightFilter"

@objc dynamic var inputImage: CIImage?
@objc dynamic var inputIntensity: NSNumber?
@objc dynamic var inputRadius: NSNumber?

override var outputImage: CIImage? {
    guard let inputImage = inputImage else {
        return nil
    }

    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(inputImage, forKey: kCIInputImageKey)
    bloomFilter.setValue(inputIntensity, forKey: "inputIntensity")
    bloomFilter.setValue(inputRadius, forKey: "inputRadius")

    let sourceOverCompositing = CIFilter(name:"CISourceOverCompositing")!
    sourceOverCompositing.setValue(inputImage, forKey: "inputImage")
    sourceOverCompositing.setValue(bloomFilter.outputImage, forKey: "inputBackgroundImage")

    return sourceOverCompositing.outputImage
}}

Я не понимаю этот невидимый прямоугольник. Я предполагаю, что это из-за CIFilter SourceOverCompositing, который накладывает измененное изображение поверх оригинала. Но почему тор спрятан, а луна нет? Я добавил материал тора в луну. материальная собственность, чтобы увидеть, если что-то не так с материалом. Но все равно, луна видна, тор спрятан. Луна вращается с узлом-помощником как дочерний элемент к узлу-контейнеру.

Moon is in visible, but torus not Torus is not visible behind this omninius rectangle

Scenegraph enter image description here

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Я не знаю точно, почему произошло это странное поведение, но удаление следующей строки заставило его исчезнуть.

self.torus.firstMaterial? .WritesToDepthBuffer = false

Свойство writeToDepthBuffer для материала на торе было установлено в значение false.

0 голосов
/ 03 ноября 2018

Это может произойти из-за двух потенциальных проблем.

РЕШЕНИЕ 1 .

Когда вы используете CISourceOverCompositing, вам нужно предварительно умноженное изображение RGBA (RGB * A) для переднего плана, где альфа-канал имеет той же формы , что и Земля (изображение слева). Но у вас есть альфа-канал, покрывающий все изображение (правая картинка).

Если вы хотите знать, какова форма альфа-канала на вашем изображении Земли - используйте одно из следующих приложений для композитинга: The Foundry Nuke, Adobe After Effect, Apple Motion, Blackmagic Fusion и т. Д.

Также, если вы хотите объединить Луну и Землю по отдельности, вы должны иметь их как два разных изображения.

enter image description here

В классическом композитинге OVER операция имеет следующую формулу:

(RGB_image1 * A_image1) + (RGB_image2 * (1 – A_image1))

Первая часть этой формулы - это предварительно умноженное изображение переднего плана (Земля) - RGB1 * A1.

Вторая часть этой формулы - это фоновое изображение с отверстием - RGB2 * inverted_A1. Вы получили инверсию альфа-канала, используя (1-A). Само фоновое изображение может иметь только три компонента - RGB (без A).

Затем вы добавляете два изображения вместе, используя простую операцию сложения. Если у вас есть несколько OVER операций - порядок этих операций имеет решающее значение.

enter image description here

РЕШЕНИЕ 2 .

Это может быть связано с Depth Buffer. Отключить writesToDepthBuffer свойство экземпляра. Это логическое значение, которое определяет, будет ли SceneKit генерировать информацию о глубине при рендеринге материала.

yourTorusNode.geometry?.materials.first?.writesToDepthBuffer = false

enter image description here

Надеюсь, это поможет.

...