unity-shader-延迟渲染

88 篇文章 8 订阅
31 篇文章 7 订阅

title: unity-shader-延迟渲染
categories: Unity3d
tags: [unity, shader, deferred, 延迟渲染]
date: 2019-04-11 15:13:19
comments: false

unity-shader-延迟渲染


前篇

相关资料

使用光体积更好的方法是渲染一个实际的球体,并根据光体积的半径缩放。这些球的中心放置在光源的位置,由于它是根据光体积半径缩放的,这个球体正好覆盖了光的可视体积。这就是我们的技巧:我们使用大体相同的延迟片段着色器来渲染球体。因为球体产生了完全匹配于受影响像素的着色器调用,我们只渲染了受影响的像素而跳过其它的像素。下面这幅图展示了这一技巧:

它被应用在场景中每个光源上,并且所得的片段相加混合在一起。这个结果和之前场景是一样的,但这一次只渲染对于光源相关的片段。它有效地减少了从nr_objects * nr_lightsnr_objects + nr_lights的计算量,这使得多光源场景的渲染变得无比高效。这正是为什么延迟渲染非常适合渲染很大数量光源。


管线流程


unity 中使用 延迟渲染

官方文档: Deferred shading rendering path - https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

  • pc, 要求显卡支持 MRT, sm3.0 和 深度图. 大部分2006年后生成的显卡都支持 延迟渲染, 如: GeForce 8xxx, Radeon X2400, Intel G45 以后的显卡

    移动设备, 所有 OpenGL ES 3.0 以上都支持延迟渲染


Implementation details

Objects with Shaders that do not support deferred shading are rendered after deferred shading is complete, using the forward rendering
path.

The default layout of the render targets (RT0 - RT4) in the geometry buffer (g-buffer) is listed below. Data types are placed in the various channels of each render target. The channels used are shown in parentheses.

  • RT0, ARGB32 format: Diffuse color (RGB), occlusion (A).

  • RT1, ARGB32 format: Specular color (RGB), roughness (A).

  • RT2, ARGB2101010 format: World space normal (RGB), unused (A).

  • RT3, ARGB2101010 (non-HDR) or ARGBHalf (HDR) format: Emission + lighting + lightmaps
    + reflection probes
    buffer.

  • Depth+Stencil buffer.

    So the default g-buffer layout is 160 bits/pixel (non-HDR) or 192 bits/pixel (HDR).

    If using the Shadowmask or Distance Shadowmask modes for Mixed lighting, a fifth target is used:

  • RT4, ARGB32 format: Light occlusion values (RGBA).


geometry pass, lighting pass
  • geometry pass : 往 gbuffer 中填充数据 (填充到四个RT).

  • lighting pass : 从 gbuffer (四个RT) 中取出数据进行光照模型着色.

    官方文档 说了默认的 lighting pass 使用的是内置的 Internal-DeferredShading.shader 里面的着色. 如果想使用不同的光照模型, 就去修改这个shader.


shader

参考: Unity 渲染教程(十三):延迟渲染 - http://gad.qq.com/program/translateview/7200862 ( 好文, 引起极度舒适 )

