关于本文

本文主要想介绍一下3D渲染的基本流程,及怎样把一个三角形(0,1,0),(1,0,1),(0,0,1)最终渲染到屏幕上来。文章的目的是对3D渲染流程做一个简单的介绍,其中不涉及任何语言的API

参考资料

局部坐标和世界坐标

接触Flash的人应该不太难理解这个概念吧,比如在库中建立一个边长为50的正方形,设置其左上角为原点,局部坐标的(0,0)为原点

然后将其拖入Flash的主舞台上面以后,就会得到一个全局坐标(84,110)

那刚才拖动的一下操作,完成的是怎样的一个运算呢?

抛开填充的蓝色先不谈,那么几何上面来说,正方形是由4个点构成的,A(0,0) B(0,50) C(50,0) D(50,50)

刚才做的操作可以理解把该正方形拖放到舞台的(84,100)位置。对应的得到ABCD四点坐标分别为A’(0+81,0+100) B’(0+84,0+50) C’(50+84,0+100) D’(50+84,50+100)

这样也就是完成了一次局部坐标到世界坐标的转换

那同样的道理,对于一个3D坐标点A(0,0,0) 也可以执行一次坐标变换,比如(84,100,37),这样也能得到一个对应的3D坐标点A’(0+81,0+100,0+37)

为何要进行局部坐标到世界坐标转换

在平常我们做Flash时候也一样,比如要做一个小人站在房子边上的图,那肯定是单独建立两个元件 元件::小人 元件::房子 ,然后将其拖入主舞台拼凑在一起。3D中也是一样的各种物体也是现在自己的坐标系内制作好,

最后放入场景内进行的拼接

了解矩阵

在进一步介绍3D之前,首先需要了解一下矩阵。本来想给出一些自己的例子,不过参考了一下现有资料,发现没有太多好补充的东西。如果对矩阵的基本改变还不是很了解

(比如矩阵是做什么用的,矩阵相乘,旋转矩阵,平移矩阵等)

请参考如下部分

《3D游戏编程大师技巧》 P161~P165

《3D数学基础:图形与游戏开发》 P85~P107

摄像机&视景体

在把所有物体完成了从局部坐标系到全局坐标系的转化,及完成了构建一个3D场景,只是这个场景中全部是由点构成的。这个时候就需要引入摄像机的概念,摄像机就像一双在这3D世界中的眼睛,眼睛的位置不同,

看的方向不同,那最终看到的景象也就不同.

和现实世界中的摄像机稍微有些不同,在于需要给这个摄像空间定义一个区域,及近剪裁面和远剪裁面。也就是小于近剪裁面和大于远剪裁面的物体将不会被渲染

在远剪裁面之外的物体: 可以理解为即使渲染了该物体也会是一个点,所以不进行渲染。在玩儿一些早期的3D游戏时候有时候会出现这种情况,一直向前走,前方的建筑物会突然从远处出现,我想也是这种原因吧

在近剪裁面之外的物体: 如果渲染的话会是一个非常大的物体,所以也不进行渲染。(近剪裁面如果用现实中的相机做比喻似乎不是很容易理解,当时若吧这个放入数学定义中去理解,反而容易一些)

世界坐标到相机坐标的转换

当确定好视景体后,也就可以确定了哪些物体最终可以见,哪些是不可以见。剔除这些不可见的物体后,需要将其余物体进行世界坐标到相机坐标的转换。

在一种极端情况下是不需要进行该步骤的,就是相机在原点(0,0,0)且方向和坐标轴的方向是一致的,此时不需要再进行转换

但是大部分时候,相机其实是不在原点的,且所朝的方向也不是坐标轴方向。

此时就要对这些物体(物体的每个顶点)进行世界坐标到相机坐标的变换。

变换一共分为几个步骤,

第一步 平移

如图,也就是假设相机的坐标点为(cam_x,cam_y,cam_z),那对所有剩余物体的顶点均执行平移操作(world_x-cam_x,world_y-cam_y,world_z-cam_z)

第二步 旋转

此时相机已经处于坐标原点处了,不过相机镜头仍旧是歪的,仍旧需要对其进行x,y,z三方向旋转才可以将相机还原为最开始那张图所画的样子。

对于先旋转哪个,后旋转哪个是无所谓的。及按xyz还是zyx方向旋转都是一样

最终流程:

为何要进行相机坐标转换

如果还不是很理解为何要进行相机坐标转换,可以再回到2D世界,还是最早的例子,那个正方形A(0,0) B(0,50) C(50,0) D(50,50) 经过的局部到世界坐标的转换是A'(0+81,0+100)  B'(0+84,0+50)  C'(50+84,0+100) D'(50+84,50+100)

