关于《Thinking in Unity3D》


笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙。不得不说,笔者最近几年的引擎研发工作中,早已习惯性的从Unity3D中寻找解决方案。

Unity3D虽比不上UE那么老练沉稳,气势磅礴。也比不上CE那样炫丽多姿,盛气凌人。但它的发展势如破竹,早已遍地生花!故而在此记录一些自己的心得体会,供大家参详交流。若有欠妥之处,还望各位及时指正。
 
Thinking in Unity3D由一系列文章组成,文章列表地址:http://www.cnblogs.com/geniusalex/p/5321545.html
 

HI,你好


Unity3D发展至今,已经是5.x版本了。对于一个引擎迭代来说,特性、效果、效率的提升,无不波及到渲染管线的改动。而与渲染管线最为紧密挂钩的就是材质系统和渲染流程,但由于材质系统和渲染流程涉及的范围和内容更广。我们将用单独的篇幅来描述。本文主要目标是渲染管线中的Rendering Path。
由于历史发展,以及各种平台、机型、版本兼容的原因。Unity3D中,目前保存了4种Rending Path.
1、Deferred Shading Rendering Path(延迟渲染)
2、Forward Rendering Path(前向渲染)
3、Lagacy Deferred Lighting Rendering Path(延迟光照)
4、Vertex Lit Rendering Path(顶点光照)
 

Forward Rendering Path(前向渲染)


传统的前向着色渲染方式是一种简单粗暴的方式。就是一次性将一个物体绘制完再绘制下一个。光照计算也是如此。前向着色最主要的问题就是光照问题。当光源过多的时候,就需要进行处理。 而Unity3D在光源处理方面,也结合了像素光照(per-pixel lighting) ,顶点光照(per-vertex lighting),球谐光照(Spherical Harmonics lighting)等多种方案,其复杂程度可见一斑。
 
Unity3D中前向渲染的光源策略
前向着色渲染由于效率和寄存器限制等原因。不可能老老实实地去处理所有的光源。因此,需要根据光源的远近,范围,重要程度等因子决定计算方式。
1、如果一个光源的RenderMode没有设置为重要(Important),那么它将永远是逐顶点或者球谐光照计算方式。
2、最亮的(Brightest)方向光源会做为逐像素光照计算。
3、如果一个光源的RenderMode设置为重要(Important),那么它将会采用逐像素光照计算方式
4、如果上面的结果中的用于逐像素计算的光源数目小于了Project Settings->Quality面板中的Pixel Light Count值。 为了减少亮度误差,有一些光源会被当作像素光源计算(PS:非像素光源无法完全计算阴影关系。会导致场景偏亮)。
5、Unity3D对顶点光照,像素光照做了最大限制。 分别为4个。而场景中不可能只有这么多光源。因此,使用了一个优先级判定。
左:光源位置图 右:光源分配图
 
从图中我们可以看到。 D参与了像素和顶点光照。 G参与了顶点光照和球谐光照。 这样的处理应该是为了做一个光照信息的平滑衔接,不至于变得很突兀。
 
 
Unity3D中前向渲染的光照的计算过程
前向渲染中,光照计算被分成了多个PASS。通常它们由1*FarwardBase Pass + N*FarwardAdd Pass组成。可以看出,光源的数目在前向渲染管线中是一个致命的效率杀手。
1、Base Pass 提交一个逐像素方向光和所有的逐顶点光照和球谐光照。
2、Additional Pass 提交一个逐像素的光照计算。 如果一个物体受更多的光源影响。那么就会有许多PASS需要进行绘制。
:在Shader中。可以指定FarwardBase来关掉Additional 功能。
:在前向渲染中,只能有一个方向光实时阴影。
 
Unity3D中的球谐光照
球谐光照是一个CPU光照算法。它可以处理大规模的光源信息,非常适合一些很小的动态点光源。但是它存在以下几个问题。
1、球谐光照是基于物体顶点的算法,并非像素级。这就意味着它不能使用一些像素级的效果增强手段。比如法线贴图。
2、基于效率的考虑,球谐光照的更新频率非常低。如果光源移动过快,就会穿邦。
3、球谐光照是基于全局空间的计算,当一个面离点光源或者聚光灯很近时,效果是错的。
 

Deferred Shading Rendering Path(延迟渲染)


 
延迟渲染技术简介
延迟渲染技术已经是一个成熟且稳定的技术。已经广泛用于各种商业引擎中。它主要解决的是当光源数目过多时带来的复杂光照计算的开销。 在传统前向渲染中,假设一个场景中有M个物体,N个光源。 那么理论上进行的光照计算次数为 M*N。 而DS管线可以使其变为M+N。
但是DS管线并非万能的。有以下情况需要注意
 
