我能否使用SceneKit和ARKit制作一个可以透过透明物体看到阴影的效果?

5
我使用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!)

我认为可以通过简单的属性来解决,但我想不出来。

我该如何解决这个问题?


在所涉及的节点中是否有“Alpha”设置(您想要使其透明)?如果是这样,请将其更改为“0.5”,以达到50%的透明度。 - Voltaire's Ghost
当然它具有透明度 alpha 值(可能为 0.2)。但是虽然它有 alpha,但阴影无法穿过透明的物体看到。 - Jun
1个回答

4
延迟着色的已知问题是它不适用于透明度,因此您可能需要删除该行并再次使用默认的正向着色。尽管如此,您要查找的“简单属性”是SCNNode上的.renderingOrder属性。例如,将其设置为99。通常情况下,渲染顺序并不重要,因为z缓冲区用于确定哪个像素在其他像素之前。为了通过对象的透明部分显示阴影,您需要确保该对象最后被渲染。

enter image description here

另外,假设您在其他问题中使用了我发布的一些材质设置,请尝试将光泽度值设为0.4。
请注意,这仍会创建一个阴影,就好像对象根本不透明,因此它不会为标签和盖子创建更暗的阴影。为了增加真实感,您可以选择完全伪造阴影,例如使用纹理来制作阴影并将其放置在平面上,然后根据需要旋转和扭曲该平面。为了增加真实感,您也可以通过这种方式伪造焦散。
您还可以将反射映射添加到材料的反射属性中。几乎与纹理映射相同,但是以灰度形式呈现,其中标签和盖子为深灰色(不太反射),玻璃部分为浅灰色(否则它看起来像标签在玻璃内部)。最后一个提示:使用Shell修饰符(无论如何,在3Ds max中都是这样称呼它)为玻璃模型增加一些厚度。

当我将阴影模式改为前向时,阴影就消失了。当我在地板材质中删除colorWriteMask属性时,我可以通过瓶子看到阴影,但是我无法看到真实环境。我发布了制作地板的代码。无论如何,非常感谢!@Xartec。我想听听你的解决方案。 - Jun
你尝试过使用renderingOrder=99和.deferred shading一起吗?(只是为了确认它不起作用)。 - Xartec
是的,我试过了,但在那种情况下无法通过物体看到阴影。我认为更改应该在scnfloor中进行。 - Jun
我同意,我认为你将不得不使用另一种方法来混合地板。然而,我不认为这将是另一个简单属性更改的问题。在延迟着色中,阴影是在后处理中添加的,而不是在绘制透明对象时添加的。在正向着色和颜色位掩码中,首先丢弃地板的像素,没有留下任何东西来绘制阴影。 - Xartec
我认为你可能需要采用SCNTechnique方法并自己渲染多个通道。例如,在单独的通道中绘制启用了投射阴影和透明度接近零(0.01即可将节点几乎隐藏,但仍然投射完整阴影)的节点副本。然后再渲染另一个通道,其中对象完全不透明且没有投射阴影。 - Xartec
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接