콘텐츠로 건너뛰기

Difference between Texture Array and Texture Atlas (simplified version)

在Unity 做Rendering相关优化时不得不使用TextureArray 。这是因为Unity里为了减少 DrawCall 而使用的 Batching。简单来说新画的material和Mesh种类越多,DrawCall 就会越多。但是 DrawCall 不便宜,会消耗很大的CPU性能。所以Unity 会自动进行 Batching 。使用同样的material就会自动捆绑,使用同样的Mesh也会自动捆绑。所以 Batching 跟 DrawCall 次数是一样的概念。

为了减少 Batching 的次数,减少material的方法对应的就是 TextureArray 。比这个还常用的方法是 TexutreAtlas ,但这种方法很单纯。在一张贴图上添加所有图片,修改UV的时候才会用。一般是在UI 图片上设置Sprite的时候会用到, Unity有一种把 Sprite合并在UGUI 功能上做成 TextureAtlas 的功能。但是3D 物体的UV 就不一样了。UV 坐标是 0和 1之间的值组成的,如果想把很多张贴图设置在一起的UV坐标合并在一起重新设置的话会非常麻烦。如果合并前的贴图在合并后又增加的话就更麻烦了。这样最终就成了生产效率的问题,所以会用其他方法,而这个方法就是 TextureArray 。

TextureArray的概念很简单,是把贴图按列进行捆绑,只要有Index就可以一个个参考使用。就是说跟UV的2D坐标一起,再有一个Index就可以。TextureArray的优点是,不会跟TextureAtlas一样需要一直合并和修改UV,只要根据 Mesh设置Index就可以很容易操作。而且不管贴图的数量是多少, material 可以维持一个的状态所以很便捷。但是要用在Unity有几个缺点。因为不支持Asset生成,所以很麻烦,显示的GUI在Unity内部也是不支持的。为了使用起来方便,需要亲自编辑代码。当然直接生成也没关系,但考虑生产效率的问题就不是很好了。而且Shader代码也要亲自替换,有很多需要设置的地方。所以很贵。

现在适用到 Unity 里看下。

需要做的有三件事。

  • 把Mesh 里的简单的2D UV坐标 换成持有(UV + Texture Index)坐标的3D坐标。
  • 生成TextureArray并适用
  • 在Shader 代码里使用TextureArray ,把 UV 坐标换成3D坐标。

*有关例子做好附上了,想参考的人请看下。

替换UV坐标根据情况不同,一般是设置成了2D UV坐标,只考虑程序的合并工作的话,添加可以给每个Mesh插入相应的Texture Index的component比较好。 只在刚开始的时候修改UV 信息就可以了,所以除了加载时间变长和占用更多的GPU 容量外,没有其他问题。担心初期的加载时间的话,添加在编辑器就可以了。参考例子里因为是刚开始的时候全部生成,所以把储存成 Vector2 的 UV坐标换成Vector3 ,插入了Texture Index。

TextureArray部分的操作最复杂。在component动态生成是最好的,但这种方法每次都要修改component所以更复杂。所以看参考例子就能知道,做了简单的做好lapping的assets。但还有一点很复杂, 生成后不能在编辑器里修改贴图数量和其他一些东西,所以几种条件中有一条出问题就要重新生成。这样和material的连接就会断了,,这是非常头疼的问题。

태그:

댓글 남기기

%d 블로거가 이것을 좋아합니다: