http://www.cnblogs.com/polobymulberry/p/5126892.html?utm_source=tuicool&utm_medium=referral

回到顶部

1. rendering path的技术基础


在介绍各种光照渲染方式之前,首先必须介绍一下现代的图形渲染管线。这是下面提到的几种Rendering Path的技术基础。

目前主流的游戏和图形渲染引擎,包括底层的API(如DirectX和OpenGL)都开始支持现代的图形渲染管线。现代的渲染管线也称为可编程管线(Programmable Pipeline),简单点说就是将以前固定管线写死的部分(比如顶点的处理,像素颜色的处理等等)变成在GPU上可以进行用户自定义编程的部分,好处就是用户可以自由发挥的空间增大,缺点就是必须用户自己实现很多功能。

下面简单介绍下可编程管线的流程。以OpenGL绘制一个三角形举例。首先用户指定三个顶点传给Vertex Shader。然后用户可以选择是否进行Tessellation Shader(曲面细分可能会用到)和Geometry Shader(可以在GPU上增删几何信息)。紧接着进行光栅化,再将光栅化后的结果传给Fragment Shader进行pixel级别的处理。最后将处理的像素传给FrameBuffer并显示到屏幕上。

回到顶部

2. 几种常用的Rendering Path


Rendering Path其实指的就是渲染场景中光照的方式。由于场景中的光源可能很多,甚至是动态的光源。所以怎么在速度和效果上达到一个最好的结果确实很困难。以当今的显卡发展为契机,人们才衍生出了这么多的Rendering Path来处理各种光照。

2.1 Forward Rendering

Forward Rendering是绝大数引擎都含有的一种渲染方式。要使用Forward Rendering,一般在Vertex Shader或Fragment Shader阶段对每个顶点或每个像素进行光照计算,并且是对每个光源进行计算产生最终结果。下面是Forward Rendering的核心伪代码[1]。

For each light:For each object affected by the light:framebuffer += object * light

比如在Unity3D 4.x引擎中,对于下图中的圆圈(表示一个Geometry),进行Forward Rendering处理。

将得到下面的处理结果

也就是说,对于ABCD四个光源我们在Fragment Shader中我们对每个pixel处理光照,对于DEFG光源我们在Vertex Shader中对每个vertex处理光照,而对于GH光源,我们采用球调和(SH)函数进行处理。  什么情况?

Forward Rendering优缺点

很明显,对于Forward Rendering,光源数量对计算复杂度影响巨大,所以比较适合户外这种光源较少的场景(一般只有太阳光)。

但是对于多光源,我们使用Forward Rendering的效率会极其低下。因为如果在vertex shader中计算光照,其复杂度将是,而如果在fragment shader中计算光照,其复杂度为 。可见光源数目和复杂度是成线性增长的。

对此,我们需要进行必要的优化。比如

2.2 Deferred Rendering

Deferred Rendering(延迟渲染)顾名思义,就是将光照处理这一步骤延迟一段时间再处理。具体做法就是将光照处理这一步放在已经三维物体生成二维图片之后进行处理。也就是说将物空间的光照处理放到了像空间进行处理。要做到这一步,需要一个重要的辅助工具——G-Buffer。G-Buffer主要是用来存储每个像素对应的Position,Normal,Diffuse Color和其他Material parameters。根据这些信息,我们就可以在像空间中对每个像素进行光照处理[3]。下面是Deferred Rendering的核心伪代码。

For each object: Render to multiple targets
For each light: Apply light as a 2D postprocess

下面简单举个例子[1]。

首先我们用存储各种信息的纹理图。比如下面这张Depth Buffer,主要是用来确定该像素距离视点的远近的。

图. Depth Buffer

根据反射光的密度/强度分度图来计算反射效果。

图.Specular Intensity/Power

下图表示法向数据,这个很关键。进行光照计算最重要的一组数据。

图.Normal Buffer

