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.