A'点也就是为(0+81,0+100)->(81,100)

此时如果假设你自己就是相机,眼睛和舞台的0,0点对齐,眼部和显示器距离为300,那么A'点在你眼中的三维坐标也就是(81,100,300)

此时也就是之前所说的极端情况,摄像机和全局坐标同轴且共相。那A'点(81,100,300) 也就是最终渲染到屏幕上面的坐标点,但是

如果此时你离开显示器一段距离,且歪一下脑袋,再看A'点(81,100,300),这时候其所在你自己眼睛(摄像机)中的位置就不是原来那个位置了,

假设此时你看到的景象是M,

那你可以想象此时你回到原位,然后有另外一个人,抱起你的显示器放在另外一个位置且稍微转一个角度

此时你看到的景象仍旧是M,

那个人对那个物体进行的操作(抱起来放边上且转了一个角度)就是相机坐标变换

物体剔除&背面消除

这块知识我想简单的说一下,在《3D游戏编程大师技巧》 里面有非常详细的说明

物体剔除:

物体剔除在2D中也是存在的,对一个物体进行包围盒测试,如果不再场景内则不显示该物体,3D中也是做同样的操作,只不过包围盒是三维的,且探测范围也不再是一个平面,而是整个视景体。

背面消除:

当一个物体确实是在视景体内部时候,也不是所有面均需要最终渲染出来,此时要做的就是背面剔除,将那些被完全挡住的平面剔除出去

为何要进行剔除

在渲染流程的前段步骤,所有操作均是针对点的,比如坐标转换,剔除等.当最终确定了一个面确实要被渲染以后。后半段的操作及要对该面进行着色(设置纹理),光照处理等。

所以如果可以在前期多剔除掉一个面,就应该多剔除一个。

透视变换

当完成了一切剔除操作后,对于剩下的平面(此时剩余的仅为一个个平面了),还需要进行透视变换。也就是将一个三维点A'(81,100,300) 变换为一个二维的坐标点。

这里面的转换涉及两种

正交投影

来源 http://baike.baidu.com/view/3153027.htm

这种投影比较简单,及直接去除z点的值即可,一般用在工业制图上面(AutoCAD),对于Starling(Flash上面使用Stage3D技术加速2D游戏的引擎),目前我还不是很了解。不过为自己写的一个Demo,投影选择的就是

正交投影。因为原本需要渲染的就是一个2D平面,只要其在视景体内,其大小就和所在位置无关了

透视投影

来源 http://baike.baidu.com/view/1318206.htm

透视投影及实现了近大远小的投影,及离摄像机距离较远的物体看起来会相对小一些,离摄像机进的物体看起来更大一些。和真实世界中看到的是一样的。在三维游戏中用到的均为这种投影

两者的区别下面这张图很好的标示出来

左面的为透视投影,右面的为正交投影

整体流程概览

3D渲染流程上面大体就是这样了

图中在背面消除后采取了两种方式,