下图使用了Diffuse Color Buffer。

图.Diffuse Color Buffer

这是使用Deferred Rendering最终的结果。

图.Deferred Lighting Results

Deferred Rendering的最大的优势就是将光源的数目和场景中物体的数目在复杂度层面上完全分开。也就是说场景中不管是一个三角形还是一百万个三角形,最后的复杂度不会随光源数目变化而产生巨大变化。从上面的伪代码可以看出deferred rendering的复杂度为 。

但是Deferred Rendering局限性也是显而易见。比如我在G-Buffer存储以下数据

Depth

R32F

Normal + scattering

A2R10G10B10

Diffuse color + emissive

A8R8G8B8

Other material parameters

A8R8G8B8

这样的话,对于一个普通的1024x768的屏幕分辨率。总共得使用1024x768x128bit=20MB,对于目前的动则上GB的显卡内存,可能不算什么。但是使用G-Buffer耗费的显存还是很多的。一方面,对于低端显卡,这么大的显卡内存确实很耗费资源。另一方面,如果要渲染更酷的特效,使用的G-Buffer大小将增加,并且其增加的幅度也是很可观的。顺带说一句,存取G-Buffer耗费的带宽也是一个不可忽视的缺陷。

对于Deferred Rendering的优化也是一个很有挑战的问题。下面简单介绍几种降低Deferred Rendering存取带宽的方式。最简单也是最容易想到的就是将存取的G-Buffer数据结构最小化,这也就衍生出了light pre-pass方法。另一种方式是将多个光照组成一组,然后一起处理,这种方法衍生了Tile-based deferred Rendering。

2.2.1 Light Pre-Pass

Light Pre-Pass最早是由Wolfgang Engel在他的博客[2]中提到的。具体的做法是

  • (1)只在G-Buffer中存储Z值和Normal值。对比Deferred Render,少了Diffuse Color, Specular Color以及对应位置的材质索引值。
  • (2)在FS阶段利用上面的G-Buffer计算出所必须的light properties,比如Normal*LightDir,LightColor,Specular等light properties。将这些计算出的光照进行alpha-blend并存入LightBuffer(就是用来存储light properties的buffer)。
  • (3)最后将结果送到forward rendering渲染方式计算最后的光照效果。

相对于传统的Deferred Render,使用Light Pre-Pass可以对每个不同的几何体使用不同的shader进行渲染,所以每个物体的material properties将有更多变化。这里我们可以看出相对于传统的Deferred Render,它的第二步(见伪代码)是遍历每个光源,这样就增加了光源设置的灵活性,而Light Pre-Pass第三步使用的其实是forward rendering,所以可以对每个mesh设置其材质,这两者是相辅相成的,有利有弊。另一个Light Pre-Pass的优点是在使用MSAA上很有利。虽然并不是100%使用上了MSAA(除非使用DX10/11的特性),但是由于使用了Z值和Normal值,就可以很容易找到边缘,并进行采样。

下面这两张图,左边是使用传统Deferred Render绘制的,右边是使用Light Pre-Pass绘制的。这两张图在效果上不应该有太大区别。

2.2.2 Tile-Based Deferred Rendering

TBDR主要思想就是将屏幕分成一个个小块tile。然后根据这些Depth求得每个tile的bounding box。对每个tile的bounding box和light进行求交,这样就得到了对该tile有作用的light的序列。最后根据得到的序列计算所在tile的光照效果。[4][5]

对比Deferred Render,之前是对每个光源求取其作用区域light volume,然后决定其作用的的pixel,也就是说每个光源要求取一次。而使用TBDR,只要遍历每个pixel,让其所属tile与光线求交,来计算作用其上的light,并利用G-Buffer进行Shading。一方面这样做减少了所需考虑的光源个数,另一方面与传统的Deferred Rendering相比,减少了存取的带宽。

2.3 Forward+

