Deferred Shading

传统的渲染过程通常为:1)绘制Mesh;2)指定材质;3)处理光照效果;4)输出。传统的过程Mesh越多,光照处理越费时,多光源时就更慢了。

延迟渲染的步骤:1)Pass0先不做光照处理,将Mesh的Position信息和Normal信息绘制到纹理(RenderTargets,D3D支持多向输出);2)Pass1仅绘制屏幕大小的一个四边形,利用之前得到的Position纹理和Normal纹理对有效地区域选择性地进行光照处理,再输出最后的图像。

分析:由于延迟渲染将光照的处理量由空间转换到了平面,减少了光照等效果的计算量,提高了绘制速度,对多光源的绘制优势更为明显。

 

渲染流程

延迟渲染管线可分为四个阶段:geometry, lighting, composition, post-processing

Post-processing阶段与传统的forward shading没有太大差别,这里不提,只说明一下前三个阶段。

Geometry阶段:将本帧所有的几何信息光栅化到G-buffer。包括位置,法线,贴图等。

Lighting阶段:以G-buffer作为输入(位置,法线)进行逐像素的光照计算,将diffuse lighting和specular

Lighting 结果分别保存在两张RT上作为lighting buffer。

Composition阶段:将G-buffer中的贴图buffer和lighting buffer融合,得到渲染结果。

整体渲染过程并不复杂,但在实际的过程中还是有许多问题需要考虑的,下面一一列举。

G-buffer

Geometry阶段将几何信息渲染到multi render target上(MRT),当前最多支持4个MRT。并且驱动要求4个MRT必须相同的bit宽度。RT对显存占用过大会增加带宽,降低cache命中。而简单格式的RT又会影响画质。因此决定使用32bit的RT(如A8R8G8B8,R16G16F)或64bit宽度的RT(如A16R16G16B16F)。需要在画质和性能间做出折衷。(开发时尽可能可以方便的配置)。[1]中有一些性能比较。

MRT中必须的信息:position(depth), normal, diffuse(texture)

可能需要的信息:specular, power, emissive, ao, material id

这些信息需要在这4个RT上用合理格式,合理的组织。这里还可以就存储空间和shader的复杂性做折衷。如只保存depth,然后在光照时计算position[12]。以及用球面坐标保存法线[13]。以目前的资料得出的结论是应该尽可能地pack数据,减少内存占用,多出来的若干条shader指令不会明显影响性能。

光照计算

使用延迟渲染技术最大的好处就是可以渲染光照极为复杂的场景。这里场景中的光照可以分为两类。

影响整个场景的scene light。如directional light。渲染一个screen quad,逐像素光照计算,没什么好说的。

另一类是只影响一部分区域的local light。如点光源,聚光灯,以及特效等等。这些local light只影响到屏幕上的某些像素,当然不需要逐像素的进行光照计算。最简单的方法是绘制这些光源的包围体(点光源的包围体是球,聚光灯的包围体是圆锥),包围体的大小要大于等于光源的衰减范围。这些包围体经过变换投影到屏幕上的对应区域,随后在pixel shader中计算光照。

优化:

1.       光源包围体的视锥剔除,遮挡剔除。

2.       光源包围体投影后很小时剔除;若干个靠的比较近的小光源合并成一个较大的光源[11]

3.       光源包围体的backface culling

4.       屏幕空间中没有被光源照到的,或者被更近的物体遮挡住的像素不需要光照计算,因此可以逐像素的深度剔除。

a.       使用正确的stencil light volume。类似shadow volume的方案,将渲染light volume的正反两面,得到正确的stencil mask,然后光照计算时使用stencil buffer。这种方法可以得到正确的结果,但是需要渲染每盏灯时频繁改变render state,可能会带来一定性能上的损失。

b 使用z test,可以得到“一定程度上正确”的结果。

阴影

光照计算的同时计算阴影。使用传统的shadow map,预先生成一张阴影图。考虑在编辑场景的时候指定那些重要的光源才会产生阴影。在计算shadow map时要针对光源的binding volume进行剔除。

方向光和聚光灯可以使用基本的shadow map投影(正交投影,透视投影)。点光源会复杂一些,需要使用cubic shadow map。(考虑unwrapping method[14])

半透明

由于在延迟渲染的过程中只计算离屏幕距离最近的那个像素的光照,因此无法处理半透明物体的光照。

方案1

延迟渲染的过程中只处理不透明的物体,将所有半透明的物体放在渲染过程的最后,使用传统的forward shading渲染。

方案2

在Geometry阶段将半透明的物体和背景逐像素的交织起来,将透明度放在一个单独的通道中。按一般的方法计算光照。随后在composition阶段再根据透明度将透明物体和背景逐像素的混合起来。

优点:

光照一致性。半透明的物体也参加延迟渲染,可以接受多光源的光照。

简单并且健壮。不需要单独区分不透明物体和半透明物体,不需要单独的半透明渲染管道。

速度快。只增加了7到10条ps指令,两张贴图,只有约2%的性能损失。

缺点:

模糊。在半透明的物体上会有一点模糊,原因是在交织的过程中会有一定信息损失。

边缘锯齿。反交织的过程中半透明物体的边缘会产生一些锯齿。

只能有一层半透明。

多种材质

在延迟光照的过程中支持多种材质需要如下方案:

在G-buffer阶段输出材质的ID到G-buffer的一个通道中,随后在lighting阶段和composition阶段根据材质ID使用不同的光照函数计算光照。这种方案在sm 3.0中使用动态分支的前提下可以很好的工作。

反锯齿

Dx9 API不支持反锯齿的MRT,Dx10支持。

