在 SceneKit 中,如何在不同大小的对象上平铺纹理,同时保持最小的绘制调用?
Posted
技术标签:
【中文标题】在 SceneKit 中,如何在不同大小的对象上平铺纹理,同时保持最小的绘制调用?【英文标题】:In SceneKit, how can one tile a texture on differently sized objects while keeping draw calls minimal? 【发布时间】:2021-01-23 16:42:00 【问题描述】:为了提高 SceneKit 场景中的性能/fps,我想尽量减少绘制调用的数量。场景包含一个程序生成的城市,我为它生成随机高度的房屋(每个都是一个 SCNBox),并用一个相同的重复立面纹理平铺它们,如下所示:
应用纹理的正确方法如下:
let material = SCNMaterial()
material.diffuse.contents = image
material.diffuse.wrapS = SCNWrapMode.repeat
material.diffuse.wrapT = SCNWrapMode.repeat
buildingGeometry.firstMaterial = material
这行得通。但正如所写,它会拉伸材料以适应盒子表面的大小。要调整纹理大小以保持纵横比,需要添加以下代码:
material.diffuse.contentsTransform = SCNMatrix4MakeScale(sx, sy, sz)
其中sx
、sy
和sz
是从几何中的面大小得出的适当比例因子。这也有效。
但是后一种方法意味着每个节点都需要自定义材质,这反过来意味着我不能为所有房屋重复使用单一材质,这反过来意味着每个节点都需要额外的绘图调用。
有没有办法使用单一纹理材质来平铺所有房屋(不拉伸纹理)?
【问题讨论】:
【参考方案1】:使用表面着色器修改器 (SCNShaderModifierEntryPointSurface
),您可以根据 scn_node.boundingBox
修改 _surface.diffuseTexcoord
。
由于边界框是动态馈送到着色器的,所有对象都将使用相同的着色器,并将受益于实例化(减少绘制调用的数量)。
SCNShadable.h 头文件对此有更多详细信息。
【讨论】:
嗨@mnuages,也想试试这个其他的SceneKit 问题吗? ***.com/questions/59670506/… 我悬赏了。 :-)以上是关于在 SceneKit 中,如何在不同大小的对象上平铺纹理,同时保持最小的绘制调用?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Xcode 10 在 SceneKit 编辑器中旋转对象
如何在 iOS SceneKit 中使用具有不同场景图形的 DAE 文件
如何访问从 Firebase 下载的 SceneKit 文件?