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

unity-shader-延迟渲染


前篇

相关资料

  • 延迟着色法 - https://learnopengl-cn.readthedocs.io/zh/latest/05 Advanced Lighting/08 Deferred Shading/

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

它被应用在场景中每个光源上,并且所得的片段相加混合在一起。这个结果和之前场景是一样的,但这一次只渲染对于光源相关的片段。它有效地减少了从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);#endifoutput.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) 管线流程

unity-shader-延迟渲染相关推荐

  1. 【Unity Shader】渲染纹理实现镜子效果

    1 基本概念 1.1 什么是渲染到纹理? 全称是Render To Texture,<入门精要>好像又把渲染目标纹理,即Render Target Texture也叫做RTT,但我认为&l ...

  2. Unity Shader卡通渲染 · 高清渲染管线·HDRP

    Unity Shader卡通渲染 · 高清渲染管线·HDRP 前言 最近在研究HDRP管线中的卡通渲染,就想着能不能把官方的UCTS移植到HDRP管线里面去,说干就干,到昨天晚上上传了github,今 ...

  3. Unity Shader 卡通渲染 模型描边之退化四边形

    目录 前言 一.基于空间的边缘检测算法 二.退化四边形 三.Unity中的CommandBuffer和ComputeBuffer 四.构成描边的简单实例 五.模型描边的实现 前言 之前写了一篇< ...

  4. Unity Shader 卡通渲染 实时模型动画描边的研究

    前言 卡通渲染也叫非真实感渲染(英文简写:NPR),"描边"在图形学和数字图像里都叫边缘检测.因此你可以在很多文献网站上面找到很多这类文献,但最后我发现基于图形学使用的方式基本都是 ...

  5. Unity Shader 布料渲染(丝袜)

    Unity Shader 布料渲染(丝袜) 现实中的丝袜效果 丹尼尔值 纤维的特性 分析 效果截图: Weak: Normal: Strong: 属性值定义: 丹尼尔值与拉伸程度 边缘度的计算 完整S ...

  6. 【Unity Shader】渲染纹理(镜子与玻璃)

    一般来说,一个摄像机的渲染结果会输出到颜色缓冲之中,并显示到我们的屏幕上.现代的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理(RTT),而不是传统的帧缓冲或者后备缓冲.与之相关的是 ...

  7. Unity Shader 素描渲染

    一.效果 Unity3D Shader 素描渲染 技术参考:https://io-meter.com/2014/12/31/sketch-rendering/ 效果思路来源于以前看的一部电影<小 ...

  8. Unity Shader 卡通渲染 (一):仿塞尔达荒野之息 Shader(简易版)

    温馨提示: 本系列文章面向那些 Shader 刚刚入门,想寻求进一步提升的群体,如果对 Shader 一无所知的话,建议自行搜索其他 Shader入门教程观看学习,再食用本系列文章. 前言: 说起卡通 ...

  9. Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)

    上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/100925621 顶点色在卡通渲染中有挺多应用,本篇会在上一篇的基础上,运用模型顶 ...

  10. unity shader卡通渲染(描边)+阴影+多光源处理

    说道卡通渲染,应该都会想到描边: 我所学的描边有三种: 一种是计算边缘深度检测描边 一种是色差检测描边 一种是利用顶点法线向外扩展返回单色pass,使用正面裁剪 我用的第三种: pass {//剔除前 ...

最新文章

  1. PermissionError: [Errno 13] Permission denied: ‘name.pdf‘
  2. 数据结构与算法-队列
  3. no.2_用绳子计时15分钟
  4. [vue] vue给组件绑定自定义事件无效怎么解决?
  5. 我喜欢用计算机400字,我的电脑400字作文
  6. Top的VIRT是什么
  7. UVa10491 Cows and Cars
  8. tomcat7.0安装及配置教程(win10)
  9. 电子产品环境可靠性测试标准有哪些?
  10. Mac OS X:显示/设置分辨率的命令(源程序)
  11. Spring框架汇总(大学生的天堂 码农的圣殿)
  12. Linux系统部署solr服务,不配置Tomcat服务器
  13. 计算机如何默认一种打字法,如何设置输入法,教您如何设置电脑的默认输入法...
  14. 360度全景图可以手动旋转的怎么制作?
  15. 云开发(微信-小程序)笔记(十四)---- 收藏,点赞(上)
  16. win7系统怎么删除电脑运行记录?
  17. 中国渠道销售管理模式特点分析
  18. 72.全卷积神经网络(FCN)及代码实现
  19. 你知道Graylog吗?不知道的话我建议你知道!
  20. 算力寻租或将终结中本聪的POW机制?深度解析BCH“司机补贴战”

热门文章

  1. 张驰咨询:某包装印刷集团第五期六西格玛项目通过专家评审
  2. Flutter isolate使用
  3. QT 删除QString空白字符
  4. 安卓异常java.lang.IllegalStateException: Content has been consumed
  5. leetcode 506. Relative Ranks(python)
  6. 使用 paddlehub的人物识别 对游戏人物识别 绘制方框
  7. 如何下载BiliBili视频
  8. oracle查询成绩属于什么等级,oracle认证考试成绩查询方法是什么?
  9. 【矩阵计算】QR分解-基于Householder变换
  10. 新旧版MATLAB中的希尔伯特-黄变换(HHT)及其边际谱的求取问题