投影方式- Unity3D游戏开发培训
2018-02-12 00:44
351 查看
投影方式- Unity3D游戏开发培训
作者:邓家海
2018-02-12 20:33:13
在Unity3D里面,投影方式决定了我们人眼看到的场景,投影方式一般分为透视投影和正交投影两种,透视投影相当于我们人的眼睛看到的东西。越远越小,越近越大。还会出现一个倒影。在物理学上面的小孔成像就是透视投影。正交投影是平行光源的投射,物体不会随着距离的改变而改变。在计算机三维图像里面,投影是可以看作是一种将三维坐标变成二维坐标的方法。
图 1-1
图 1-2
正交投影:用于二维世界的呈现。
图 1-3
无论远近,大小是一样的
3D默认是透视投影(Perspective),2D默认是正交投影(Orthographic)。
使用Matt Fairfax实现的Model_3DS类支持3DS模型文件的载入,该类的实现非常简单,而且很容易使用,具体可参考[7]。由于本文的DEMO只需要其中的模型载入功能,所以对源代码进行了删减,去掉了纹理加载(暂不需要)和渲染(我们自己实现)代码,在析构函数中添加了资源释放代码。
[b]6.2 视图变换[/b]
为表示透视投影的一般模型,实现了KCamera类,除保存视点的位置和姿态,还保存视图变换矩阵m_kmView,随着视点位置和姿态的变化,视图矩阵也不断更新,更新算法详见第4节。对于世界坐标系中的任何一点v(x, y, z),通过v = m_kmView*v将其变换到透视投影的标准模型坐标系,详见KCamera::Transform函数。
[b]6.3 透视变换[/b]
KFrustum类用来对透视投影的标准模型进行建模,其成员包括视平面的尺寸大小,以及近截面和远截面的z轴坐标。KFrustum通过Project函数将视图变换的结果变换为透视坐标。算法的原理见第3节,代码实现如下:
[b]6.4 屏幕变换[/b]
屏幕变换的算法通过宏实现,代码如下:
6.5 渲染
Demo中的渲染使用软件实现,没有使用任何第三方图形库,主代码在KCamera::Render函数中,它接收两次参数:Model_3DS和KSurface,对Model_3DS中的顶点进行透视投影,然后将结果绘制到Ksurface中。函数代码如下:
作者:邓家海
2018-02-12 20:33:13
摘 要
透视投影是3D渲染的基本概念,也是3D程序设计的基础。掌握透视投影的原理对于深入理解其他3D渲染管线具有重要作用。本文详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型、一般模型和屏幕坐标变换等,并通过VC实现了一个演示程序。在Unity3D里面,投影方式决定了我们人眼看到的场景,投影方式一般分为透视投影和正交投影两种,透视投影相当于我们人的眼睛看到的东西。越远越小,越近越大。还会出现一个倒影。在物理学上面的小孔成像就是透视投影。正交投影是平行光源的投射,物体不会随着距离的改变而改变。在计算机三维图像里面,投影是可以看作是一种将三维坐标变成二维坐标的方法。
相机设置
透视投影:与人的视觉系统相似,多用在三维平面中对三维世界的呈现。模型是由视点E和视平面P两部分构成(要求E不在平面P上),视点就是观察者的位置,也就是三维世界的角度,视平面就是渲染三维对象的二维平面图,对于任意一点X,构造一条从E到X的射线R,R与平面P的交点X,p即是X点的透视投影结果。如图所示:图 1-1
图 1-2
正交投影:用于二维世界的呈现。
图 1-3
无论远近,大小是一样的
3D默认是透视投影(Perspective),2D默认是正交投影(Orthographic)。
透视投影的实现
[b]6.1 载入3D模型[/b]使用Matt Fairfax实现的Model_3DS类支持3DS模型文件的载入,该类的实现非常简单,而且很容易使用,具体可参考[7]。由于本文的DEMO只需要其中的模型载入功能,所以对源代码进行了删减,去掉了纹理加载(暂不需要)和渲染(我们自己实现)代码,在析构函数中添加了资源释放代码。
[b]6.2 视图变换[/b]
为表示透视投影的一般模型,实现了KCamera类,除保存视点的位置和姿态,还保存视图变换矩阵m_kmView,随着视点位置和姿态的变化,视图矩阵也不断更新,更新算法详见第4节。对于世界坐标系中的任何一点v(x, y, z),通过v = m_kmView*v将其变换到透视投影的标准模型坐标系,详见KCamera::Transform函数。
[b]6.3 透视变换[/b]
KFrustum类用来对透视投影的标准模型进行建模,其成员包括视平面的尺寸大小,以及近截面和远截面的z轴坐标。KFrustum通过Project函数将视图变换的结果变换为透视坐标。算法的原理见第3节,代码实现如下:
void KFrustum::Project(KVector3& v) { // xp = x*n/z, yp = y*n/z, zp = n. float fFactor = GetNear()/v.z; v.x *= fFactor; v.y *= fFactor; v.z = GetNear(); }
[b]6.4 屏幕变换[/b]
屏幕变换的算法通过宏实现,代码如下:
#define ToScreen(v, Ws, Hs) / {/ float x = (v.x/GetWidth()+0.5f)*(Ws-1);/ float y = (v.y/GetHeight()+0.5f)*(Hs-1);/ v.x = KMath::Round(x);/ v.y = KMath::Round(y);/ }
6.5 渲染
Demo中的渲染使用软件实现,没有使用任何第三方图形库,主代码在KCamera::Render函数中,它接收两次参数:Model_3DS和KSurface,对Model_3DS中的顶点进行透视投影,然后将结果绘制到Ksurface中。函数代码如下:
bool KCamera::Render(Model_3DS& m3DS, KSurface& kSurface) { kSurface.Fill(RGB(0,0,0)); // 背景为黑色 COLORREF crPen = RGB(255,0,0); // 用红色绘制模型 KMatrix4 m = m_kmView; int Ws = kSurface.GetWidth(); int Hs = kSurface.GetHeight(); for(int i=0; i<m3DS.numObjects; i++) { Model_3DS::Object& obj = m3DS.Objects[i]; for(int n=0; n<obj.numFaces; n+=3) { int index = obj.Faces *3; KVector4 v0(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]); index = obj.Faces[n+1]*3; KVector4 v1(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]); index = obj.Faces[n+2]*3; KVector4 v2(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]); Transform(v0, Ws, Hs); Transform(v1, Ws, Hs); Transform(v2, Ws, Hs); // 绘制网线 kSurface.MoveTo(v0.x, v0.y); kSurface.LineTo(v1.x, v1.y, crPen); kSurface.LineTo(v2.x, v2.y, crPen); kSurface.LineTo(v0.x, v0.y, crPen); } } return true; }
相关文章推荐
- 内置3D对象-Unity3D游戏开发培训
- Unity3D开发之开发android游戏的调试方式
- 用户输入- Unity3D游戏开发培训
- 7小时Unity3D游戏开发培训教程
- 7小时Unity3D游戏开发培训教程
- Unity3D教程游戏开发鼠标路线
- Unity3D ARPG游戏开发《最初的幻想》之第一张地图与跳跃的改善详解
- (转)【Unity3D游戏开发】—— iTween笔记 一(战棋寻路)
- Unity3D 游戏引擎之详解游戏开发音频的播放(十五)
- 【UNITY3D 游戏开发之三】NGUI && HUDText 的练习源码及资源
- Unity3d开发IOS游戏 基础
- 【游戏客户端开发】Unity3D 学习笔记4 —— UGUI+uLua游戏框架
- Unity3D手机斗地主游戏开发实战(03)_地主牌显示和出牌逻辑(不定期更新中~~~)
- Unity3D游戏UI开发经验谈
- 【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式,并把SQLite的数据库文件存储在SD卡中!!!
- 当优美的C#与Unity3D结合时开发游戏变的超Esey(一)必须掌握的C#100个基本点。
- 【Untiy3D 游戏开发之一】Unity3D For Mac最新3.4.1版本破解教程分享并将Unity3D项目在iphone上运行;
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读
- [Unity3D]Unity3D游戏开发Lua随着游戏的债券(于)
- iPhone培训应用游戏开发班(全天班)