延迟渲染技术缺陷
1、DS需要多渲染目标(MRT)的支持、深度纹理、双面模板缓存。
     这个特性,需要显卡支持SM3.0的API。2006年以后的PC显卡应该不成问题。比如GeForce 8xxxx,AMD Radeon X2400,Intel G45以后的显卡。
2、DS管线会消耗更多的显存,用于缓存G-Buffer。同时,会要求显卡拥有更大的位宽(bit counts)。
     在手机上目前(2016年)还不实现。
3、DS管线无法处理半透明物体。
     半透明物体需要退回到传统前向渲染中进行
4、硬件抗锯齿(MSAA)无法使用。
     只能使用一些后期算法,如FXAA等。
5、这句话中的内容目前未测试,故无法准确体会其中的意思:There is also no support for the Mesh Renderer’s Receive Shadows flag and culling masks are only supported in a limited way. You can only use up to four culling masks. That is, your culling layer mask must at least contain all layers minus four arbitrary layers, so 28 of the 32 layers must be set. Otherwise you will get graphical artefacts.
 
延迟渲染技术在Unity3D中的实现方案
Unity3D中,延迟渲染管线为分两个阶段进行。G-Buffer阶段和光照计算(Lighting)阶段。
 
G-Buffer阶段
Unity3D渲染所有的非透明对象到各个RT中,RT的内容分布见 G-Buffer内容。Unity3D将各个RT做成了全局变量,方面Shader中进行操作。像这样:CameraGBufferTexture0 .. CameraGBufferTexture3
 
光照计算阶段
这个阶段的主要目的就是根据G-Buffer的内容进行光照计算。由于是屏幕空间的计算,显然要比之前的前向渲染来得容易得多。
 
:实时阴影的计算是在光照计算之前的。 DS管线并不能减少实时阴影的开销。应该怎么整还得怎么整。最后,每个物体受到的实时阴影的影响会叠加到RT3中。一些特殊的爆光效果,Lightmap光影贴图效果等都会进入RT3。 参见G-Buffer内容
 
 
G-Buffer内容
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.
 
:为了减少显存和渲染开销。当前场景的摄像机开启了HDR模式时,RT3将不会被创建。而是直接使用摄像机的HDR RT。
 
自定义DS管线
Unity3D中,标准的DS管线是Standard系列。如果你想修改某一个部分。你可以新建一个自己的Shader。然后替换掉默认的即可。
替换的位置在Edit->Project Settings->Graphics面板中。把Deferred属性下拉框变成Custom,就可以进行替换操作了。
 
内置Shader设置

Lagacy Deferred Lighting Rendering Path(延迟光照)


:从5.0开始,DL渲染已经不被Unity3D推荐,Unity3D更推荐大家新项目使用DS管线方式。因为DL方式不好实现基于PBR着色的Standard材质,以及场景反射。
:如果摄像机设置为了正交投影。会强制退回前向渲染
:DL也不会降低实时阴影的开销
 
和DS渲染管线一样,DL的出现同样是为了解决光照计算的复杂度问题。然后不同的是,DL仅仅把光照计算拿出去了。简单说来,DL管线工作流程如下。
步骤一、渲染场景中的对象,输出光照计算需要的RT(深度、法线、高光信息)
步骤二、使用上面的RT进行光照计算
步骤三、再次渲染场景中的对象,并与计算机来的光照信息结合。
 
不难看出,DL相比DS而言,不需要大量的G-Buffer支持。甚至不需要MRT的支持。但是对深度图的要求是必须的。如果遇上无法访问深度BUFFER的情况。那就需要做一次Pre-Depth Pass渲染。
 
比起DS而言,DL由于不需要MRT的支持。在硬件特性需求和位宽上,少了许多开销。
1、SM3.0
2、PC:GeForce FX、Radeon X1300、Intel 965 / GMA X3100
3、Mobile:所有支持OpenGL ES 3.0的设备,部分支持OpenGL ES 2.0的设备。
 

Vertex Lit Rendering Path(顶点光照)


注:这不是一个通用的技术名词,只有Unity3D中有。
注:主机平台这个不顶用。
注:不支持实时阴影和高精度高光计算。
 
