Проблема с добавлением тени к SCNPlane с чистым фоном - PullRequest
2 голосов
/ 08 мая 2020

Я пытаюсь добавить тень на SCNPlane, все работает нормально, но я не могу сделать SCNPlane прозрачным, чтобы отображалась только тень, а не белый фон. вот код:

        let flourPlane = SCNPlane()
        let groundPlane = SCNNode()


        let clearMaterial = SCNMaterial()
        clearMaterial.lightingModel = .constant
        //clearMaterial.colorBufferWriteMask = []
        clearMaterial.writesToDepthBuffer = true
        clearMaterial.transparencyMode = .default

        flourPlane.materials = [clearMaterial]

        groundPlane.scale = SCNVector3(200, 200, 200)
        groundPlane.geometry = flourPlane
        groundPlane.castsShadow = false
        groundPlane.eulerAngles = SCNVector3Make(-Float.pi/2, 0, 0)
        groundPlane.position = SCNVector3(x: 0.0, y: shadowY, z: 0.0)
        node.addChildNode(groundPlane)

        // Create a ambient light
        let ambientLight = SCNNode()
        ambientLight.light = SCNLight()
        ambientLight.light?.shadowMode = .deferred
        ambientLight.light?.color = UIColor.white
        ambientLight.light?.type = SCNLight.LightType.ambient
        ambientLight.position = SCNVector3(x: 0,y: 5,z: 0)

        // Create a directional light node with shadow
         let myNode = SCNNode()
        myNode.light = SCNLight()
        myNode.light?.type = .directional
        myNode.light?.castsShadow = true
        myNode.light?.automaticallyAdjustsShadowProjection = true
        myNode.light?.shadowSampleCount = 80
        myNode.light?.shadowBias = 1
        myNode.light?.orthographicScale = 1
        myNode.light?.shadowMode = .deferred
        myNode.light?.shadowMapSize = CGSize(width: 2048, height: 2048)
        myNode.light?.shadowColor = UIColor.black.withAlphaComponent(0.5)
        myNode.light?.shadowRadius = 10.0
        myNode.eulerAngles = SCNVector3Make(-Float.pi/2, 0, 0)
        node.addChildNode(ambientLight)
        node.addChildNode(myNode)

Когда я добавляю clearMaterial.colorBufferWriteMask = [] тень исчезает! как создать прозрачный материал, чтобы отображалась только тень.

enter image description here

Белая область - это плоскость SCN, а красная - фон.

Ответы [ 2 ]

0 голосов
/ 13 мая 2020

Я обнаружил трюк в другом ответе SO .

Отрегулируйте blendMode плоскости пола, чтобы изменить то, как его пиксели сочетаются с нижележащими пикселями.

let clearMaterial = SCNMaterial()
// alter how pixels affect underlying pixels
clearMaterial.blendMode = .multiply
// use the simplest shading that shows a shadow (so not .constant!)
clearMaterial.lightingModel = .lambert
// unobstructed parts are render pure white and thus have no effect
clearMaterial.diffuse.contents = UIColor.white

floorPlane.firstMaterial = clearMaterial

Вы можете увидеть эффект на этом изображении. Основная плоскость невидима, но тень видна. Куб, его тень и сетка шара имеют одинаковое положение XZ. Обратите внимание, как «тень» влияет на базовую геометрию и фон сцены.

Sample render of invisible plane with shadow

0 голосов
/ 11 мая 2020

Вы можете установить "цвет" материалов на .clear, как показано ниже:

extension SCNMaterial {
convenience init(color: UIColor) {
    self.init()
    diffuse.contents = color
}
convenience init(image: UIImage) {
    self.init()
    diffuse.contents = image
}
}

let clearColor = SCNMaterial(color: .clear)
flourPlane.materials = [clearColor]
...