漫谈游戏中的阴影技术(阴影技术比较)

摘要:
本文介绍了shadow在当前游戏中的实现。ProjectiveShadow中阴影技术投影的原理可以应用于任何地图,这称为阴影投影。有必要将顶点从设备空间转换为贴图空间。场景中对象渲染的管理对于实时应用也是一个挑战。首先,它需要根据作为视点的光源的位置来渲染整个场景,以获得它们相对于光源的深度信息,然后使用这些深度信息来确定场景的哪个部分在阴影中。

http://blog.sina.com.cn/s/blog_55288aa20100e2fk.html

随着硬件的越来越高端化,各种以前可望而不可及的效果越来越多的应用到网络游戏里。本篇文章是介绍目前游戏中影子的实现方式,它们的优缺点以及应用的场合。

一般来说,在游戏中,应用比较多的影子技术有三种,Projective shadow, Shadow map以及Shadow map.我们接下来便依次的介绍它们。
Projective Shadow  
漫谈游戏中的阴影技术
投影的原理可以应用在任意贴图上
 
就是我们通常所说的投射影子,它的实现比较简单,具体有两个步骤:
1.  以光源为视点,渲染有影子的物体到一张预备好的Shadow texture中。要注意的是,这里的渲染在计算投影的时候,需要把顶点从设备空间转换到贴图空间,以便于后面的贴图。
2.  渲染被影子覆盖到的物体,然后把影子覆盖到物体上。这里是整个Projective shadow的最为关键的步骤。通过上面提供的Shadow Texture,可以使用一个PASS把受影子影响的物体渲染出来。也可以根据实际应用通过Blend,使用多个PASS来渲染。在渲染Shadow Texture的时候,需要API来为它生成最后的贴图坐标。在DX中,你需要把D3DTSS_TEXCOORDINDEX设置成D3DTSS_TCI_CAMERASPACEPOSITION;同时把D3DTSS_TEXTURETRANSFORMFLAGS设置为D3DTTFF_PROJECTED。如果你使用OGL,可以把GL_TEXTURE_GEN_MODE设置GL_EYE_LINEAR, 同时设置纹理矩阵为投影纹理矩阵。
 
Projective Shadow原理简单,实现方便,对于硬件配置的要求很低,效果也不错。对于对影子效果要求不高的游戏来说,只需要不多的代码就可以加入。但是由于Projective Shadow是需要计算能被影子投射到的对象,需要根据影子Caster来计算出它所对应的Receiver,这个步骤当场景对象过多的话会大量消耗CPU时间。同时,对于场景中物体渲染的管理也是对于实时应用的一个挑战,我们必须小心的管理物体渲染的层次关系。
 
Shadow Map Shadow Map是一种成熟已久的技术,对于它的原理,很多初涉图形学的爱好者都能够很清晰的讲出他的实现步骤。简单来说,它是一种基于图像空间的技术。首先它需要根据光源的位置作为视点把整个场景渲染出来以得到它们相对于光源的深度信息,然后再使用这些深度信息去决定场景中哪一个部分是处于阴影之中的。
                                           漫谈游戏中的阴影技术
判断点是否处在阴影中
 
标准的Shadow Map,在DX SDK中你就能找到它的例子,看起来它的实现也并不复杂。但不幸的是它的作用也只是停留在能够教学。换句话说,它一点都不实用,即使在例子中,你也能很容易的发现它的缺点。
首先它的精度不够,虽然DX的例子还能看得过去,但由于Shadow Map是基于整个场景来渲染的,也就是说,它会用一张贴图来渲染整个场景的影子。这样来说,用于存储信息的贴图大小就直接影响到影子的质量。小场景还勉强能够应付,但只需要碰到稍大的场景,影子就有可能出现很严重的锯齿,影响到影子的质量。另外深度缓冲的精度也是难于解决的,特别是当影子的Caster和Receiver很接近的时候,Z-Fighting的情况发生得非常明显。
当然Shadow Map也有自己的优点,实现方便,效率较高,易于理解等,尤其是由于它是基于图像空间的一项技术,可以用不大的代价就实现软阴影的效果。所以近些年来,很多图形学的学者也基于Shadow Map的原理提出了很多改进型的算法,Shadow Map也越来越多的应用到了大型的游戏中。我们要介绍的也是一种Shadow Map很重要的改进算法的思想――Perspective Shadow Map(PSM),需要注意的是,这种思想的本身也是不尽完美的。但是以它为主导思想,近些年来提出了不少新型的算法。
PSM是在当前摄像机的透视后的空间中计算中,用传统图形学的说法,就是归一化后的设备空间中计算的。它的基本想法是首先把场景映射到Post-perspective空间中,然后在这个空间中通过把变换后的光源转换到一个归一化空间里生成一个标准的Shadow map。
如下图,S是场景Bounding,L光产生的视锥,V是视锥,而M包含了所有从V到L的涉嫌。这个算法比较关键的是最后能够生成下图中黄色的区域H,H包含了所有Shadow Map所需要包含的空间。这也是生成Post-Perspective空间的最小Bounding。
漫谈游戏中的阴影技术
 
有了Bounding之后, Post-Perspective空间的视点就很容易得到了。
根据以上的计算得到Post-Perspective空间的矩阵之后。其他的步骤就和标准的Shadow Map是一致的了。
漫谈游戏中的阴影技术
标准的Shadow Map
漫谈游戏中的阴影技术
Perspective Shadow Map
 