Vertex Lit Rendering就是指,所有的光照计算都通过顶点进行。而在Unity3D中,它的主要目的是为了支持那些没有可编程管线的设备。VL也提供了几种方法,用于支持不同的材质类型。
1、Vertex 使用Blinn-Phong进行光照处理,针对没有lightmap的对象使用。
2、VertexLMRGBM 针对lightmap贴图使用RGBM加密(PC和主机平台)的对象, 没有额外的光照计算。
3、VertexLMM 针对lightmap贴图使用double-LDR加密(移动平台)的对象,没有额外的光照计算。
 

Unity3D对几种渲染管线的统一处理


在上面我描述中,我们发现,不管哪一种管线。都会涉及到几个部分。 1、光照计算 2、透明渲染 3、阴影计算 4、图像输出。 那Unity3D又是如何对这些进行统一流程控制的呢。我们看下面的图就明白了。
 Unity3D渲染管线图
 
从图中我们可以看到。Unity3D的传统渲染管线和延迟渲染管线,在非透明物体渲染和光照阶段是分离的。当处理完以后,紧接着处理非透明图像效果->天空盒->透明物体渲染->后期效果。
 
结束语

总的来说,Unity3D的渲染管线还算稳定和易用,其的渲染管线包含了常见的三种方案。最主要目的还是在想着光照计算和效果显示的处理。同时保持对上层透明。其Graphics Commander Buffer提供了扩展管线的能力。而Graphics设置面板里,也提供了自定义延迟管线Shader的功能。然而也有诸多的美中不足,比如,正交摄像机模式下,不能使用延迟渲染技术。 延迟光照下无法实现PBR和实时环境反射抽取等等。
 
参考文献

Thinking in Unity3D:渲染管线中的Rendering Path的更多相关文章

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

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

  2. 渲染路径-实时渲染中常用的几种Rendering Path

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

  3. Unity 的“Vertex Lit Rendering path“中 shader Pass 的注意事项

    "MADFINGER/Environment/Unlit (Supports Lightmap)"是 ShadowGun 示例中最简单的 shader 了,如下: // Unlit ...

  4. Rendering Path

    Rendering Path:渲染路径 设置:1.Player Setting,2.Camera(会覆盖PlayerSetting中的设置) 选择:根据渲染内容和目标平台来选择合适的Rendering ...

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

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

  6. Unity3D光照前置知识——Rendering Paths(渲染路径)及LightMode(光照模式)译解

    简述 Unity supports different Rendering Paths. You should choose which one you use depending on your g ...

  7. Unity Lighting - Choosing a Rendering Path 选择渲染路径(三)

      Choosing a Rendering Path 选择渲染路径 Unity supports a number of rendering techniques, or ‘paths’. An i ...

  8. 渲染路径-Unity5 的新旧推迟渲染Deferred Lighting Rendering Path

    Unity5 的新旧延迟渲染Deferred Lighting Rendering Path unity5 的render path ,比4的区别就是使用的新的deferred rendering,之 ...

  9. shader 3 rendering path

    渲染通道, rendering path. vertexlit, forward 和 Deferred lighting 旧有的非统一架构下: 分为顶点着色引擎和像素渲染通道 渲染通道是GPU负责给图 ...

随机推荐

  1. 【每日一linux命令4】常用参数:

     下面所列的是常见的参数(选项)义: --help,-h                              显示帮助信息 --version,-V                        ...

  2. 前端框架 EasyUI (0) 重新温习(序言)

    几年前,参与过一个项目.那算是一个小型的信息管理系统,BS 结构的,前端用的是基于 jQuery 的 EasyUI 框架. 我进 Team 的时候,项目已经进入开发阶段半个多月了.听说整个项目的框架是 ...

  3. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  4. java中servlet的各种路径

    1. web.xml中<url-pattern>路径,(叫它Servlet路径!) > 要么以“*”开关,要么为“/”开头 2. 转发和包含路径 > *****以“/”开头:相 ...

  5. 微信小程序体验(2):驴妈妈景区门票即买即游

    驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...

  6. C# 多种方式发送邮件(附帮助类)

    因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...

  7. Oracle数据库该如何着手优化一个SQL

    这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异. 所以有时候我们应该先 ...

  8. Linux基础介绍【第一篇】

    Linux简介 什么是操作系统? 操作系统,英文名称Operating System,简称OS,是计算机系统中必不可少的基础系统软件,它是应用程序运行以及用户操作必备的基础环境支撑,是计算机系统的核心 ...

  9. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  10. Java:Double Brace Initialization

    在我刚刚接触现在这个产品的时候,我就在我们的代码中接触到了对Double Brace Initialization的使用.那段代码用来初始化一个集合: final Set<String> ...