所以我在SceneKit中有这些场景,我以编程方式创建了一堆不同高度的对象.他们中的大多数是简单的盒子,但其中一些是挤压路径.
我需要能够为它们添加一种简单的材料颜色,使颜色从较暗的值变为从底部到顶部的较浅的颜色.
我一直试图通过创建一个具有渐变图像纹理的材质来实现这一目标CAGradientLayer
.这"几乎"有效.这种方法的问题是对象的所有面都会得到相同的效果,这不是我想要的.物体的顶部和底部表面应为纯色 - 顶部表面的浅色和底部的浅色.
我一直在使用着色器,但结果是一个相对于屏幕而不是我的对象的渐变,从而将我的3D对象渲染为2D.
这是我如何创建一个简单的纯色框,例如:
func createBox(with bounds: CGRect, and height: CGFloat) { let material = SCNMaterial() material.diffuse.contents = UIColor.white if #available(iOS 10.0, *) { material.lightingModel = .physicallyBased material.metalness.contents = 0.2 material.roughness.contents = 0.5 } let geometry = SCNBox(width: bounds.size.width, height: height, length: bounds.size.height, chamferRadius: 0.0) geometry.materials = [material] geometry.chamferRadius = 0.02 let node = NKNode(geometry: geometry) }
现在,由于一个盒子默认有6个不同的几何元素,我可以选择创建一个材料,将其内容设置为渐变图像,然后在该materials
数组中添加所述材质6次geometry
.这允许我单独为每个面设置材质,如下所示:
let material = SCNMaterial() material.diffuse.contents = UIImage(named: "gradient-test") geometry.materials = [material, material, material, material, material, material]
有了这个,我可以有3种不同的材料(侧面,顶部,底部),并通过反复试验在materials
阵列中以正确的顺序添加它们.这将转化为:
let sideMaterial = SCNMaterial() sideMaterial.diffuse.contents = UIImage(named: "gradient") let topMaterial = SCNMaterial() topMaterial.diffuse.contents = UIColor.white let bottomMaterial = SCNMaterial() bottomMaterial.diffuse.contents = UIColor.black // The order is side, side, side, side, top, bottom geometry.materials = [sideMaterial, sideMaterial, sideMaterial, sideMaterial, topMaterial, bottomMaterial]
但是当我的对象不是一个简单的盒子而是一个挤出的路径时,我的问题出现了.以下是创建它们的方式:
func createFromPath(_ path: UIBezierPath, with height: CGFloat) { let material = SCNMaterial() material.diffuse.contents = UIColor.white if #available(iOS 10.0, *) { material.lightingModel = .physicallyBased material.metalness.contents = 0.2 material.roughness.contents = 0.5 } material.isDoubleSided = true let geometry = SCNShape(path: path, extrusionDepth: height) geometry.materials = [material] geometry.chamferRadius = 0.02 }
如您所见,简单的纯色很容易.但是应用相同的逻辑在侧面添加渐变纹理不再起作用,因为我的路径可能有不确定数量的面.说实话,我甚至认为像这样创建的几何体不像简单的盒子那样被分成多个"元素".
所以,任何想法我怎么能达到我想要的?
这是我想要实现的一个非常基本的例子.如您所见,此地图中的3D"建筑物"具有微妙的从底部到顶部的渐变.