SceneKit - примененный CIFilter на SCNNode скрывает SCNTorus

У меня есть следующая настройка узла на моей сцене: Контейнерный узел с дочерними узлами: земля, тор и луна. Я применил к свойству фильтра земного узла следующий пользовательский 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, который накладывает измененное изображение поверх оригинала. Но почему тор спрятан, а луна нет? Я добавил материал тора в луну. материальная собственность, чтобы увидеть, если что-то не так с материалом. Но все равно, луна видна, тор спрятан. Луна вращается с helperNode как дочерний элемент к containerNode.

Луна видна, а тора нет Тора не видна за этим прямоугольником омниния

дерева сцены

2 ответа

Решение

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

РЕШЕНИЕ 1.

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

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

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

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

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

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

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

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

РЕШЕНИЕ 2.

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

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

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

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

self.torus.firstMaterial?.writesToDepthBuffer = false

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

Другие вопросы по тегам