我可以使用scenekit和arkit制作透过透明对象的阴影吗?

时间:2017-10-16 13:18:10

标签: ios swift scenekit arkit

我使用scenekit创建透明对象并与arkit链接。 我用闪电材料制作了一个阴影,但透过透明物体无法看到阴影。 我做了一架飞机并将物体放在上面。 并将光线照射到透明物体上。 阴影出现在对象后面,但无法透过对象看到。

enter image description here

这是制作阴影的代码。

          let light = SCNLight()
          light.type = .directional
          light.castsShadow = true
          light.shadowRadius = 200
          light.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3)
          light.shadowMode = .deferred
          let constraint = SCNLookAtConstraint(target: model)
          lightNode = SCNNode()
          lightNode!.light = light
          lightNode!.position = SCNVector3(model.position.x + 10, model.position.y + 30, model.position.z+30)
          lightNode!.eulerAngles = SCNVector3(45.0, 0, 0)
          lightNode!.constraints = [constraint]
          sceneView.scene.rootNode.addChildNode(lightNode!)

以下代码用于在瓶子下面铺地板。

 let floor = SCNFloor()
 floor.reflectivity = 0
 let material = SCNMaterial()
 material.diffuse.contents = UIColor.white
 material.colorBufferWriteMask = SCNColorMask(rawValue:0)
 floor.materials = [material]
 self.floorNode = SCNNode(geometry: floor)
 self.floorNode!.position = SCNVector3(x, y, z)
 self.sceneView.scene.rootNode.addChildNode(self.floorNode!)

我认为它可以通过简单的属性来解决,但我无法弄明白。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

延迟着色的一个已知问题是它无法使用透明度,因此您可能必须删除该行并再次使用默认的前向着色。也就是说,您正在寻找的“简单属性”是SCNNode上的.renderingOrder属性。例如,将其设置为99。通常,渲染顺序无关紧要,因为z缓冲区用于确定哪些像素位于其他像素之前。要通过对象的透明部分显示阴影,您需要确保最后渲染对象。

enter image description here

另一方面,假设您使用了我在其他问题上发布的一些材料设置,请尝试将光泽值设置为0.4。

请注意,这仍会产生阴影,就像对象根本不透明一样,因此不会为标签和上限创建更暗的阴影。为了获得额外的真实感,您可以选择完全伪造阴影,例如使用阴影纹理并将其放置在您根据需要旋转和倾斜的平面上。为了更加真实,你也可以用这种方式来伪装焦散。

您可能还想将反射贴图添加到材质的反射属性中。几乎与纹理贴图相同,但是在灰度级中,标签和帽子是深灰色(不是非常反光),而玻璃部分是浅灰色(否则它看起来像标签在玻璃内部)。最后提示:使用Shell修改器(无论如何都是在3Ds max中调用它)来为玻璃模型提供一些厚度。