一种方案是使用超采样,先渲染到大的RT上,再downsample到正常的大小,得到没有锯齿的结果。延迟渲染的效率跟分辨率有很大关系,因此这种方法会极大的降低性能,基本不可取。

另一种方案是使用“intelligent blur”,只模糊物体边缘的像素:

根据相邻像素的深度和法线提取物体边界,然后对提取出的边界进行模糊。模糊时要避免不正确的泄露。如后面物体的颜色泄露到前面的物体上[11]。 总体而言实现会较为复杂。

另一种方案pre-lighting [8][9][17]

一种pre-z rendering 和deferred rendering的结合。G-buffer阶段只保存depth和normal,然后计算光照信息到lighting buffer,格式如下

LightColor.r * N.L * Att
LightColor.g * N.L * Att
LightColor.b * N.L * Att
R.V^n * N.L * Att

最后使用传统的forward shading再将整个场景渲染一遍,期间查询lighting buffer。

与普通的deferred shading相比:

优点:

占用带宽小,第一遍渲染只输出normal,depth是自动获得的。

可以用在较老的硬件平台上,不需要MRT支持。

对现有forward shading管道改动较小,比较容易实现。

缺点:

整个场景需要渲染两遍,相当于在pre-z和forward shading中间加了一个lighting stage。

Deferred Shading延迟渲染的更多相关文章

  1. Deferred Shading,延迟渲染(提高渲染效率,减少多余光照计算)【转】

    Deferred Shading,看过<Gems2> 的应该都了解了.最近很火的星际2就是使用了Deferred Shading. 原帖位置:   http://blog.csdn.net ...

  2. Deferred Shading 延迟着色(翻译)

    原文地址:https://en.wikipedia.org/wiki/Deferred_shading 在3D计算机图形学领域,deferred shading 是一种屏幕空间着色技术.它被称为Def ...

  3. opengl deferred shading

    原文地址:http://www.verydemo.com/demo_c284_i6147.html 一.Deferred shading技术简介 Deferred shading是这样一种技术:将光照 ...

  4. Deferred Shading(延迟渲染)

    1.简介      在计算机图形学的词典里,Shading表示“对受光物体的渲染”,这个渲染过程包括下面几步[1]: 1) 计算几何多边形(也就是Mesh).      2) 决定表面材质特性,例如法 ...

  5. Unity5 的新旧延迟渲染Deferred Lighting Rendering Path

    unity5 的render path ,比4的区别就是使用的新的deferred rendering,之前的4的deferred rendering(其实是light prepass)也被保留了下来 ...

  6. Deferred shading rendering path翻译

    Overview 概述 When using deferred shading, there is no limit on the number of lights that can affect a ...

  7. Unity的Deferred Shading

    什么是Deferred Shading Unity自身除了支持前向渲染之外,还支持延迟渲染.Unity的rendering path可以通过Edit/Project Settings中的Graphic ...

  8. DirectX11 With Windows SDK--36 延迟渲染基础

    前言 随着图形硬件变得越来越通用和可编程化,采用实时3D图形渲染的应用程序已经开始探索传统渲染管线的替代方案,以避免其缺点.其中一项最流行的技术就是所谓的延迟渲染.这项技术主要是为了支持大量的动态灯光 ...

  9. DirectX11 With Windows SDK--37 延迟渲染:光源剔除

    前言 在上一章,我们主要介绍了如何使用延迟渲染,以及如何对G-Buffer进行一系列优化.而在这一章里,我们将从光源入手,讨论如何对大量的动态光源进行剔除,从而获得显著的性能提升. 在此之前假定读者已 ...

随机推荐

  1. Python 基本数据类型和序列类型

    python 3.6.4 中,有9种数据类型: int, float, bool, complex, list, tuple, string, set, dict (1).int 整型,不可变 (2) ...

  2. iOS源代码管理svn

    01. SVN介绍 SVN 是集中式源代码管理工具 概念: 1> Repository   代码仓库,保存代码的仓库 2> Server       服务器,保存所有版本的代码仓库 3&g ...

  3. Asp.Net 5 Web Hook

    首先,然我们来看一下WebHooks是什么.WebHooks是一个协议.它们是HTTP回调技术.并且它们是"用户定义的HTTP回调".你和 (或) 您的应用程序在有什么事情发生时会 ...

  4. Difference Between ZIP and GZIP

    From: http://www.differencebetween.net/technology/difference-between-zip-and-gzip/ Summary: 1. GZIP ...

  5. Openstack 架构简述

    概述 在学习OpenStack的过程中,感觉对整个OpenStack的架构稍稍有些了解,所以将这些记录下来,一来防止自己忘记,二来也可以对有需要的人提供帮助 本文章相关的灵感/说明/图片来自于http ...

  6. 小程序网络请求arraybuffer 转为base64

    wx.request({ url: result.tempFilePath, method: 'GET', responseType: 'arraybuffer', success: function ...

  7. 【Flask】Sqlalchemy 常用数据类型

    ### SQLAlchemy常用数据类型:1. Integer:整形,映射到数据库中是int类型.2. Float:浮点类型,映射到数据库中是float类型.他占据的32位.3. Double:双精度 ...

  8. Ansible 实战之部署Web架构

    WEB架构(ubuntu 16.04): Proxy -- WebServer(Nginx+PHP+Django) -- Nosql -- MariaDB 一. 定义Inventory [proxy] ...

  9. POJ 之2386 Lake Counting

    Lake Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20003   Accepted: 10063 D ...

  10. Delphi UniDAC 通过http协议连接数据库的设置

    Connection through HTTP tunnel(using http protocol) Sometimes client machines are shielded by a fire ...