« Shadow Map阴影贴图技术之探Ⅳ成员函数指针使用小感 »

Shadow Map Demo2

 这里是阴影帖图系列,伴随学习而写的DEMO系列。这些DEMO做得并不华丽,但却是让我持续学习不断深入的动力,理论与实践的血脉相连,尤其在这Cascaded Shadow Maps里体现充分了。——ZwqXin.com

 [Shadow Map阴影贴图技术之探Ⅳ]

本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
      原文地址:http://www.zwqxin.com/archives/opengl/shadow-map-demo-2.html

 实现的过程是个蛮曲折的过程,出了[联结FBO与Texture Array] 中提及的事故,也有[成员函数指针使用小感]之类必须想办法查资料解决的问题(这里稍微穿越一下)。其实自[Shadow Map Demo1]的实现就觉得Shadow Map系列的实现其实一点也不比Shadow Volume简单,更麻烦的是遇到问题的时候很难调试。过程中NV SDK的CSM DEMO无疑是重要的指引与排错参考,但成也萧何败也萧何,它带来的麻烦也一点不少。最后还是紧随理论而走,这其中的理论知识也要感谢GPU GEMS 3中撰写PSSM一章的作者。总之,结果是这个小DEMO也终于有点让人安心地落户了。

如果我把整个调试历程分四阶段,那么第一无疑是最漫长最痛苦的,因为上面讲述的问题,一直没把shadow maps调出来,不断怀疑不断排错,甚至对照NV那个DEMO逐行比对,完全否定自己的思路……到了第二阶段弄出maps则是为其正确性以及场景产生的赝像排错(赝像是很可怕的,但直到第三阶段才明白它是必然出现的东西,只是某些地方没处理好[被glMatrixMode(GL_MODELVIEW)害惨了],让它进入了视野)。

www.zwqxin.com  shadow map demo2
(第二阶段调试ING)
www.zwqxin.com  shadow map demo2
首先得辛苦这个车模型了,DEMO漫长的调试时间里,是它一直陪伴到最后

第三阶段开始已经能弄出CSM的基础效果了。这时候则是完善场景,很重要的一步是在3DS MAX里处理网络收集的模型大小方向,然后导入模型后安排位置。纹理问题的解决(程序中各种纹理状态如glMatrixMode(GL_TEXTUREi)的调正恢复)后就是增加一点视觉上的东西(RocCircle)。也是在此发现实现中应该考虑的视锥外投影物处理的事情。

www.zwqxin.com  shadow map demo2
(第三阶段调试ING)
www.zwqxin.com  shadow map demo2
(DEMO 全场景)

这里是汽车的陈列台(另感谢模型提供者www.3lian.com)。注意上下两图的区别。在不处理视锥外投影物情况下,近看地面是不会出现RocCircles的影子的,远看则会出现。因为这些RocCircles有些在视锥里有些在视锥外,而我们能看到的只有"Splited 视锥"包围盒内投影物的阴影,只有把视锥范围加大至其包围盒包含这些RocCircles时,地面才会被投影。详细见[Shadow Map阴影贴图技术之探Ⅳ] 。为此进行的是第四阶段调试,顶空直升飞机。

www.zwqxin.com  shadow map demo2
(CROP MATRIX0 广场视觉:这时候helicopter处于第三视锥包围盒内,故能投影)
www.zwqxin.com  shadow map demo2
(CROP MATRIX0 广场视觉:这时候helicopter处于第二视锥包围盒与光源之间空域,故不能投影)

www.zwqxin.com  shadow map demo2
(CROP MATRIX1 局部视觉:更改光源投影矩阵,设置近投影面为-1,这时候无论眼睛去到哪里都能看到helicopter的阴影了)

再强调一下,虽然设置近投影面为-1来生成CROP MATRIX1(见[Shadow Map阴影贴图技术之探Ⅳ])是PSSM的推荐做法,但是毕竟这样会损害Shadow Maps的清晰度,所以还是保留不强制设置的原法,当不需要高空物体投影的场合,用这个方式更恰当。在DEMO中用键盘1键表示应用CROP MATRIX0(默认),用2键表示应用CROP MATRIX1。

事实上还应该分为Screen Independent的CROP MATRIX和Screen Dependent的CROP MATRIX(见GPU GEMS3),以上都是属于前者的,因为它到底只是参考了“Splited视锥”的包围盒。这可能是有点浪费的——有时候Shadow Maps上就那么一小块地域有投影物(尤其越大的视锥这种浪费越明显)——这时候就可能要综合考虑投影物集合(casters)的包围盒、“Splited视锥”的包围盒和投影接收物(recervers)的包围盒了。注意是取三者中覆盖范围最小的那个包围盒,这样才能使Shadow Maps中最充盈地包含“Shadows”。但这要分析场景,设置各个集合,生成包围盒,在本DEMO里就不想深入去了(本来想弄但万一陷进去了……或者后版本里在下会添加吧)。

最后是DEMO一点点后续说明:

www.zwqxin.com  shadow map demo2
(在末视锥里阴影几乎消失)
www.zwqxin.com  shadow map demo2
(光源大幅度偏离场景后车阴影出现)

Cascade切换的时候,物体影子可以相差很大,这是基于应用可以调节的(譬如分割算法的mix因子,真整个大视锥的线性长度Zfar-Znear,光源高度[对点光源]、角度等等)。尤其是最后的“Splited视锥”和其前一个相差很大,在本DEMO中当进入最后的cascade时,车的阴影基本消失了。其实从阴影图(按HOME键打开)可以看出,这时候或许只有第四张Shadow map有车模的阴影,但车的高度毕竟太小了所以阴影几乎是“融进地面”的(而且看不清吧,就该阴影图的分辨率而言)。注意当切换虚拟点光源位置时(向X正方向),微弱的阴影逐渐出现了。

DEMO采用点光源模式但是投影依然是正交投影,所以可以说该光源与阴影并不对应,只是为了取得一些感受而已(场景对平行光产生的diffuse太单调了)。场景视觉、光源视觉的设置等都是为了方便调试而已。在这些视觉下会看到一些可怕的赝像,没什么关系的(吧?)。

www.zwqxin.com  shadow map demo2

寒假到此为止,先后熟悉了两大阴影算法Shadow Volume和Shadow Map,接下来是什么呢?也许是LiPSM,也许是更新鲜的阴影帖图算法,也许是更高效率的阴影锥改进,也许是结合Geometry shader的阴影锥生成,也许是软阴影……其实,一切也许才刚开始呢,只要继续这条图形学学习之路。

 Demo相关:

视觉Camera:鼠标左键+鼠标移动/滚动
光源位置:→   ←   ↑   ↓  PageUp  PageDown

鼠标右键:光源自动旋转开关
空格键:光源视线viusualize
HOME键:Shadowmaps viusualize

三种视觉:
局部视觉[LocalEye]:DELETE键
场景视觉[SceneEye]:END键
光源视觉[LightEye]:INSERT键
(注:调整为只有局部视觉下阴影符合)

两种CropMatrix(见上述):
键 1:CropMatrix1
键 2:CropMatrix2

www.zwqxin.com  shadow map demo2

本DEMO使用了shader,需要下载glew库到指定目录,下载见此:OpenGL常用的库
放上本DEMO:CascadedShadowMapsDemobyZwqXin.rar

本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
      原文地址:http://www.zwqxin.com/archives/opengl/shadow-map-demo-2.html

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2013 ZwqXin. All Rights Reserved. Theme edited from ipati.