首页 > 其他分享 >Unity中的三种渲染路径

Unity中的三种渲染路径

时间:2024-09-16 15:02:25浏览次数:10  
标签:渲染 光源 路径 Unity Pass 光照

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),会有更多的光源以逐像素的方式进行渲染。

img

向前渲染中的两种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个逐顶点光源。

img

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

img

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

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文件。

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

img

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

选择哪种渲染路径?

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

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

标签:渲染,光源,路径,Unity,Pass,光照
From: https://www.cnblogs.com/TonyCode/p/18416280

相关文章

  • 路径总和-112
    题目描述给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false。叶子节点是指没有子节点的节点。解题思路我们这题采用任何一种遍历......
  • Unity之单例模式探索
    最近在使用Unity管理远程攻击的时候涉及到了对象池,又因为需要进行脚本之间的通信,而标准通信有略显麻烦,于是使用单例的方式进行脚本之间的伪通信废话不多说,首先登场的就是最为简单的单例实现方法publicclassSingleBase:MonoBehaviour{publicstaticSingleBase......
  • 上海登陆最强台风 & 台风路径追踪 All In One
    上海登陆最强台风&台风路径追踪AllInOne上海最强台风路径追踪中央气象台、市气象服务中心介绍,今年第13号台风“贝碧嘉”(强台风级)的中心已于今天(2024年09月16日)7点30分前后在上海浦东临港新城登陆,登陆时中心附近最大风力14级(42米/秒),中心最低气压为955百帕。“贝碧嘉”也超......
  • 【油猴脚本】00008 案例 Tampermonkey油猴脚本,动态渲染表格-实现页面动态-添加表格列,
    前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • 【Unity精品源码】Ultimate Character Controller:高级角色控制器完整解决方案
    ......
  • 二叉树的所有路径(所有从根节点到叶子节点的路径)-257
    题目描述给你一个二叉树的根节点root,按任意顺序,返回所有从根节点到叶子节点的路径。叶子节点是指没有子节点的节点。解题思路这道题我们采用二叉树里的前序遍历方式,我们要遍历所有到叶子节点的路径,我们采用复用的思想,就是让这里的几个数据结构我们可以重复使用,但是重复使......
  • Field D* 路径规划
    D*算法D*算法是用于路径规划的增量式搜索算法,旨在解决在环境中有障碍物动态变化时的路径规划问题。D*算法的主要思想是在每次环境状态变化时,只更新受影响的部分路径,而不必重新规划整个路径。D*算法的核心概念包括:代价函数:通常包括实际代价函数 g 和备用代价函数 rhs......
  • 【数据结构和算法实践-树-LeetCode113-路径总和Ⅱ】
    数据结构和算法实践-树-LeetCode113-路径总和Ⅱ题目MyThought代码示例JAVA-8题目给你二叉树的根节点root和一个整数目标和targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。叶子节点是指没有子节点的节点输入:root=[5,4,8,11,null,13......
  • Unity设计模式(1) FSM有限状态机
    有限状态机(FSM)的核心原理是基于状态和状态之间的转换。它可以用来描述系统的行为和流程,尤其是在处理离散事件和复杂逻辑时使代码有较强的可维护性及健壮性。为什么使用状态机在一开始学习程序的时候,你可能会陷入一种误区,就是想把所有事情全在一个脚本里给干了,可是当你需要在......
  • 路径规划 | 基于A*算法的往返式全覆盖路径规划的改进算法(Matlab)
    目录效果一览基本介绍程序设计参考文献效果一览基本介绍基于A*算法的往返式全覆盖路径规划的改进算法matlab实现代码往返式全覆盖路径规划,通过建立二维栅格地图,设置障碍物,以及起始点根据定义往返式路径规划的定义的优先级运动规则从起始点开始进行全图遍历,利用A星算法逃离死角......