我目前正在尝试在场景套件中设置旋转球。我创建了球并为其应用了纹理。
ballMaterial.diffuse.contents = UIImage(named: ballTexture)
ballMaterial.doubleSided = true
ballGeometry.materials = [ballMaterial]
当前的ballTexture是半透明的纹理,因为我希望看到背面滚动。
但是,我得到了一些奇怪的剔除,即使将doubleSided属性设置为true,也只显示了一半的背面多边形。
任何帮助,将不胜感激,谢谢。
最佳答案
发生这种情况是因为透明度的影响取决于绘制顺序。 SceneKit不知道在前向多边形之前绘制球体的后向多边形。 (实际上,如果不为每一帧重新组织GPU上的顶点缓冲区,就无法做到这一点,这将极大地影响渲染性能。)SCNSphere
的顶点布局设置得像地球上的经/纬网格:三角形沿子午线从0°到360°依次渲染,因此取决于球体相对于相机的方向,有些球体远侧的面中的一部分将在较近的面之前渲染。
要解决此问题,您需要直接或通过深度缓冲区强制渲染顺序。这是一种实现方法,对内表面使用单独的材料来说明差异。
// add two balls, one a child of the other
let node = SCNNode(geometry: SCNSphere(radius: 1))
let node2 = SCNNode(geometry: SCNSphere(radius: 1))
scene.rootNode.addChildNode(node)
node.addChildNode(node2)
// cull back-facing polygons on the first ball
// so we only see the outside
let mat1 = node.geometry!.firstMaterial!
mat1.cullMode = .Back
mat1.transparent.contents = bwCheckers
// my "bwCheckers" uses black for transparent, white for opaque
mat1.transparencyMode = .RGBZero
// cull front-facing polygons on the second ball
// so we only see the inside
let mat2 = node2.geometry!.firstMaterial!
mat2.cullMode = .Front
mat2.diffuse.contents = rgCheckers
// sphere normals face outward, so to make the inside respond
// to lighting, we need to invert them
let shader = "_geometry.normal *= -1.0;"
mat2.shaderModifiers = [SCNShaderModifierEntryPointGeometry: shader]
(不需要最后的shader修改器位,它只是使内部材质具有漫反射阴影。您也可以使用不涉及法线或光照的材质属性,例如
emission
,具体取决于您想要的外观)您也可以通过禁用
writesToDepthBuffer
来使用带有双面材质的单个节点来执行此操作,但这也可能导致与其余场景内容发生不必要的交互-在这种情况下,您可能还需要弄乱 renderingOrder
。