Unity中的渲染路径

Unity的渲染路径

在Unity里,渲染路径(Rendering Path)决定了光照是如何应用到Unity Shader中的。因此,我们只有为Shader正确地选择和设置了需要的渲染路径,该shader的光照计算才可以被正确执行。

unity中的渲染路径:

  • Forward Rendering Path (向前渲染路径)
  • Deferred Rendering Path (延迟渲染路径) 【新的版本已替换老版本】
  • Vertex Lit Rendering Path (顶点渲染路径)【Unity 5.X之后已被抛弃】

大多数情况下,一个项目只会使用一种渲染路径。

Forward Rendering Path (向前渲染路径)

前向渲染路径是传统的渲染方式,也是我们最常用的一种渲染路径。

向前渲染路径原理:

在进行一次完整的向前渲染过程中,我们需要渲染该对象的渲染图元,并计算两个缓冲区的信息:颜色缓冲区和深度缓冲区。利用深度缓冲来确定一个片元是否是可见的,如果可见就更新颜色缓冲区中的颜色值。

Pass  {
for (each primitive in this model) {
for (each fragment covered by this primitive) {
if (failed in depth test) {
// 如果没有通过深度测试,说明该片元是不可见的
discard;
} else {
// 如果该片元可见
// 就迚行光照计算
float4 color = Shading(materialInfo, pos, normal, lightDir, viewDir);
// 更新帧缓冲
writeFrameBuffer(fragment, color);
}
}
}
}

对于每个逐像素光源,我们都需要进行上面一次完整的渲染流程。

如果一个物体在多个逐像素光源的影响区域内,那么该物体就需要执行多个Pass,每个Pass计算一个逐像素光源的光照结果,然后在帧缓冲中把这些光照结果混合起来得到最终的颜色值。

Unity中的向前渲染:

Unity中向前渲染路径的3种处理光照的方式:

逐顶点处理、逐像素处理和球谐函数(Spherical Harmonics,SH)处理。

而决定一个光源使用哪种处理模式取决于它的类型和渲染模式。

光照类型:指该光源是平行光还是其它类型光源

光源的渲染模式:是否是Important

在前向渲染中,当我们渲染一个物体时,Unity会根据场景中各个光源的设置以及这些光源对物体的影响程度(例如,距离该物体的远近、光源强度等)对这些光源进行一个重要度排序。其中,一定数目的光源会按逐像素的方式处理,然后最多有4个光源按逐顶点的方式处理,剩下的光源可以按SH方式处理。

  • 场景中最亮的平行光总是按逐像素处理的。
  • 渲染模式被设置成Not Important的光源,会按逐顶点或者SH处理。
  • 渲染模式被设置成Important的光源,会按逐像素处理。
  • 如果根据以上规则得到的逐像素光源数量小于Quality Setting中的逐像素光源数量(Pixel Light Count),会有更多的光源以逐像素的方式进行渲染。

向前渲染中的两种Pass ,在Pass中进行光照计算。

对于前向渲染来说,一个Unity Shader通常会定义一个Base Pass(Base Pass也可以定义多次,例如需要双面渲染等情况)以及一个Additional Pass。

一个Base Pass仅会执行一次(定义了多个Base Pass的情况除外),而一个Additional Pass会根据影响该物体的其他逐像素光源的数目被多次调用,即每个逐像素光源会执行一次Additional Pass。

Vertex Lit Rendering Path (顶点渲染路径)

顶点照明渲染路径是对硬件配置要求最少、运算性能最高,但同时也是得到的效果最差的一种类型,它不支持那些逐像素才能得到的效果,例如阴影、法线映射、高精度的高光反射等。实际上,它仅仅是前向渲染路径的一个子集,也就是说,所有可以在顶点照明渲染路径中实现的功能都可以在前向渲染路径中完成。

如果选择使用顶点照明渲染路径,那么Unity会只填充那些逐顶点相关的光源变量,意味着我们不可以使用一些逐像素光照变量。

Unity中的顶点照明渲染:

顶点照明渲染路径通常在一个Pass中就可以完成对物体的渲染。在这个Pass中,我们会计算我们关心的所有光源对该物体的照明,并且这个计算是按逐顶点处理的。这是Unity中最快速的渲染路径,并且具有最广泛的硬件支持(但是游戏机上并不支持这种路径)。

可访问的内置变量和函数:

在Unity中,我们可以在一个顶点照明的Pass中最多访问到8个逐顶点光源。

顶点照明渲染路径中可以使用的内置变量

顶点照明渲染路径中可以使用的内置函数

Deferred Rendering Path (延迟渲染路径)

延迟渲染是一种更古老的渲染方法,但由于上述前向渲染可能造成的瓶颈问题,近几年又流行起来。