B路线为画家算法(http://baike.baidu.com/view/2020287.htm),

A路线为在常规的物体消除后再进行一次空间剪裁(及把那些不是完全在视景体内部的元件再剪裁,及AABB测试压线的物体)

但是无论是经过A路线,还是B路线 最终剩余的平面就会开始光栅化(忽略屏幕坐标变化,具体的请看书)。及真正的对其进行着色,打光等操作了

本文和Stage3D的关系

首先请阅读两篇文章

GPU大百科全书第二章 凝固生命的光栅化 http://vga.zol.com.cn/236/2366808.html

How Stage3D works http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html

看完这两篇文章以后可以看出,本文其实只是大体上面说明了一下3D渲染的基本过程,但是和目前真正的技术(我参考的资料已经是十几年前的东西了吧)还是有一定出入的,

Stage3D最相关的东西也就是这张图中的

VertexShader 还有 FragmentShader(也就是Pixel shaders)

我在初探Stage3D(二) 了解AGAL中做了一些说明,

VertexShader 主要作用就是3D流程中的前半段操作(对顶点进行一系列的矩阵变换)

FragmentShader 操作是对这些变换后的顶点(及流程中的光栅化部分)进行渲染

初探Stage3D(一) 3D渲染基础原理的更多相关文章

  1. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  2. 初探Stage3D(三) 深入研究透视投影矩阵

    关于本文 本文主要讲解从数学的角度如何推导出Stage3D中用到的两个投影矩阵 perspectiveLH public function perspectiveLH(width:Number,hei ...

  3. 初探Stage3D(二) 了解AGAL

    关于本文 本文并无打算事无巨细的介绍一遍AGAL,仅仅是对现有文档的一些理解及汇总,所以请先阅读相参考文档 AGAL概念 参考资料 http://www.adobe.com/devnet/flashp ...

  4. 裸眼3D立体显示技术原理详解

    众所周知,现实世界是一个三维空间,除去时间这一维度,现实世界是由长度.宽度和高度三个维度组成,我们每天就生活在这个三维世界中,而现有的显示设备大多数都只能显示二维信息,并不能带给人真实的三维感觉.为了 ...

  5. 3D模板阴影原理

    3D模板阴影原理 1:先从3dsMax中导出一个简单的场景,一个园环,球,平面. 2:园环直接面向光源,园环对球体来说是一个光线的阻挡物,园环在它上面形成阴影,同时,园环和球体对平面来说是光线的阻挡物 ...

  6. 基于 HTML5 Canvas 的 3D 渲染引擎构建生产管控系统

    前言 大家好,老郑我又回来了.这一期为大家带来一个非常好玩的 demo,我们制作一套自己的 3D 管道控制系统,运用了( http://www.hightopo.com )HT 的 Graph3dVi ...

  7. 3D立体显示技术原理与游戏应用历程简介 【转】

    本文来自 中关村ZOL 「3D 立体显示」可说是近来娱乐产业相当热门的话题,不但有好莱坞推出<阿凡达>等卖座 3D 立体电影,全球各大家电厂商也积极布局准备推出一系列支持 3D 立体显示的 ...

  8. 3D开发基础知识和简单示例

    引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...

  9. 【一起学源码-微服务】Hystrix 源码一:Hystrix基础原理与Demo搭建

    说明 原创不易,如若转载 请标明来源! 欢迎关注本人微信公众号:壹枝花算不算浪漫 更多内容也可查看本人博客:一枝花算不算浪漫 前言 前情回顾 上一个系列文章讲解了Feign的源码,主要是Feign动态 ...

随机推荐

  1. 工资低的.Net程序员,活该你工资低

    这两天博客园上关于“.Net工资低”的讨论挺多的,让我不禁想起一句话“拉不出屎来怪地球没引力”. 那些抱怨“做.Net工作三年了月薪才6千,我的同学做Java现在都一万二”的哥们,你问问自己“我会什么 ...

  2. Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)

    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 一个很好的例子: # -*-coding:utf-8 -*- ...

  3. AlwaysON同步性能监控的三板斧

    延迟是AlwaysOn最大的敌人之一 延迟是AlwaysON的最大敌人之一.对AlwaysON而言,其首要目标就尽量减少(无法避免)主副本.辅助副本的数据延迟,实现主副本.辅助副本的“数据同步”.只有 ...

  4. Server Develop (八) IOCP模型

    IOCP模型 IOCP全称I/O Completion Port,中文译为I/O完成端口.IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的 ...

  5. web应用性能测试-Tomcat 7 连接数和线程数配置

    转自:http://www.jianshu.com/p/8445645b3aff 引言 这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7.期间学到了蛮多散碎的知识点,及时梳理 ...

  6. Cocos2d-x3.6 Android编译问题

    在Cocod2d-x论坛上看到越来越多人吐槽新版本更新太快,改动太大,而且经常有BUG导致升级要折腾很久很久..但我就是喜欢折腾,喜欢升级到最新版本,看看有了哪些新功能,哪些改进.为此也折腾了不少,遇 ...

  7. ios 手动添加mapview

    1,首先选中Build Phases ,在Link Binary With Libraries 下添加MapKit.framework框架 2,在头文件(.h文件)处添加:#import <Ma ...

  8. 判断输入的数是否为数字,不使用isNaN

    虽然不使用 isNaN ,但使用了 Math 的一些方法. <!-- Author: XiaoWen Create a file: 2016-12-08 11:14:34 Last modifi ...

  9. [轻微]WEB服务器启用了OPTIONS方法/如何禁止DELETE,PUT,OPTIONS等协议访问应用程序/tomcat下禁用不安全的http方法

    使用了360网站安全检测 查到有OPTIONS方法 百度了下 https://my.oschina.net/maliang0130/blog/338725 找到这个方法奈何http.conf 找不到无 ...

  10. hdu4508 完全背包,湫湫系列故事——减肥记I

    湫湫系列故事——减肥记I 对于01背包和完全背包,昨晚快睡着的时候,突然就来了灵感 区别:dp[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值 在第二重循环,01 是倒着循环的,因 ...