关于《Thinking in Unity3D》
笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙。不得不说,笔者最近几年的引擎研发工作中,早已习惯性的从Unity3D中寻找解决方案。
Unity3D虽比不上UE那么老练沉稳,气势磅礴。也比不上CE那样炫丽多姿,盛气凌人。但它的发展势如破竹,早已遍地生花!故而在此记录一些自己的心得体会,供大家参详交流。若有欠妥之处,还望各位及时指正。
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和实时环境反射抽取等等。
参考文献
- 【原】实时渲染中常用的几种Rendering Path
[原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...
- 渲染路径-实时渲染中常用的几种Rendering Path
http://www.cnblogs.com/polobymulberry/p/5126892.html?utm_source=tuicool&utm_medium=referral 回到顶部 ...
- Unity 的“Vertex Lit Rendering path“中 shader Pass 的注意事项
"MADFINGER/Environment/Unlit (Supports Lightmap)"是 ShadowGun 示例中最简单的 shader 了,如下: // Unlit ...
- Rendering Path
Rendering Path:渲染路径 设置:1.Player Setting,2.Camera(会覆盖PlayerSetting中的设置) 选择:根据渲染内容和目标平台来选择合适的Rendering ...
- Unity5 的新旧延迟渲染Deferred Lighting Rendering Path
unity5 的render path ,比4的区别就是使用的新的deferred rendering,之前的4的deferred rendering(其实是light prepass)也被保留了下来 ...
- Unity3D光照前置知识——Rendering Paths(渲染路径)及LightMode(光照模式)译解
简述 Unity supports different Rendering Paths. You should choose which one you use depending on your g ...
- Unity Lighting - Choosing a Rendering Path 选择渲染路径(三)
Choosing a Rendering Path 选择渲染路径 Unity supports a number of rendering techniques, or ‘paths’. An i ...
- 渲染路径-Unity5 的新旧推迟渲染Deferred Lighting Rendering Path
Unity5 的新旧延迟渲染Deferred Lighting Rendering Path unity5 的render path ,比4的区别就是使用的新的deferred rendering,之 ...
- shader 3 rendering path
渲染通道, rendering path. vertexlit, forward 和 Deferred lighting 旧有的非统一架构下: 分为顶点着色引擎和像素渲染通道 渲染通道是GPU负责给图 ...
随机推荐
- HTTP协议系列(1)
一.为什么学习Http协议 首先明白我们为什么学习HTTP协议,也就是说明白HTTP协议的作用.HTTP协议是用于客户端与服务器之间的通讯.明白了HTTP协议的作用也就知道了为什么要学习H ...
- 从Membership 到 .NET4.5 之 ASP.NET Identity
我们前面已经讨论过了如何在一个网站中集成最基本的Membership功能,然后深入学习了Membership的架构设计.正所谓从实践从来,到实践从去,在我们把Membership的结构吃透之后,我们要 ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- 微信小程序初探
做为码农相信大家最近肯定都会听到微信小程序,虽然现阶段还没有正式开放注册,但大家可以还是可以开发测试. 到微信的WIKI(http://mp.weixin.qq.com/wiki?t=resource ...
- 无法访问org.springframework.core.NestedRuntimeException 找不到org.springframework.core.NestedRuntimeException的类文件
在学习springAOP时,出现如下异常: 无法访问org.springframework.core.NestedRuntimeException 找不到org.springframework.cor ...
- 【centos7常用技巧】RPM打包
一.RPM打包的目的 1.当目标机中不存在编译环境时,可以先在本地环境中编译打包,然后直接在目标机中用rpm -ivh *.rpm安装即可. 2.当需要在目标机中安装多个软件或者增加多个文件时,可以将 ...
- SSIS 包部署 Package Store 后,在 IS 中可以执行,AGENT 执行却报错
可以执行 SSIS Package ,证明用 SSIS Package 的账户是可以执行成功的.SQL Server Agent 默认指定账号是 Network Service. 那么可以尝试一下将 ...
- MySQL 数据库双向同步复制
MySQL 复制问题的最后一篇,关于双向同步复制架构设计的一些设计要点与制约. 问题和制约 数据库的双主双写并双向同步场景,主要考虑数据完整性.一致性和避免冲突.对于同一个库,同一张表,同一个记录中的 ...
- 【转】 XenServer的架构
一.Dom0或者控制域 XenServer从安装上看起来像是一个Linux,所以有些同学认为XenServer就是Linux或者是Linux修改的.真实的XenServer和Linux的关系是这样的: ...
- logstash服务启动脚本
logstash服务启动脚本 最近在弄ELK,发现logstash没有sysv类型的服务启动脚本,于是按照网上一个老外提供的模板自己进行修改 #添加用户 useradd logstash -M -s ...