除了前向渲染中使用的颜色缓冲和深度缓冲外,延迟渲染还会利用额外的缓冲区,这些缓冲区也被统称为G缓冲(G-buffer),其中G是英文Geometry的缩写。G缓冲区存储了我们所关心的表面(通常指的是离摄像机最近的表面)的其他信息,例如该表面的法线、位置、用于光照计算的材质属性等。

延迟渲染的原理:

延迟渲染主要包含了两个Pass。

在第一个Pass中,我们不进行任何光照计算,而是仅仅计算哪些片元是可见的,这主要是通过深度缓冲技术来实现,当发现一个片元是可见的,我们就把它的相关信息存储到G缓冲区中。

然后,在第二个Pass中,我们利用G缓冲区的各个片元信息,例如表面法线、视角方向、漫反射系数等,进行真正的光照计算。

        Pass  1  {
// 第一个Pass不迚行真正的光照计算
// 仅仅把光照计算需要的信息存储到G缓冲中 for (each primitive in this model) { for (each fragment covered by this primitive) {
if (failed in depth test) {
// 如果没有通过深度测试,说明该片元是不可见的
discard;
} else {
// 如果该片元可见
// 就把需要的信息存储到G缓冲中
writeGBuffer(materialInfo, pos, normal, lightDir, viewDir);
}
}
}
} Pass 2 {
// 利用G缓冲中的信息迚行真正的光照计算 for (each pixel in the screen) {
if (the pixel is valid) {
// 如果该像素是有效的
// 读取它对应的G缓冲中的信息
readGBuffer(pixel, materialInfo, pos, normal, lightDir, viewDir); // 根据读取到的信息迚行光照计算
float4 color = Shading(materialInfo, pos, normal, lightDir, viewDir);
// 更新帧缓冲
writeFrameBuffer(pixel, color);
}
}
}

延迟渲染使用的Pass数目通常就是两个,这跟场景中包含的光源数目是没有关系的。

换句话说,延迟渲染的效率不依赖于场景的复杂度,而是和我们使用的屏幕空间的大小有关。

这是因为,我们需要的信息都存储在缓冲区中,而这些缓冲区可以理解成是一张张2D图像,我们的计算实际上就是在这些图像空间中进行的。

Unity中的延迟渲染:

Unity有两种延迟渲染路径,一种是遗留的延迟渲染路径,即Unity 5之前使用的延迟渲染路径,而另一种是Unity5.x中使用的延迟渲染路径。如果游戏中使用了大量的实时光照,那么我们可能希望选择延迟渲染路径,但这种路径需要一定的硬件支持。

对于延迟渲染路径来说,它最适合在场景中光源数目很多、如果使用前向渲染会造成性能瓶颈的情况下使用。而且,延迟渲染路径中的每个光源都可以按逐像素的方式处理。

延迟渲染的缺点:

  • 不支持真正的抗锯齿(anti-aliasing)功能。
  • 不能处理半透明物体。
  • 对显卡有一定要求。如果要使用延迟渲染的话,显卡必须支持MRT(Multiple Render Targets)、Shader Mode 3.0及以上、深度渲染纹理以及双面的模板缓冲。

Unity要求我们提供两个Pass。

(1)第一个Pass用于渲染G缓冲。在这个Pass中,我们会把物体的漫反射颜色、高光反射颜色、平滑度、法线、自发光和深度等信息渲染到屏幕空间的G缓冲区中。对于每个物体来说,这个Pass仅会执行一次。

2)第二个Pass用于计算真正的光照模型。这个Pass会使用上一个Pass中渲染的数据来计算最终的光照颜色,再存储到帧缓冲中。

默认的G缓冲区(注意,不同Unity版本的渲染纹理存储内容会有所不同)包含了以下几个渲染纹理(Render Texture, RT)。

  • RT0:格式是ARGB32, RGB通道用于存储漫反射颜色,A通道没有被使用。
  • RT1:格式是ARGB32, RGB通道用于存储高光反射颜色,A通道用于存储高光反射的指数部分。
  • RT2:格式是ARGB2101010, RGB通道用于存储法线,A通道没有被使用。
  • RT3:格式是ARGB32(非HDR)或ARGBHalf(HDR),用于存储自发光+lightmap+反射探针(reflection probes)。

深度缓冲和模板缓冲。

当在第二个Pass中计算光照时,默认情况下仅可以使用Unity内置的Standard光照模型,如果我们想要使用其他的光照模型,就需要替换掉原有的Internal-DeferredShading.shader文件。

可访问的内置变量和函数:

这些变量都可以在UnityDeferred Library.cginc文件中找到它们的声明。

选择哪种渲染路径?