同样的视点,同样的贴图大小,使用PSM我们可以得到更加细致的效果。
但PSM也有一些缺陷,比如说影子的质量比较依赖视点,影子近处和远处所得到的Z分布差异过大等。近些年提出的TSM,LISPSM都基于PSM的原理使得这些问题得到了一些改进,也使得Shadow map更多的使用到游戏中。
Shadow Volume Shadow Volumes技术是一种基于几何形体的技术,它需要几何体在一定方向的灯光下的轮廓去产生一个封闭的容积,然后通过光线的投射就可以决定场景的阴影部分(通常来说使用模板缓冲去模拟光线的投射)。
这种技术最大的优点就是影子可以精确到像素级别。影子的效果会很细致。但它也有一些缺点,首先对几何体有一定的要求(必须是闭合的),同时对于效率的损耗也非常大(高填充率)。
为了构造阴影体,我们需要从灯光的位置引出通过要投射影子物体的每个顶点,这些投射的射线组成了一个封闭的体积,任何处于这个体积中的点我们便可以认为它是被阴影覆盖。反之,处于体积之外的点便是处于光照中的。
 
漫谈游戏中的阴影技术
处于阴影体中的物体才会接收到影子
 
通常来说,判断物体是否处在阴影中有两种基本算法:Z-PASS和Z-FAIL。简单来说Z-PASS算法是从视点引一条射线,当射线进入阴影体的时候,stencil加1,当射线出阴影体的时候,stencil就减1。这样的话,如果stencil的值在计算完成后为0,就代表物体不处在阴影中。对于Z-Fail算法,不同的是在渲染阴影体的时候,对于back face和front face的情况做了一些特殊的判断,当对于back face 的Z test失败的时候,stencil值加1,而对于front face的Z test失败的时候,stencil值减1。
对于构建Shadow volume来说,找出物体的轮廓线很重要。基本的思想就是找出所有朝向相反的两个三角形的共享边,最终组成整个物体的轮廓。
 
总结 本文讲解了目前主流的几种生成阴影的方式。总体来说,各自都有应用的场合。Projective shadow比较适合应用在对效率要求比较高,对影子要求不是完全真实的场景中。Shadow map比较适合用于场景中静态物体的影子渲染,它也能实现比较柔和的软阴影。而Shadow Volume更适合于场景中的动态物体,比如说角色,怪物,风车等。大家可以根据自己具体项目的特点和需求来选择合适的技术。

免责声明:文章转载自《漫谈游戏中的阴影技术(阴影技术比较)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇(转)理解Android系统的进程间通信原理(一)RPC中的代理模式nodemon 自动重启nodejs服务下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解

全面——你知道吗?1891年,卡尔森纳做出的第一把瑞士军刀,只有螺丝刀和开罐器。经过一代又一代能工巧匠的打磨,这把刀陆续增加了锯子、剪刀、镊子、放大镜、改锥,甚至内藏激光、LED手电筒、USB记忆碟等功能。 稳定——你知道吗?公元前1500多年前,埃及人就已经用绳子和竖棍做成了简易天平,成为现代天平的雏型。天平是平衡的象征,托盘内不断增加的砝码,更是自...

时隔半年,重新尝试番茄

我有时候在思考,到底自己还有哪些缺点和坏习惯?就算是自己找到了,自己有没有有效的方法进行纠偏? 我一天的工作效率到底是多少? 领导分配给我们组任务是负责产品中心项目和任务调度项目,今年下半年又有一个运维和开发工作更重的API平台。 我和一个有接近一年经验的毕业生暂时负责这三个项目。 这是很正常的现象,随着我们的经验的积累同时在公...

[安卓开发]App Widget开发入门指导

      本节所要讲的主要内容包括Android桌面小部件、App Widget的开发入门指导,并通过一个简单实例的形式来直观的讲解App Widget。        一、Widget 、App Widget 、Web App 的概念        Widget最初的概念是98年一个叫Rose的苹果工程师提出,直到2003年的时候才正式为大家所知,不过...

Threejs 开发3D地图实践总结

  前段时间连续上了一个月班,加班加点完成了一个3D攻坚项目。也算是由传统web转型到webgl图形学开发中,坑不少,做了一下总结分享。 1、法向量问题   法线是垂直于我们想要照亮的物体表面的向量。法线代表表面的方向因此他们为光源和物体的交互建模中具有决定性作用。每一个顶点都有一个关联的法向量。   如果一个顶点被多个三角形共享,共享顶点的法向量等于...

Unity3D的GUI插件(UIToolkit,GUIX)

在Unity的社区里发现一个不错的UI插件----UIToolkit. https://github.com/acron0/UIToolkit/downloads 下载资源包后,导入到Unity3D中即可。可以看下如下的一些东西: 上面三个是显示的DEMO,最后一个就是这个插件的核心代码了。 使用步骤: 1.创建一个新的层。这边我命名为“UILayer"...

一个研发团队是如何坚持7年技术分享的?

    ——“所有分享都是有意义的” ——“在PingCode,人人都可以成为分享者” 这是PingCode研发团队的分享精神,而这样的精神,在过去7年中已经闪耀了100次。 2020年10月24日,PingCode开发者大会百期盛典如期举行: 在一天的开发者大会中,分享者从公司CEO、CTO到研发的新老同学,他们围绕: 编程范式——编程世界的方法论与...