Forward+ == Forward + Light Culling[6]。Forward+很类似Tiled-based Deferred Rendering。其具体做法就是先对输入的场景进行z-prepass,也就是说关闭写入color,只向z-buffer写入z值。注意此步骤是Forward+必须的,而其他渲染方式是可选的。接下来来的步骤和TBDR很类似,都是划分tiles,并计算bounding box。只不过TBDR是在G-Buffer中完成这一步骤的,而Forward+是根据Z-Buffer。最后一步其实使用的是forward方式,即在FS阶段对每个pixel根据其所在tile的light序列计算光照效果。而TBDR使用的是基于G-Buffer的deferred rendering。

实际上,forward+比deferred运行的更快。我们可以看出由于Forward+只要写深度缓存就可以,而Deferred Render除了深度缓存,还要写入法向缓存。而在Light Culling步骤,Forward+只需要计算出哪些light对该tile有影响即可。而Deferred Render还在这一部分把光照处理给做了。而这一部分,Forward+是放在Shading阶段做的。所以Shading阶段Forward+耗费更多时间。但是对目前硬件来说,Shading耗费的时间没有那么多。

Forward+的优势还有很多,其实大多就是传统Forward Rendering本身的优势,所以Forward+更像一个集各种Rendering Path优势于一体的Rendering Path。

回到顶部

3. 总结


首先我们列出Rendering Equation,然后对比Forward Rendering,Deferred Rendering和Forward+ Rendering[6]。

3.1 Rendering Equation

其中点 处有一入射光,其光强为 ,入射角度为 。根据函数 和 来计算出射角为 处的出射光强度。最后在辅以出射光的相对于视点可见性 。注意此处的 为场景中总共有 个光源。

3.2 Forward Renderng

由于Forward本身对多光源支持力度不高,所以此处对于每个点 的处理不再考虑所有的 个光源,仅仅考虑少量的或者说经过挑选的 个光源。可以看出这样的光照效果并不完美。另外,每个光线的 是计算不了的。

3.3 Deferred Rendering

由于Deferred Rendering使用了light culling,所以不用遍历场景中的所有光源,只需遍历经过light culling后的 个光源即可。并且Deferred Rendering将计算BxDF的部分单独分出来了。

3.4 Forward+ Rendering

可以看出Forward+和Forward最大区别就是光源的挑选上有了很到改进。

回到顶部

参考文献

[1] Shawn Hargreaves. (2004) “Deferred Shading”. [Online] Available:

http://hall.org.ua/halls/wizzard/books/articles-cg/DeferredShading.pdf (April 15,2015)

[2] Wolfgang Engel. (March 16, 2008) “Light Pre-Pass Renderer”. [Online] Available:

http://diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.html(April 14,2015)

[3] Klint J. Deferred Rendering in Leadwerks Engine[J]. Copyright Leadwerks Corporation, 2008.

[4] 龚敏敏.(April 22, 2012) “Forward框架的逆袭:解析Forward+渲染”. [Online] Available:

http://www.cnblogs.com/gongminmin/archive/2012/04/22/2464982.html(April 13,2015)

[5] Lauritzen A. Deferred rendering for current and future rendering pipelines[J]. SIGGRAPH Course: Beyond Programmable Shading, 2010: 1-34.

[6] Harada T, McKee J, Yang J C. Forward+: Bringing deferred lighting to the next level[J]. 2012.

转载于:https://www.cnblogs.com/nafio/p/9137329.html