这里只有 geometry pass, 也就是往 gbuffer 中填充数据.

  1. 相机的 Rendering Path 设置为 Deferred. (此时 MSAA 无效)

  2. shader 中指定 "LightMode" = "Deferred". frag的返回值为四个buffer. (具体参考: My Lighting.cginc)

    struct FragmentOutput {
        float4 gBuffer0 : SV_Target0;
        float4 gBuffer1 : SV_Target1;
        float4 gBuffer2 : SV_Target2;
        float4 gBuffer3 : SV_Target3;
    };
    
    // 然后往这四个buffer中填充数据
    FragmentOutput MyFragmentProgram (Interpolators i) {
    	...
        FragmentOutput output;
        #if !defined(UNITY_HDR_ON)
            color.rgb = exp2(-color.rgb);
        #endif
        output.gBuffer0.rgb = albedo;
        output.gBuffer0.a = GetOcclusion(i);
        output.gBuffer1.rgb = specularTint;
        output.gBuffer1.a = GetSmoothness(i);
        output.gBuffer2 = float4(i.normal * 0.5 + 0.5, 1);
        output.gBuffer3 = color;
    	return output;
    }
    
    • 第一个G缓冲区 (SV_Target0) 用于存储漫反射率和表面遮挡。这是一个ARGB32纹理,就像一个常规的帧缓冲区。反射率存储在RGB通道中,遮挡存储在A通道中。
    • 第二个G缓冲区 (SV_Target1) 用于存储RGB通道中的镜面高光颜色,以及A通道中的平滑度值。它也是一个ARGB32纹理。
    • 第三个G缓冲区 (SV_Target2) 包含的是世界空间中的法向量。它们存储在ARGB2101010纹理的RGB通道中。这意味着每个坐标都是使用十位进行存储,而不是通常的八位。这使得它们更加精确。A通道只有两位-所以总共再次是32位 - 但是它没有被使用,所以我们只需将它设置为1。法线的编码就像是一个普通的法线贴图
    • 第三个G缓冲区 (SV_Target3) 用于累积场景的光照。它的格式取决于相机是否设置为高动态光照渲染或是低动态光照渲染。在低动态光照渲染的情况下,它是一个ARGB2101010纹理,就像正常的缓冲区一样。当启用高动态光照渲染的时候,格式为ARGBHalf,它存储每个通道的16位浮点值,总共64位。 所以高动态光照渲染版本他缓冲区的大小是其他缓冲区的两倍。仅仅使用RGB通道,因此A通道可以再次设置为1。
  3. 可以在场景编辑器中查看各个缓冲区的纹理


《Real-Time Rendering 3rd》 提炼总结 - 阅读笔记

来源于: https://github.com/QianMo/Real-Time-Rendering-3rd-CN-Summary-Ebook

7.1 延迟渲染 Deferred Rendering

我们知道,正向渲染(Forward Rendering),或称正向着色(Forward Shading),是渲染物体的一种
非常直接的方式,在场景中我们根据所有光源照亮一个物体,之后再渲染下一个物体,以此
类推。
传统的正向渲染思路是,先进行着色,再进行深度测试。 其的主要缺点就是光照计算跟场景
复杂度和光源个数有很大关系。假设有 n 个物体, m 个光源,且每个每个物体受所有光源的
影响,那么复杂度就是 O(m*n)。

正向渲染简单直接,也很容易实现,但是同时它对程序性能的影响也很大,因为对每一个需
要渲染的物体,程序都要对每个光源下每一个需要渲染的片段进行迭代,如果旧的片段完全
被一些新的片段覆盖,最终无需显示出来,那么其着色计算花费的时间就完全浪费掉了。

可以将延迟渲染( Deferred Rendering)理解为先将所有物体都先绘制到屏幕空间的缓冲(即 Gbuffer, Geometric Buffer,几何缓冲区)中,再逐光源对该缓冲进行着色的过程,从而避免了
因计算被深度测试丢弃的⽚元的着色而产⽣的不必要的开销。 也就是说 延迟渲染基本思想
是,先执行深度测试,再进行着色计算,将本来在物空 间(三维空间)进行光照计算放到了
像空间(二维空间)进行处理。
对应于正向渲染 O(m*n)的 复杂度,经典的延迟渲染复杂度为 O(n+m)。


7.2 几何缓冲区 G-buffer

G-Buffer,全称 Geometric Buffer ,译作几何缓冲区,它主要用于存储每个像素对应的位置
( Position),法线( Normal),漫反射颜色( Diffuse Color)以及其他有用材质参数。 根据这
些信息,就可以在像空间(二维空间)中对每个像素进行光照处理。

下图是一帧中 G-buffer 中存储的内容:

可以将延迟渲染理解为两个 Pass 的过程:
1、几何处理阶段(Geometry Pass)。这个阶段中,我们获取对象的各种几何信息,并将第二步
所需的各种数据储存(也就是渲染)到多个 G-buffer 中;
2、光照处理阶段(Lighting Pass)。 在这个 pass 中,我们只需渲染出一个屏幕大小的二维矩形,
使用第一步在 G-buffer 中存储的数据对此矩阵的每一个片段计算场景的光照;光照计算的过
程还是和正向渲染以前一样,只是现在我们需要从对应的 G-buffer 而不是顶点着色器(和一些
uniform 变量)那里获取输入变量了。
下面这幅图片很好地展示了延迟着色的整个过程:


7.5 延迟渲染 vs 正向渲染
  • 正向渲染( Forward Rendering)管线流程

  • 延迟渲染 (Deferred Rendering) 管线流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝶泳奈何桥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值