最近读到去年I3D上面的一篇论文,Shadow Caster Culling for Efficient Shadow Mapping,觉得不错,这里简单总结一下。对于算法的基本原理还是比较容易理解的,可以见下图所示。从图中可以看出对于当前某特定帧下的Camera来说,其可见的几何体元是整个场景的一个有限子集,而需要做阴影计算的也必然是这些可见几何体元集的一个子集,因而在生成Shadow Map时就可以只将那些对于当前需要计算SM的Shadow receiver有所影响的Shadow Caster投影绘制到SM中去(比如在下图所示中就可以只绘制C到SM中去,而C0,C1...Cn都是可省去的)。

这个算法的核心就是计算出这样一个优化的Caster集合来避免无谓的Caster绘制。算法的基本流程如下所列:

  1. 首先需要确定Shadow Receiver的集合
  2. 利用Receiver来创建Caster的Mask以供下一步Caster向SM中的渲染时使用
  3. 利用Caster Mask并结合Culling操作来进行高效的Caster渲染
  4. 常规的Shadow Mapping操作

其中最关键的就是第二步,即如何使用Receiver集合来创建Caster的Mask以供下一步阴影投射体的渲染时使用。这里的Mask其实也就是一张包含需要绘制的Caster的投影的Stencil Buffer或贴图,其使用原理与Occlusion Culling是一样的。这里的Receiver集合是对场景在当前Camera下进行裁剪的结果集,这也就要求引擎的裁剪系统有这么样的一个集合提取功能。关于Caster mask的生成文中给出了四种方法:

Bounding Volume Mask

这是一种最直接同时也最为保守的方法,直接使用几何体元的包围体来投影生成Mask。这里包围体的类型也就可以有多种选择,比如AABB,Sphere,OBB等,当然不同类型的包围盒对最终的精度也是会产生不同影响的。

Geometry Mask

这种方法在包围体的基本上进一步提高了精度,直接使用几何体元本身进行绘制来生成Mask。其相对于BVM来说精度提高了很多,但随之而来的问题就是渲染的效率,但是其也有另外的一个好处就是对于那些既是Caster又同时是Receiver的体元来说在生成Mask的同时就可以更新写入depth到SM中去,省去了下一步SM生成时的一些操作。

Geometry & Bounding Volume Mask

鉴于BVM与GM两者的优缺点,也可以将两者进行结合进行使用。这种方法需要将Reciver集合进行分类并从中提取出Receiver和Caster的交集,对于这些几何体使用GM的方法来操作,这样就避免了下一步SM中的depth写入;而对于其它的几何体则直接使用BVM的方法进行操作。这里对于需要使用Geometry Mask进行绘制的体元的判断采用了Temporal coherence的方法来实现,如果一个Receiver在上一帧的SM中可见那么在当前帧中将其视为既是Receiver&Caster,使用GM的方法来更新Mask。

Fragment Mask

在上述三种方法是最为精确的应该是Geometry Mask的方法了,但是其在某些情况下仍然会得到过于保守的Mask结果,这样就对后续的SM生成并没有多少效率上的提升,比较极端且典型的情况如下图所示:

图中很大的曲面可能是场景中的一个较大的地形(整个地形属于一个单一的几何体元,也即上述的一个Geometry单位),在当前的Camera下,其可能只有很少一部分可见。但是这种情况下不管是BVM还是GM都需要将其完全绘制到Mask 中去,而由于其本身很大,所以可能直接将整个Mask填满,如此一来所有的Caster就都需要绘制,没有起到Caster culling的作用。此时更加精确的方法是提取出其中的Camera可见部分并将其写入到Mask中去。这里又有两种方法:

  1. 将较大的物体进行细分然后处理成多个独立的、较小的几何体元来进行操作。这样虽然不能达到完全精确,但却至少可以减少写入到Mask中的无用区域的范围以便提高下一步Caster culling的裁剪力度。
  2. 使用逐Pixel比较的操作来精确提取可见部分,这其实也相当于提前进行了一次Quasi Shadow Mapping的操作。比如对于上图中几何体元中的像素A,需要判断其是否是Camera中的Receiver点,这可能就需要记录一些当前Camera下的几何体元投影信息(如果有G-Buffer就可以直接使用),然后在Light Space中投影A到Camera space下并做一系列的判断得到结果。如果其是Receiver则将其更新到Mask中,若不是则丢弃之。如此一来就可以计算了精确的Mask。

