关于3DsMax与Unity坐标轴的若干问题详解

关于3DsMax与Unity坐标轴的若干问题详解

  网上有很多叙述关于3DsMax制作的模型导入到Unity3D时如何进行坐标轴处理的方法,大部分只告诉你该如何做,至于为什么也没写。有的解释了,但是解释的完全是错误的。由于我之前解析过FBX文件,所以对其的格式有所了解,但是之前一直使用OpenGL写程序,U3D和3DsMax之间的纠葛我也没怎么了解,今天学习U3D时候碰到了所以针对坐标轴的一些问题和FBX文件的一些问题写了一篇文章,希望把东西分享出去同时记录下来怕自己以后忘了。

一、 FBX文件格式

  FBX格式是Autodesk公司推出的一种“跨平台”的模型文件格式也是U3D支持最好的模型文件格式,其跨平台指的是在3DsMax、Maya、Blender等等建模软件中都可以导出和导入(有的可能需要装插件)甚至你可以自己写程序去解析FBX数据,把你需要的顶点、UV、法线等等信息全部取出来。
  解析其中的数据一般是通过官方给的FBX SDK进行解析,因为FBX导出时有两种选项,一是文本格式(很少很少用)另一种就是二进制格式,所以针对文本格式,你可以自己分析自己写解析器,但是对于二进制格式,你还是还是乖乖的使用FBX SDK,而且FBX有一个特点,就是它所包含的信息非常非常非常的多,普通的模型格式文件比如obj,它所包含的就是模型数据,顶点位置、法线、UV和材质(材质单独为mat文件),而且本身obj就是文本格式,简单明了。而FBX包含的除了上面的基本信息还有蒙皮信息、骨骼信息和动画信息以及很多的旋转信息、每帧时间、坐标系、灯光、摄像机、场景结点等等很多信息,它丰富的足以“保存”下一个游戏场景而不是单单一个模型。加之官方对其的文档让人很无语,即使使用SDK仍然要花蛮多的时间弄懂这些信息代表的是什么。

二、3DsMax和U3D使用的坐标系及其转换

  首先3DsMax使用的是右手坐标系,Unity使用的是左手坐标系
  左右手坐标系的转换是不能单靠一个旋转就能解决的,必须翻转某一个轴再进行渲染操作才能使得右手坐标系到左手坐标系
通常我们在3Ds建模完成的模型文件直接导入到Unity中,会看到Unity自动绕x方向旋转了-90度(左手坐标系)
U3D
如图中的Rotation X
  很多人以为Unity旋转了一下就OK了,实际上Unity内部执行了坐标轴翻转操作。因为3DsMax在使用右手坐标系时Z轴向上,即使对z轴进行取负后仍需要旋转才能跟U3D的坐标轴对的上。
关于3DsMax与Unity坐标轴的若干问题详解_第1张图片
图为3Ds中的坐标轴,可以看到使用右手坐标系,并且z朝上

二、 导出时的Y轴向上和Z轴向上

  导出FBX文件时我们会看到坐标轴可以选择z还是y向上,但是不管你选哪个导入到Unity中貌似都没什么作用,实际上这个设置是有影响的,稍后会说道,现在要说清楚另一个事情。
  FBX文件会保存模型的顶点位置信息,这个顶点位置是相对于建模时使用的坐标轴(默认就是右手,z向上)的模型空间顶点位置,不管你对其进行了平移、旋转、缩放还是导出时怎么设置,包括层次关系中选中“仅影响轴”对轴进行修改。这个顶点位置信息都不会变,它所依赖的坐标系(右手,Z向上)都不会改变,始终是模型空间的位置信息。
回到上一个问题,导出时选择Y还是Z,它这里的哪个轴向上针对的都是右手坐标系来说的,所以通过保存一个旋转信息就能实现。在FBX文件中有一种属性叫做PreRotation,它指明了模型的“初始旋转”。
关于3DsMax与Unity坐标轴的若干问题详解_第2张图片
  这张图是针对Y轴向上导出后保存的PreRotation信息,也就是说你的设置是有影响的,只不过Unity会忽略这个信息因为本身顶点位置不会被改变(模型空间的顶点位置),管你是Y向上还是Z向上,加上了反而还会增加一次旋转。
所以对于U3D开发者来说这个选项没什么用。

三、 调整轴操作

  还有一些文章会说道,如果你不想看到U3D里面个-90度操作,你可以直接调整轴把物体的轴绕x轴旋转90度就行了。确实,旋转后U3D初始的绕x先旋转-90的操作没了,但是为什么?或者说调整轴这个操作改变了什么?