渲染路径-实时渲染中常用的几种Rendering Path相关推荐

  1. 【原】实时渲染中常用的几种Rendering Path

    [原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 -- polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...

  2. UML中常用的几种图

    浅谈UML中常用的几种图 1 UML简介 2 UML常见图分类 3 用况图(用例) 4 类图 简单类图使用 举例 5 其他辅助用图 时序图(顺序图) 协作图(Collaboration Diagram ...

  3. 注册表:HKCR, HKCU, HKLM, HKU, HKCC,注册表中常用的5种数据类型

    注册表是Microsoft Windows中的一个重要数据库.用于存储系统和应用程序的系统信息. Windows 3.0 注册表已经出现 Windows NT 广泛使用注册表的操作系统 Microso ...

  4. Python 编程中常用的12种基础知识总结

    Python 编程中常用的12 种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出 ...

  5. python编程中常用的12种基础知识总结

    python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进 ...

  6. php三个数字比较大小排序,php中常用的4种实现数字大小排序的冒泡选择等算法函数代码...

    分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中按照从小到大的顺序进行排序. 本站收录这篇文章php中常用的4种实现数字大小排序的冒泡选择等算法函数代码,详细解说文章中相关排序 冒泡 ...

  7. java中常用的几种排序算法--常见笔试面试

    转载:http://blog.csdn.net/ygc87/article/details/7208082 以下列出Java中常用的几种排序算法,只是简单实现了排序的功能,还有待改进,望指教(以下均假 ...

  8. 【温故知新】——原生js中常用的四种循环方式

    一.引言 本文主要是利用一个例子,讲一下原生js中常用的四种循环方式的使用与区别: 实现效果: 在网页中弹出框输入0   网页输出"欢迎下次光临" 在网页中弹出框输入1   网页输 ...

  9. pytorch梯度下降函数_Pytorch中常用的四种优化器SGD、Momentum、RMSProp、Adam

    来源:AINLPer微信公众号 编辑: ShuYini 校稿: ShuYini 时间: 2019-8-16 引言     很多人在使用pytorch的时候都会遇到优化器选择的问题,今天就给大家介绍对比 ...

最新文章

  1. 关系数据库的数据迁移
  2. ESP8266之2M脚本
  3. anaconda打不开没反应_为什么账户总是有点击没对话?无非这2个原因
  4. IP分片和TCP分段的区别
  5. (转)智能投顾只能这么搞!美国证监会发15页指南
  6. 毕设/私活/必备,一个挣钱的标准开源前后端分离【springboot+vue+redis+Spring Security】脚手架--若依框架
  7. 以下数据库收录外文文献全文的有_除了SCIHUB,这十大外文文献下载数据库也应该一试!...
  8. C语言实现strcmp函数
  9. 软件项目管理 6.6.三点估算法
  10. pad平板性能测试软件,苹果iPad 2020款评测,最便宜的iPad,性能碾压安卓?
  11. DWZ 富文本编辑器 IE下失去焦点
  12. ORB-SLAM3论文详细解读
  13. 30岁后的测试工程师都去哪儿了?
  14. GOM GEE引擎的传奇SF“怪物召唤卷”功能脚本实例分享
  15. 电脑怎么连接隐藏的无线WiFi ?
  16. 用Websocket聊天完整demo,做笔记用,各位大佬多多指教
  17. 赋能 打造应对不确定性的敏捷团队 pdf_协会成长课堂|《赋能》:打造应对不确定性的敏捷团队...
  18. 安装python包的时候文件夹权限报错:InvalidArchiveError(“Error with archive D:\\anaconda\\pkgs\\cudnn-8.4.1.50-h)
  19. jQuery canvas碎片粒子组成爱心图形动画特效
  20. 马士兵java ppt_[马士兵JAVA教程课件.ppt

热门文章

  1. WeRide to a Better World | 文远知行2019-2020校招启动!
  2. mysql hql查询语句_查询hql语句
  3. 游戏推箱子(c语言)
  4. golang 通用Contains方法
  5. vivo手机使用应用沙盒一键修改imsi数据
  6. 短视频软件开发中如何实现720P磨皮美颜录制?
  7. 运行python脚本卡住_为什么我的 Python 程序卡住啦!
  8. hdu-2612-Find a way(双bfs)
  9. 新能源时代,奇瑞老将陈剑将与奇瑞新能源共创辉煌
  10. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java汽车租赁系统00snr