首页 > 代码库 > Unity3D图形基础笔记(1)

Unity3D图形基础笔记(1)

   1.坐标系

   (1).Unity 世界空间坐标系为左手系,Y正向向上的左手系。这一点在需要从3ds max里导入模型到Unity时需要注意,3ds max使用的是以Z正向朝上的右手系。根据坐标系手系和坐标基朝向的不同,可以很容易推导出所需要做的坐标变换。

   3DS Max -> Unity 的坐标变换为:绕着x轴旋转90度,直接使用四元数变换如下:

1 public Vector3 MaxToUnity(Vector3 v)2 {3     return Quaternion.Euler(90.0f,0.0f, 0.0f) * v ;4 }

  根据旋转矩阵,可以得到一个更简单优化的版本,

  把90度代入左手系绕x轴旋转任意角度的旋转矩阵,可得到最终变换矩阵,形式如下:

  

 V = V0 * MatrixRotation = ( X0 ,-Z0 ,Y0 )

代码为

1 public Vector3 MaxToUnity(Vector3 v)2 {3      return new Vector3(v.x,-v.z  ,v.y);4 }

相应的,把Unity坐标转换到Max坐标,可以简单实现如下

1 public Vector3 UnityToMax(Vector3 v)2 {3     return new Vector3(v.x,v.z,-v.y);4 }

  (2).Unity的相机空间坐标系为右手系,即相机空间的基由(RightDirection,UpDirection,LookDirection)组成

  写到这儿的时候顺便吐槽一下Unity的相机实现---Unity的相机在IDE上可操控的Transform中不包含Eye‘s Position和LookAt,这种标新立异的做下让人在Unity里调相机的时候痛苦无比,想要精确定位相机时非常困难。虽然理论上来说相机空间仅包含平移和旋转,使用平移、旋转两个分量已经足够,但以往所加入LookAt点可以帮助美术在场景里迅速对焦。从完备和便捷性这一点上来说,Unity是还远不如人意的。

   使用传统的Eye‘s Position和LookAt计算Unity相机矩阵代码如下:   

 1 public static Matrix4x4 calcCameraMatrix(Vector3 eye, Vector3 lookat, Vector3 upDir) 2         { 3             Matrix4x4 mat = new Matrix4x4(); 4             Vector3 lookDir, rightDir; 5             lookDir = (eye - lookat).normalized; 6             upDir = Vector3.up;         7             rightDir = Vector3.Cross(upDir, lookDir); 8             upDir = Vector3.Cross(lookDir, rightDir); 9             mat.SetColumn(0, new Vector4(rightDir.x, rightDir.y, rightDir.z, 0.0f));10             mat.SetColumn(1, new Vector4(upDir.x, upDir.y, upDir.z, 0.0f));11             mat.SetColumn(2, new Vector4(lookDir.x, lookDir.y, lookDir.z, 0.0f));12             mat.m30 = -Vector3.Dot(rightDir, eye);13             mat.m31 = -Vector3.Dot(upDir, eye);14             mat.m32 = -Vector3.Dot(lookDir, eye);15             mat.m33 = 1.0f;16         mat = mat.transpose;17             return mat;18         }      
View Code

  也可以简单的转换为Unity所使用的四元数和位置信息,代码如下: 

1 public static void lookatToTR(Vector3 eye ,Vector3 lookat, out Vector3 position ,out Quaternion rotation)2 {3     position = - eye;4     rotation = Quaternion.LookRotation (eye - lookat);5 }

   通过这样转换之后,之间在其它引擎既有的相机操作代码就可以简单移植过来了。

2. 雾效

   在没有特别说明的情况下,Unity在PC端实现的是像素雾,但在Mobile设备上则是顶点雾。这样超大面积三角形在使用默认的Mobile材质的时候会不受雾效影响,和周围场景会不协调。对应的处理方式为只能是把三角形切小,或自己实现相关材质在shader里自行计算雾效。

Unity3D图形基础笔记(1)