前言
上篇讲了文件夹结构,这篇呢我们来聊一聊3D模型的相关内容。
我们先来梳理下模型进入游戏的整个工作流程,然后再依次分析有哪些标准与规则。
- 美术在DCC(Digital Content Creation,数字内容创作,游戏行业中是指美术制作数字内容所使用的软件工具)软件中进行模型创作。
- 制作完成后,从DCC软件中导出FBX格式。
- 导入Unity引擎并设置导入的相关选项。
- 生成预设供程序使用。
从以上流程我们可以看出,游戏最终使用的是模型的Prefab(不用Prefab,直接上模型行不行?答
:可以,但是你一定会后悔的!),所以先与程序讨论确定Prefab是以什么样的内容给到程序的,比如层级结构、文件命名、组件都需要添加哪些等等,不过这块标准与模型本身的关系不是特别大,更多的是TA与程序间的标准确认,Prefab所引用的原始资源才是TA的重点关注对象,这其中又大多与性能优化息息相关,接下来详细说明这一块内容。
单位统一
在项目之初首先要定的就是模型单位,如果单位没有统一,那么在引擎中的比例就会不一致,这会给项目带来很多后续的烦恼。
以常用的Max为例,按下图中进行设置:
确定后我们会发现在状态栏显示Grid=0.1m,意思就是表示视图中的1个格子是0.1米的长度。
随后我们创建一个Cube,长宽高都为一米,然后导出为FBX,注意在导出弹窗中单位设置为自动,这样可以保证缩放系数是1,与当前Max中设置的一样。
然后将FBX再导入Unity中,先不做任何设置直接将其拖放到场景中,然后我们在Unity中同样创建一个Cube,缩放都为1。此时你会发现两个Cube大小是一样的,这样就保证了我们在Max中的单位与Unity中是相对一致的,为什么说是相对呢?
因为在Unity中其实是没有实际单位的,如果我们设置游戏内1米=1个单位的话,这恰恰与Unity内的物理系统所期望的正确结果保持统一,所以想要单位统一的话,只需按上面的进行设置即可。
方向
单位说完,我们再来说下方向,方向不统一的话会导致Prefab上的旋转值很混乱,这就会给程序带来诸多不便,所以不管如何我们有必要统一一下。
方向其实就是坐标轴,在定方向前我们先来了解下两个概念:
1.左手坐标系
左手的大拇指表示X轴正方向,食指表示Y轴的正方向,中指表示Z轴的正方向。
2.右手坐标系
右手的大拇指表示X轴正方向,食指表示Y轴的正方向,中指表示Z轴的正方向。
所以我们可以很容易的看出Max是右手坐标系,而Unity是左手坐标系,左手坐标系与右手坐标系是不能完美转换的,总是会有一个轴是反过来的。
所以还是先回到Unity中定下我们想要的是什么样的结果,首先我们在Unity中看到Y轴是朝上的,这就意味着如果是个人的模型的话,那么头顶上方的方向应该就是Y轴,如果不是Y轴那么人物就会出现方向错误。其次,哪个方向才是前方呢?Z轴正方向是前方,这点在Unity的官方文档中有说明,所以我们只需要定好这两个轴向就行了。
然后我们回到Max中,以一个茶壶为例,壶嘴表示前方,按以下步骤进行操作:
1.先将坐轴系设置为Local,我们只需关心模型的自身坐标轴。
2.在层级修改面板,点击Affect Pivot Only,旋转茶壶的坐标轴,将其调整为Y轴朝上,Z轴朝壶嘴方向。
3.退出修改,塌陷几何体,并导出。
4.导入Unity,直接将模型拖入场景并将其Roation全部归为0.
5.完成,这样方向既保证了正确性,Transform组件中的Roation也都是默认的0.
顶点数与面数
这点与优化息息相关,可能在有些同学眼里觉得只要控制好面数就行了,其实不然,顶点数也很关键,面数的规则反而简单,只要达到性能优化标准的同时满足美术效果就好了。
在渲染一个模型的时候,Shader层面会有两块计算量,一个是顶点着色器,一个片断着色器,顶点数越多,顶点着色器消耗就越大。
所我们重点来说下顶点数,首先在Max中创建一个Cube(长宽高段数都为1)并导入Unity中,然后与Unity中默认的Cube(Unity中创建的默认Cube)对比:
Max:顶点数8,面数12.
Unity:顶点数24,面数12.
面数是一致的,为什么顶点数却多了这么多呢?在回答这个问题之前,我们先来做几个小测试。
在Max中创建一个面片(Plane),只在长度上分为两段,如下图中所示,然后不做任何修改,直接导入Unity中,结果如下:
Max:顶点数6, 面数4.
Unity:顶点数6, 面数4.
这时发现面片在Max中与在Unity中的顶点数与面数都是一致的,好,那么接下来,我们回到max中,为刚才的面片添加Unwarp UVW修改器并将两个面的UV切开使其呈现下图中所示的效果,然后导入Unity中,得到如下数据:
Max:顶点数6, 面数4.
Unity:顶点数8, 面数4.
这时我们发现Unity中比Max中多了2个顶点,面数还是一致的,导致这个结果的原因就是因为我们将模型的UV切开了,由原来的6个UV点变成了8个UV点,而这恰恰与在Unity中显示的顶点数是一致的。我们现在再做另外一个测试,回到一开始的这个面片,不切开UV保持默认,但是我们把中间的线拉起来如下图所示的样子,并同时给两边的两个面分别不同的光滑组,然后导出到Unity中,结果如下:
Max:顶点数6, 面数4.
Unity:顶点数8, 面数4.
难道光滑组不一样也会增加顶点数吗?确实会,但也不全是,此时我们在Max中将上面拉起来的线放平(就是整个面片上的两个面都在同一平面),但是两个面的光滑组同样还是不一样,这时我们再导入Unity,结果如下:
Max:顶点数6, 面数4.
Unity:顶点数6, 面数4.
现在却又变成一样了,为什么呢?
通过以上几个小测试我们可以得出以下几个结论:
1.模型的UV顶点数增加会直接导致引擎中顶点数增加,这是因为同一个顶点被切成多个UV点时,在引擎中是会被认为是多个顶点的。
2.不同光滑组的面会导致它们的共用顶点属性信息不能共享,所以在引擎中也是会被认为成多个顶点的,但如果这些面虽然光滑组不一样,但是它们又实实在在的是在一个平面上的,只是被强制设置成光滑组不一致而已,这时引擎会自动优化,从而不会产生额外的顶点数。
3.如果某1个顶点,它既是多个UV点,也是两个不同光滑组的共用顶点,那么它在引擎中会是2个顶点,而不是4个。
4.Max与Unity显示的顶点数原理不一样,请以引擎为准。
好了,现在我们回到一开始的问题,为什么Cube在Unity中会有24个顶点呢?我相信你应该明白了吧,因为Cube有8个顶点,每个顶点会在UV中被分成3份,所以在引擎中就是8x3=24个顶点。
顶点属性
每个顶点上可以存储多个属性信息以便在引擎中可以去使用它做一些事情,我们先不管用它做什么,从模型上来讲,属性信息越少就代表着模型的容量越小,同时它所占用的内存也就越小。所以我们要明确模型应该带有什么属性,不需要的都要清除掉,保证美术资源只含有必须要的内容。
首先我们来看下在Unity中模型上可以认到属性有哪些:
顶点数、面数、UV1
顶点数与面数是模型的基本,所以没什么好说的,UV1也是不可缺少的属性,否则我们也没有办法让模型呈现我们的贴图。
UV2
如果是需要烘焙的模型,是必须要有UV2的,可以在Unity中自动生成,也可以在DCC软件中自行制作,如果不需要的话就要清除。
UV3
UV4
通常情况UV3和UV4都是用不到的属性,大多情况下要清除。
顶点色
用法较多,可通过顶点色实现很多功能,有需要用则保留,没有则清除。
法线
切线
法线与切线可在DCC中生成也可以在引擎中自动生成,根据需要进行设定。
需要注意的事,有些属性信息在引擎中是不能清除掉的(只能通过插件的形式去修改本地FBX文件的内容来实现),比如UV和顶点色,所以如果要清除只能通过回到DCC中清除完后再导回来,这也是前期定好标准的好处之一,必免了今后做优化时美术更改的痛苦。
以下列出在Max中清除属性的方法:
通过**Tools/Channel Info…**打开通道属性面板.
选中需要清除的属性,点击此面板上方的Clear即可,操作前记得先将模型转换成Editable Poly,之前有发现过Editable Mesh下清除无效的情况,这里不清楚是为什么。。。以下给出同一个模型清除前后的对比:
只清除掉了顶点色与2套UV,内存占用上就少了100KB,不要小看这100KB,在量级上去以后这些优化也能省下不少的内存,特别是在移动端,内存寸土寸金啊。