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         }      

也可以简单的转换为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里自行计算雾效。

时间: 2024-10-25 14:26:50

Unity3D图形基础笔记(1)的相关文章

我的LINUX基础笔记

Linux系统管理      1 Day   2014.5.23 su -name   切换用户passwd 密码   更改密码gnome-terminal    伪CLI   桌面终端程序1.查看内核版本uname -r    2.查看红帽系统版本cat /etc/redhat-rdlease3.查看LINUX标准分发版信息  lsb_release4.查看网卡的IP,MAX       ifconfig                       ifconfig eth 10.0.0.10

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

网络基础笔记——OSI七层模型

OSI七层模型 由于整个网络连接的过程相当复杂,包括硬件.软件数据封包与应用程序的互相链接等等.如果想要写一支将联网全部功能都串连在一块的程序,那么当某个小环节出现问题时,整只程序都需要改写.所以我们将整个网络分成数层,每层都有自己独立的功能,而且每层的代码都可以独立撰写,因为相互之间不会干扰.如此一来,当某个小环节出现问题时,只要将该层的代码改写即可.并且这样可以让整个网络层次更加的清晰. 在网络上传输信息就像是一个发包裹的过程,从己方的应用程序开始往第七层的包裹里塞数据,再依次塞到第一层的包

[Java基础笔记]数组

Java基础笔记 定义数组: int[] numbers = new int[100]; //方法一 double[] num = new double[10]; int[][] a = new int[2][5]; 通过new创建的数组,元素默认值为0(0.0) int[] scores = {5,4,33,12,46}; //方法二 int[][] a = { //位数不足,自动补0 {5,3,2,1,6}, {10,12,14,15}, }; 数组特性:存储的都是同类型数据:长度定义后不可

C# 基础笔记(第一篇)

C#基础 概念:.net与c#.net/dontnet:一般指.net framework框架,一种平台,一种技术c#(charp):一种编程语言,可以开发基于.net的应用. *java既是一种技术又是一种编程语言.                           .net都能干什么?开发桌面应用程序   Winforminternet应用程序    Asp.net/webservice C/S:客户机(Client)/服务器模式(Server)B/S:浏览器(Browser)/务器模式(

Nginx基础笔记

Nginx基础笔记 资源 安装 ubuntu下 编译安装 基本操作 HTTP基本配置 配置说明 配置文件目录结构 配置文件结构 模块 模块化 index模块 Log模块 Real IP模块 Access模块 Rewrite模块 Proxy模块 upstream模块 其他 配置静态化目录 负载均衡 控制页面缓存 nginx的内置变量 nginx小结 资源 资源 Nginx 官网 Nginx 官方下载地址 Nginx最佳实践配置项目 地址 Nginx Configuration wiki 教程 ag

MYSQL基础笔记(三)-表操作基础

数据表的操作 表与字段是密不可分的. 新增数据表 1 Create table [if not exists] 表名( 2 字段名 数据类型, 3 字段名 数据类型, 4 字段n 数据类型 --最后一行不需要加逗号 5 )[表选项]; If not exists:如果表名不存在,那么就创建,否则不执行创建代码,实现检查功能. 表选项:控制表的表现 1.字符集:charset/character 具体字符集:--保证表中数据存储的字符集. 2.校对集:collate 具体校对集: 3.存储引擎:e

Unity3D项目实战笔记(10):Unity3D编译IPA的PostEvents–节约时间利器

最近,SDK支付等接入差不多了,就从Unity3D生成IPA (企业版License), 然,需要手动执行的PostEvents竟然多大10项+, 这些我默默的承受了1周时间,每次约浪费20分钟-额外的. 周末用了2天时间,研究一下官方的例子和雨松的相关博客2篇,总算是搞定了这件事情,开心! 痛苦的前传: Unity3D导出为XCode工程后,有如下任务需要做 Plist 文件中 <key>CFBundleDevelopmentRegion</key> 中文 <string&

Unity3D项目实战笔记(5):延时功能的几种实现

我所做过的系统,分单机版系统(2005年).CS系统(2010年).实时系统(2015年),各个系统均有“延时”功能:定时调度的: 本博客说的是实时系统中的延时功能(基于Unity3D游戏引擎). 在Unity3D中,新建的脚本会默认继承MonoBehaviour,其中Update函数会被引擎自动调度,如在我的电脑上,Update函数被调用的周期为0.012s. 那么Unity3D中,仅有通过Update函数来实现延时功能吗?  还有无其他的实现呢? 怎么才能让一个界面只显示1秒之后 然后再执行