实际上刚才我也说道,无论你执行调整轴还是旋转、平移、缩放操作,顶点位置是不会改变的,也就是说FBX只会保存旋转信息,这个信息保存在哪里了?
  FBX中还有一个属性叫做Lcl Rotation,这个属性保存的是物体的旋转信息:
关于3DsMax与Unity坐标轴的若干问题详解_第3张图片
  注意看这三个属性,你的一切平移、旋转、缩放信息实际上是把模型从模型空间转换到世界空间,这些转换信息都会保存在Lcl xxxx属性中,这里的模型没有这些操作所以都是0,对其进行旋转操作,会看到:
关于3DsMax与Unity坐标轴的若干问题详解_第4张图片
  这和在3DsMax中的旋转信息界面看到的一样
  说了这么多,和调整轴有什么关系?实际上,调整轴操作本质上就是把物体旋转了(或者平移、缩放,一般不会用到这两个操作)。这里先来说一下3DsMax调整轴的概念,首先它调整的不是真正的物体的局部坐标系,你可以看到FBX文件中顶点位置仍然按照3DsMax默认的z向上的右手坐标系。这里的调整轴可以这样理解,原本z向上的轴,你把它绕x轴旋转90度使得y向上,z向前(物体一并旋转)这时候的坐标系就是y向上了,这里注意绕x旋转90度这个状态(注意这个状态)保留住就相当于局部坐标系y向上了,但是为了避免物体也被旋转,就必须有一种变换先让物体逆方向变换,这里就是绕x逆方向90度旋转。而且这种变换不能是模型变换,否则两者抵消保留不住y向上的状态。于是3DsMax引入了一种变换较GeometricTransform,针对旋转就是GeometricRotation。也就是咱们在3DsMax看到的,你调整轴后,物体的旋转信息就是你旋转轴的旋转信息。但是物体方位没变。
这里写图片描述
图为经过调整轴使得y向上后FBX文件中Geometric变换发生了改变。如果没调整轴这个变换平移、旋转都是0。
  还有一个疑问,Lcl和Geometric发生了抵消,按理说Transform上仍然都会显示-90为什么调整轴后会发生变化?
这里写图片描述这里写图片描述
左图为未调整轴导入到U3D时的情况,右图为调整轴后导入U3D的情况
关于3DsMax与Unity坐标轴的若干问题详解_第5张图片
  左边的茶壶的Transform就是上面左图,右边茶壶就是上面右图
  可以看出位置都是正确的
关于3DsMax与Unity坐标轴的若干问题详解_第6张图片
  对比上面2图,可以看到局部轴实际上得到了调整。

  那么为什么调整轴实际上效果抵消但是Transform上能显示出差别呢?因为对Geometric的变换是内部进行的,而Lcl的变换是会显示到Transform上的。也就是说FBX中使用的坐标系的信息自然会保存到FBX文件中,U3D发现坐标轴不对。注意这里的坐标轴FBX中的局部坐标轴仍然是z向上坐标轴。U3D会执行翻转z轴然后绕x轴旋转-90度的操作。由于GeometricRotation不为0先执行该变换,这是导入模型内部进行的。然后法线LclRotation为90度,这个实际上就是对应到Rotation上的,然后执行-90度操作,二者抵消就是0度。而如果没有调整轴,Lcl变换为0,执行-90度操作就会看到Transform上的-90度

四、 总结

实际上咱们可以看出

  1. FBX中保存顶点位置依赖的是3DsMax中的坐标轴,而旋转、调整轴都不会改变这个坐标轴所以顶点位置始终不变
  2. 导入一个FBX模型先内部进行Geometric变换,LclRotation就是模型坐标系向世界坐标系的变换,这会影响Transform上的Rotation
  3. 旋转轴、调整轴的操作会保存在LclRotation上

      另外U3D实际上背后做了很多细节上的调整,你大可以忽略这些背后的原理,但是懂了这些更能看透一个引擎背后做了哪些东西,也能对坐标轴的理解更深入。而且3DsMax中制作的模型直接导入到U3D就行,为了避免一次旋转而进行调整轴实际上内部还是会执行这次旋转,而且还多一次旋转。所以除非某些特殊情况大可不必进行调整轴的操作。
      对于FBX文件来说,可以看出这种文件格式包含了很多很多很多的信息,不仅仅是一个模型文件了。
    其实如果世界上都使用一种坐标系,那这些较为繁琐的小细节都不会存在了,制定标准是一个很重要的事情。

你可能感兴趣的:(游戏开发)