上述几种方法中,最后一种方法虽然精度高但是操作起来较为复杂,而且对引擎的改动影响较大,最后得到的结果可能会得不偿失。个人觉得还是第三种方法比较实用些,如果现有的引擎中有比较完善的Culling系统的话那么其应用起来不是太复杂,而且性能应该有不错的提升。

Shadow Caster Culling相关推荐

  1. Unity 2D光照(2D Light)和阴影(Shadow Caster 2D)

    前言 在上一篇我们简单了了解了Unity 2D动画的实现,在这一篇中,我们来学一下Unity的2D Light,给我们的2D动画添加上光照效果,简单的效果图如下: 首先先分享一个B站上别人翻译了的视频 ...

  2. rendering omni shadow in one pass.

    通常而言, 对于不支持TextureArray 的设备(D3D9 是完全不支持的), 渲染omni light shadow 通常的做法是. shadow generation:for (int fa ...

  3. [E]PSM算法简析

    转自: http://www.graphicsgeeks.org/index.php?title=PSM&oldid=153 (图形学极客) 参照:http://www.opengpu.org ...

  4. Unity 性能优化:降同屏Tris、动态合批降DC、遮罩剔除、渲染路径

    前言: 元宵节快到了,想要做一个上千盏孔明灯的场景,由于不懂建模,于是在Asset Story找了一套模型,结果找的灯笼模型精细度超标,当在游戏场景中实例化出四百个孔明灯时,帧率只有十帧左右 为了使得 ...

  5. 2020年度大赏 | UWA问答精选

    UWA每周推送的知识型栏目<厚积薄发 | 技术分享>已经伴随大家走过了252个工作周.精选了2020年十大精彩问答分享给大家,期待2021年UWA问答继续有您的陪伴. UWA 问答社区:a ...

  6. LoS - 2D 视野、光影相关技术研究及分享

    About / 关于 一句话介绍一下这个项目,就是基于 Cocos 引擎的 2D 光线追踪.视野范围计算及渲染相关的东西. Resources / 资源 Repository / 仓库 SSRLoS- ...

  7. Unity Draw call batching小结

    文章目录 DrawCalls 和 Batches draw call就是你知道的那个draw call draw call不一定意味着状态切换 静态batching 静态batching更费内存 静态 ...

  8. Draw Call未被批处理?在Unity 5.6中如何查找原因

    unity在5.6之前的版本中并未提供很直接的方式来查找Draw Call未被批处理的原因,但Unity 5.6在Frame Debugger中新增了一项功能,帮助开发者查找相关信息.今天这篇文章就为 ...

  9. Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(2)

    Lighting and Shadowing 现代的游戏中,基本没有物体能在一步就完成渲染,这是因为有光照和阴影的关系.光照和阴影的渲染在Fragment Shader中需要额外的pass. 首先要设 ...

最新文章

  1. [DB那些事]数据库加密
  2. Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)
  3. java解惑你知道多少_Java解惑
  4. 《学习之道》第四章学习语言和记忆痕迹
  5. 利用IDM工具下载ESA上的Sentinel数据
  6. 淮阴工学院计算机学院机房,实验室开放
  7. JRebel Idea热更新插件
  8. DDoS功击的判定方法和防护措施
  9. Office 程序默认打开方式
  10. OpenCV学习笔记总结
  11. apache camel 相关配置_Web基础配置篇(二): Maven配置及使用
  12. 逻辑卷管理和磁盘配额
  13. vue中实现简单切换图片效果
  14. Win7系统C盘空间太小怎么扩容【系统天地】
  15. rabbitmq集群安装与配置(故障恢复)
  16. 流程图-一些要点总结
  17. 重磅!李飞飞、颜宁等9位华人当选美国艺术与科学院院士,DeepMind创始人也成新晋院士!
  18. JavaWeb_04_ELJSTL
  19. 在linux下搭建私有云
  20. 新建 Microsoft Office Word 文档(C语言)

热门文章

  1. JavaScript 中 innerHTML 属性
  2. 2018.7.26 为RapidMiner5进行插件扩展(extension)开发
  3. Supervisor的使用
  4. 贪吃蛇-EasyX版
  5. tensorflow: bn层 的 decay参数项
  6. Windows如何使用sh
  7. linux dmesg查看时间,查看dmesg中的时间
  8. 个人隐私保护法_浅学一下
  9. 在API 中,常用的code码
  10. 3天25顿的潮汕美食记