Unity的官方文档(http://docs.unity3d.com/Manual/RenderingPaths.html)中给出了4种渲染路径(前向渲染路径、延迟渲染路径、遗留的延迟渲染路径和顶点照明渲染路径)的详细比较,包括它们的特性比较(是否支持逐像素光照、半透明物体、实时阴影等)、性能比较以及平台支持。

总体来说,我们需要根据游戏发布的目标平台来选择渲染路径。如果当前显卡不支持所选渲染路径,那么Unity会自动使用比其低一级的渲染路径。

Unity中的三种渲染路径的更多相关文章

  1. File类三种得到路径的方法

    转: File类三种得到路径的方法 2010年11月29日 20:37:00 ssyan 阅读数:27123 标签: filemicrosoftstringexceptionwindowsunix   ...

  2. Hive中的三种不同的数据导出方式介绍

    问题导读:1.导出本地文件系统和hdfs文件系统区别是什么?2.带有local命令是指导出本地还是hdfs文件系统?3.hive中,使用的insert与传统数据库insert的区别是什么?4.导出数据 ...

  3. Vue中的三种Watcher

    Vue中的三种Watcher Vue可以说存在三种watcher,第一种是在定义data函数时定义数据的render watcher:第二种是computed watcher,是computed函数在 ...

  4. iOS中的三种定时器

    iOS中的三种定时器 NSTimer 一.背景 定时器是iOS开发中经常使用的,但是使用不慎会造成内存泄露,因为NSTimer没有释放,控制器析构函数dealloc也没有调用,造成内存泄露. 二.使用 ...

  5. Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

    Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过 ...

  6. Asp.Net中的三种分页方式

    Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...

  7. httpClient中的三种超时设置小结

    httpClient中的三种超时设置小结   本文章给大家介绍一下关于Java中httpClient中的三种超时设置小结,希望此教程能给各位朋友带来帮助. ConnectTimeoutExceptio ...

  8. MySQL buffer pool中的三种链

    三种page.三种list.LRU控制调优 一.innodb buffer pool中的三种页 1.free page:从未用过的页 2.clean page:干净的页,数据页的数据和磁盘一致 3.d ...

  9. 研究分析JS中的三种逻辑语句

    JS中的三种逻辑语句:顺序.分支和循环语句. 一.顺序语句 代码规范如下:1. <script type="text/javascript"> var a = 10;  ...

  10. JavaScript中的三种弹出对话框

    学习过js的小伙伴会发现,我们在一些实例中用到了alert()方法.prompt()方法.prompt()方法,他们都是在屏幕上弹出一个对话框,并且在上面显示括号内的内容,使用这种方法使得页面的交互性 ...

随机推荐

  1. 领域驱动设计(DDD)分层架构的三种模式

    模式一:四层架构 1.User Interface为用户界面层(或表示层),负责向用户显示信息和解释用户命令.这里指的用户可以是另一个计算机系统,不一定是使用用户界面的人.2.Application为 ...

  2. Python 按规则解析并替换字符串中的变量及函数

    按规则解析并替换字符串中的变量及函数 需求 1.按照一定规则解析字符串中的函数.变量表达式,并替换这些表达式.这些函数表达式可能包含其它函数表达式,即支持函数嵌套 2.函数表达式格式:${ __函数名 ...

  3. openEuler 安装 DocekrCE

    就个人而言,openEuler 算是不错的国产化操作系统."一脉传承"自redhat让实际的使用体验非常丝滑.软件源都是国内的,开箱即用,漏洞的补丁发的也挺及时.美中不足的是貌似 ...

  4. 辅助分类器生成对抗网络( Auxiliary Classifier Generative Adversarial Network,ACGAN)(附带pytorch代码)

    1 ACGAN基本原理 1.2 ACGAN模型解释 ACGAN相对于CGAN使的判别器不仅可以判别真假,也可以判别类别 .通过对生成数据类别的判断,判别器可以更好地传递loss函数使得生成器能够更加准 ...

  5. Cython与C函数的结合

    技术背景 在前面一篇博客中,我们介绍了使用Cython加速谐振势计算的方法.有了Cython对于计算过程更加灵活的配置(本质上是时间占用和空间占用的一种均衡),及其接近于C的性能,并且还最大程度上的保 ...

  6. 【MySQL】拆分经纬度字段

    数据结构: 表中一字段存储经度和纬度: +---------------------------+ | INSTALL_LOLA_NUM | +---------------------------+ ...

  7. 【DataBase】XueSQL Training

    地址: http://xuesql.cn/ Lesson0 -- 认识SQL -- [初体验]这是第一题,请你先将左侧的输入框里的内容清空,然后请输入下面的SQL,您将看到所有电影标题: SELECT ...

  8. 【Lodop】02 C-Lodop手册阅读上手

    版本:4.0.6.2 一.概述 C-Lodop云打印是一款精巧快捷的云打印服务产品,以Lodop功能语句为基础,JS语句实现远程打印 移动设备+Wifi+普通打印机+集中打印 C-Lodop对客户端浏 ...

  9. nvtop —— GPU使用情况的可视化工具

    安装: sudo apt install nvtop

  10. MindSpore1.3.0 GPU pip方式安装 —— Ubuntu18.04系统 (最终安装结果为成功)需要管理员权限,sudo安装

    官网地址: https://www.mindspore.cn/install =========================================================== 安 ...