>通过SCNMaterial使用UIColor的alpha通道.(diffuse | emission | ambient | …).contents
>使用SCNMaterial.transparency(从0.0到1.0的CGFloat)
>使用SCNMaterial.transparent(另一个SCNMaterialProperty)
>使用SCNNode.opacity(从0.0(完全透明)到1.0(完全不透明)的CGFloat)
问题:
>某处有颜色数学的详细描述吗?
>添加透明度的常用方法是什么(每个对象,而不是纹理/每个顶点)?
> SCNMaterial.transparent如何与其他颜色通道(如漫反射)进行交互?
>是否必须按照https://stackoverflow.com/a/30195543/278842中的建议对alpha通道进行预乘?
解决方法
漫反射Alpha通道
有时可以使用带有漫反射纹理的简单网格,而不是使用具有大量顶点的网格,请参阅下面的示例.
SCNMaterial.transparency
均匀调整整个材质的不透明度.此属性是可动画的.
SCNMaterial.transparent
您可以单独设置每个点的不透明度,而不是为整个材质设置透明度值,通常使用纹理.
SCNNode.opacity
设置整个节点和任何子节点的不透明度.
甚至可以控制更多:
SCNMaterial.transparencyMode
使用材质的transparencyMode,您可以使用不同的模式:.aOne使用alpha通道,.rgbZero根据颜色亮度确定透明度.
颜色数学
颜色数学由混合模式决定,如下所述:
https://developer.apple.com/documentation/scenekit/scnblendmode
case alpha
Blend by multiplying source and destination color
values by their corresponding alpha values.case add
Blend by adding the source color to the destination color.
case subtract
Blend by subtracting the source color from the destination color.
case multiply
Blend by multiplying the source color with the background color.
case screen
Blend by multiplying the inverse of the source color with the inverse of the destination color.
case replace
Blend by replacing the destination color with the source color,
ignoring alpha.
例子
树木/树叶
代替使用具有大量顶点的网格,这将导致帧速率的显着或甚至不可接受的降低,通常可以使用透明的漫射纹理.一个很好的例子是例如树木和树叶.
在这里你可以看到一个透明纹理,中间是一个带有几个简单平面的网格,右边是SceneKit渲染时的样子(网格和纹理取自http://www.loopix-project.com).
let mat = SCNMaterial() mat.diffuse.contents = "palms1.png" if let geometry = palm.geometry { geometry.materials = [mat] }
发光效果
对于不同的效果,可以使用混合模式,例如,要获得一种发光效果,可以使用blendMode .add:
mat.blendMode = .add
淡入淡出
SCNNode.opacity是指包含所有子节点的节点.此属性是可动画的,因此如果要淡入或淡出节点(或一组节点),这是正确的方法.
您还可以使用它来为每个对象应用透明度.
预乘alpha与直alpha
内部SceneKit使用预乘alpha.因此,如果您正在编写着色器,您应该知道这一点.
如果您只是在API级别工作,则不会受到影响,例如:如果你加载一个透明的a.png文件,你不需要做任何事情来自己预乘RGB.
例如,SCNMaterial.transparent与其他渠道
透明胶片必须能够在不同的使用场景下一起使用.例如,您希望淡出具有已部分透明区域的对象.
人工演示示例
>具有一些已经透明区域的噪声纹理的球体
>使用材料alpha .75显示球体
>添加第二个球体进行比较
设置:
let sphere1 = SCNSphere(radius: 0.5) let material1 = SCNMaterial() material1.diffuse.contents = "art.scnassets/colorTex.png" material1.transparent.contents = UIColor(red: 1,green: 1,blue: 1,alpha: 0.75) sphere1.materials = [material1] let sphereNode1 = SCNNode(geometry: sphere1) sphereNode1.position = SCNVector3(x: 0,y: -2,z: 0) let sphere2 = SCNSphere(radius: 0.25) let sphereNode2 = SCNNode(geometry: sphere2) sphereNode2.position = SCNVector3(x: 0,y: -0.5,z: 0) let spheres = SCNNode() spheres.addChildNode(sphereNode1) spheres.addChildNode(sphereNode2) self.scnScene.rootNode.addChildNode(spheres)
现在通过SCNNode.opacity应用淡出:
let fadeOut = SCNAction.customAction(duration: 5) { (node,elapsedTime) -> () in node.opacity = 1 - elapsedTime / 5 } DispatchQueue.main.asyncAfter(deadline: .now() + 1) { spheres.runAction(fadeOut) }
结果如下: