Doom 3 阴影算法简介
【hotball技術小舖】Doom 3的打光系統簡介
(2004-10-21) 在本文中,會對Doom 3的打光系統中,最重要的兩個部份:陰影和凹凸貼圖,做一些簡單的介紹。 |
|
【作者/陳秉哲】 |
原文链接 http://www.poweruser.com.tw/ 阴影的产生 经过漫长的等待,id Software 终于在今年八月正式推出Doom 3。虽然Doom 3在游戏性上,和过去的Doom系列游戏并没有太大的不同,但是Doom 3引擎则是一个完全不同、全新的设计。Doom 3引擎最大的特色,就在于它的打光系统。它结合了完整的阴影和凹凸贴图,并号称使用一致的打光模型,对整个场景中的所有物体一视同仁。它产生的效果相当理想,也为3D引擎又设下了一个新的里程碑。 大家都知道,阴影就是光线没有照射到的地方。换句话说,如果一个地方,和光源之间有东西挡住,那它就会在阴影中。从物理的角度来看,其实是刚好相反的:有光线照射到的地方,就会反射光线。因此,它会比没有被光线照射的地方,要显得更亮。不管用什么角度来看,阴影都不是只和某个物体有关,整个场景都会对阴影产生影响。 因此,要在3D绘图中,产生正确的阴影,就需要考虑到整个场景。这和一般对物体进行打光、著色的动作有很大的差别。一般3D绘图中,物体的颜色、亮度等等的变化,只和物体本身,以及光源的位置有关系(有时和观察者的位置也有关系)。它并不会牵扯到其它的物体。因此,它的效果是区域性的。但是,阴影的效果则是整体的,因为随著光源位置改变,任何物体都有可能遮住另一个物体,而产生阴影。也因此,要正确地画出阴影,是一个相当困难的问题。
使用3D绘图晶片产生阴影 一般3D绘图晶片,是针对“区域性”的打光效果设计的。3D晶片上并没有保留整个场景的三角面资料,它只是对目前送进来的三角面进行著色的动作。因此,在一般的情形下,3D晶片并不能自行判断出,一个三角面是否被别的三角面遮住,而使它在阴影中。 不过,虽然如此,3D晶片还是得处理一些“整体性”的工作。最简单的例子,就是处理隐藏面问题。在进行3D绘图的时候,离观察者较近的物体,会遮住较远的物体。因此,3D晶片需要能判断出,哪些三角面会被哪些三角面遮住。由于3D晶片并不保留任何三角面的资料,因此,它并不能去检视之前所画的三角面是否会遮住目前所画的三角面。为了解决这个问题,目前的3D晶片,通常是使用Z buffer。这样一来,3D晶片就可以避免以三角面为单位来进行隐藏面的判断,而是以pixel为单位进行。 可以看出,阴影的问题,和消除隐藏面的问题,其实是十分类似的。如果把观察者的位置到在光源的位置,把整个场景画过一次,就可以知道哪些物体是被光源直接照射到的,也就是会反射光线,较亮的物体。相对的,没有被直接照射到的物体,当然就是在阴影中了。这个方法其实就是Shadow map的基本原理。不过,Shadow map还有许多麻烦的问题要克服,而且Doom 3也不是使用这个方法,因此这里就不再多做讨论。但是Shadow map的前景看好,最近推出的3DMark05主要就是使用Shadow map来产生阴影。Shadow map也有比较简单的版本,但是它并不能用在整个场景上面。 Doom 3使用的是所谓的Volumetric Shadow,或称为stencil Shadow(因为Volumetric Shadow通常需要使用到stencil buffer)。Volumetric Shadow的基本原理,是让所有的物体“投射”出阴影。被“投射”到的物体,就是在阴影中。相反的,没有被“投射”到的物体,就是被光源直接照射,会反光的部份。Volumetric Shadow和Shadow map方式最大的不同,是Shadow map基本上是由pixel组成,但是Volumetric Shadow则直接在三角面上进行处理,而不是把物体看成一个一个的pixel。 Volumetric Shadow Volumetric Shadow的基本方式,是先找出物体的外框。接著,再从外框延伸出一个"Volume"。这个Volume就是阴影的范围,也可以称为Shadow Volume。任何在这个Volume内部的pixel,就是在阴影里面。因此,问题就变成,要如何判断一个pixel是否在Volume里面。这就是 stencil buffer发挥作用的地方。 Stencil buffer有点类似Z buffer,它为每个pixel记录一个数字。在画三角面时,可以指定要进行某个运算,例如把数字加一、减一等等。另外,也可以指定在画三角面时,只处理stencil数字在某个值的pixel。例如,可以要求只画在stencil值是0的pixel,其它的pixel则不画。
要利用stencil buffer来判断哪些pixel在Shadow Volume中,首先要把每个pixel的stencil值清为0。接著,画出所有的三角面的Shadow Volume中,正对著观察者的部份(上图的白色部份),同时,把stencil设成“加一”。这样一来,所有在Shadow Volume后面的pixel(包括Shadow Volume里面),其stencil值都会是正数。接著,再画出Shadow Volume中,背对观察者的部份,但这次把stencil 设成“减一”。这样一来,在Shadow Volume后面,但是却不在Shadow Volume中的pixel,其stencil值会回到0,但是在Shadow Volume中的pixel的stencil值则还是正数。这样一来,就可以用每个pixel的stencil值,来判断它是否在阴影中了。 虽然Volumetric Shadow的基本原理就是这样,但是实际上却还有很多问题。最明显的问题,是当观察者跑到Shadow Volume里面的时候,Volumetric Shadow就会出错。另外,在3D绘图时,通常都会设定一个Z clip plane,限制场景绘图的范围,但是如果切到Shadow Volume,则会产生空洞,而造成问题。因此,许多人发展出各种方法,设法解决这些问题。其中,最有效的方法是Carmack's reverse,是由id Software的John Carmack提出的(其中也有许多其他人的贡献)。这个方法是利用反转Z buffer测试的方式,使观察者永远不可能出现在Shadow Volume里面。这样就解决了第一个问题。第二个问题的解决方法,则可以透过取消远端的Z clip plane来解决,不过这样可能较缺乏效率。另一个方法,则是由显示晶片在硬体上,针对Z clip plane进行处理,使Shadow Volume在Z clip plane上可以自动封住Shadow Volume,使它不会产生空洞。 经过这些改进,Volumetric Shadow变成一个相当可靠的方法。由于它是以三角面为基础,因此它非常精确,不像Shadow map等方法会有解析度不足的问题。而且,它并不需要很多特别的硬体支援,只需要stencil buffer。Stencil buffer是OpenGL的标准功能,因此许多3D晶片都有支援。这想必也对id Software决定在Doom 3中使用Volumetric Shadow有一定的影响。 不过,Volumetric Shadow并非全无缺点。它最大的问题,是在绘制Shadow Volume时,会吃掉大量的fillrate。而且,由于Shadow Volume是由物体的3D模型的外框所产生的,而要计算外框,就需要处理器进行处理(这个工作并不适合由显示晶片进行)。这会增加处理器的运算量。它也无法用在利用具有透明区域的贴图的物体上,有些游戏使用这样的贴图来绘制复杂的物体,像是树木。最后,voluemtric Shadow 产生的阴影都非常锐利,但真实世界中的阴影通常都有些模糊。这是因为真实世界中的光源都不是一个小点,而是具有某个大小。要使用Volumetric Shadow产生模糊的阴影,可以用多个靠近的点光源来模拟一个具有大小的光源,但是这样当然就会更慢了。这些都是Shadow Volume的主要问题。 凹凸贴图 除了一般的凹凸贴图之外,Doom 3在人物和怪物等物体上使用另一种方式产生凹凸贴图。由于一般的显示晶片速度有限,所以一般人物或怪物的3D模型,并不能有很多的三角面。特别是Doom 3大量使用Volumetric Shadow,需要处理器处理这些三角面以计算出物体的外框,因此三角面的数目更是不能太多。因此,id Software在Doom 3中使用了一个很特别的方式:首先,以大量的三角面去设计人物和怪物的3D模型。然后,再将这些3D模型简化,产生一个三角面数目较少的3D模型。这个 3D模型就是游戏中实际会用到的3D模型。然后,再从原本较复杂的3D模型,对照简化的3D模型,产生适当的凹凸贴图。这样一来,在使用凹凸贴图进行打光的时候,就可以用较简单的3D模型,产生看起来接近原本复杂的3D模型的效果。 结语
|
文⊙劉人豪(夜露死苦技術專欄)
原文链接 http://www.poweruser.com.tw/
转载于:https://www.cnblogs.com/oiramario/archive/2006/10/31/545472.html
Doom 3 阴影算法简介相关推荐
- doom 源码_Cartpole和Doom的策略梯度简介
doom 源码 by Thomas Simonini 通过托马斯·西蒙尼(Thomas Simonini) Cartpole和Doom的策略梯度简介 (An introduction to Polic ...
- 数据结构与算法:算法简介
数据结构与算法:算法简介 雪柯 大工生物信息 提笔为写给奋进之人 已关注 你说呢 . shenwei356 等 70 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国 ...
- hash算法_一致性hash算法简介
一致性hash算法有什么用?我们为什么需要一致性hash算法?这两个问题的答案可以看这篇文章 分布式系统路由算法简介. 了解了一致性hash算法出现的背景,我们来看看什么是一致性hash算法.一致性h ...
- Minimax 和 Alpha-beta 剪枝算法简介,及以此实现的井字棋游戏(Tic-tac-toe)
前段时间用 React 写了个2048 游戏来练练手,准备用来回顾下 React 相关的各种技术,以及试验一下新技术.在写这个2048的过程中,我考虑是否可以在其中加入一个 AI 算法来自动进行游戏, ...
- 推荐系统算法_机器学习和推荐系统(二)推荐算法简介
推荐算法简介 一. 基于人口统计学的推荐算法 二.基于内容的推荐算法 三. 基于协同过滤的推荐算法 协同过滤(Collaborative Filtering , CF) 基于近邻的系统过滤 基于用户( ...
- 图像迁移风格保存模型_CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、关键步骤配图、案例应用...
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介.过程思路.关键步骤配图.案例应用之详细攻略 目录 图像风格迁移算法简介 图像风格迁移算法过程思路 1.VGG对比NS 图像风 ...
- 魔棒工具--RegionGrow算法简介
from: 魔棒工具--RegionGrow算法简介 ps里面的魔棒工具非常好用,是图像处理中非常常用的一个工具,它现在已经是我的c++工具箱中很重要的一员了,我会在以后的时间里把我的工具箱逐渐介绍给 ...
- 【数据挖掘】基于划分的聚类方法 ( K-Means 算法简介 | K-Means 算法步骤 | K-Means 图示 )
文章目录 一. 基于划分的聚类方法 二. K-Means 算法 简介 三. K-Means 算法 步骤 四. K-Means 方法的评分函数 五. K-Means 算法 图示 一. 基于划分的聚类方法 ...
- AI - 常见算法简介(Common Algorithms)
机器学习常见算法简介 - 原文链接:http://usblogs.pwc.com/emerging-technology/machine-learning-methods-infographic/ 应 ...
最新文章
- 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(61)-如何使用框架来开发?...
- JavaScript开发
- c# 注册表操作,创建,删除,修改,判断节点是否存在
- 【leetcode】147. Insertion Sort List
- 【STC15库函数上手笔记】6、ADC
- 状态机fsm_Verilog专题(三十二)101 Sequence Recognition Mealy FSM(101序列识别状态机)...
- ubuntu apt-get 时遇到waiting for headers的破解办法
- office excel2013如何启用solver选项
- 01 Nginx的高并发处理
- 【习题 8-10 UVA - 1614】Hell on the Markets
- activemq linux 100M,Linux下安装 activemq 并指定jdk 1.8(示例代码)
- 最大熵模型中的数学推导
- 手写键盘计算机,鼠标手写输入法计算机版本v2017最新版本
- 清华等7校联考时间确定 北大联盟增至13所
- My Fifty-Seventh Page 递增子序列 - By Nicolas
- ospfdr选举规则_DR/BDR详细选举过程
- 强势崛起!这所年轻大学南科大,是中国高教的奇迹!
- 你还在以为打马赛克就安全了吗?AI消除马赛克,GitHub开源项目上线三天收获近7000星
- html5研究背景及意义,基于HTML5的统计图表系统的研究与设计
- 艰涩难懂,不存在的,消息队列其实很简单