Unity Shader入门精要总结--渲染路径
来源:互联网 发布:怎么在淘宝举报店铺 编辑:程序博客网 时间:2024/05/23 02:05
前向渲染路径
原理
每进行一次完整的前向渲染,我们需要渲染该对象的渲染图元,并计算两个缓冲区的信息:一个是颜色缓冲区,一个是深度缓冲区。我们利用深度缓冲来决定一个片元是否可见,如果可见就更新颜色缓冲区中的颜色值。我们可以用下面的伪代码来描述前向渲染路径的大致过程:
Pass { for(each primitive in this model){ for(each fragment coverd by this primitive){ if(failed in depth test){ //如果没有通过深度测试,说明该片元是不可见的 discard; } else{ //如果该片元可见,就进行光照计算 float4 color = Shading(materialInfo,pos,normal,lightDir,viewDir); //更新帧缓冲 writeFrameBuffer(fragment,color); } } } }
Unity中的前向渲染
在Unity中,前向渲染路径有3种处理光照的方式:逐顶点处理、逐像素处理、球谐函数处理。而决定一个光源使用哪种处理模式取决于它的类型和渲染模式。光源类型指的是该光源是平行光还是其他类型的光源,而光源的渲染模式指的是该光源是否是重要的。如果我们把一个光照的模式设置为Important,意味着我们告诉Unity“这个光源很重要,把它当成一个逐像素光源来处理”。我们可以在光源的Light组件中设置这些属性。
- Unity 使用的判断规则如下。
场景中最亮的平行光总是按逐像素处理的。
渲染模式被设置成Not Important的光源,会按逐顶点或者SH处理。
如果根据以上规则得到的逐像素光源数量小于Quality Setting 中的逐像素光源数量(Pixel Light Count),会有更多的光源以逐像素的方式进行渲染。
前向渲染有两种Pass:Base Pass 和 Addition Pass。这两种Pass 进行的标签和渲染设置以及常规光照计算如下图所示。
- Unity 使用的判断规则如下。
内置光照变量和函数
顶点照明渲染路径
顶点照明渲染路径是对硬件配置要求最少、运算性能最高、但同时也是得到的效果最差的一种类型,它不支持那些逐像素才能得到的效果,例如阴影、法线映射、高精度的高光反射等。它只是使用了逐顶点的方式来计算光照。实际上,我们在上面的前向渲染路径中也可以计算一些逐顶点的光源。但如果选择使用顶点照明渲染路径,那么Unity会只填充那些逐顶点相关的光源变量,意味着我们不可以使用一些逐像素光照变量。
Unity中的顶点照明渲染
顶点照明渲染路径通常在一个Pass 中就可以完成对物体的渲染。在这个Pass中,我们会计算我们关心的所有光源对该物体的照明,并且这个计算是按逐顶点处理的。这是Unity中最快速的渲染路径,并且具有最广泛的硬件支持。
内置光照变量和函数
延迟渲染路径
前向渲染的问题是:当场景中包含大量实时光源时,前向渲染的性能会急速下降。例如,如果我们在场景的某一块区域放置了多个光源,这些光源影像的区域互相重叠,那么为了得到最终的光照效果,我们就需要为该区域内的每个物体执行多个Pass来计算不同光源对物体的光照结果,然后再颜色缓存中把这些结果混合起来得到最终的光照。然而,每执行一个Pass我们都需要重新渲染一遍物体,但很多计算实际上是重复的。
延迟渲染是一张更古老的渲染办法。除了前向渲染中使用的颜色缓冲和深度缓冲外,延迟渲染还会利用额外的缓冲区,这些缓冲区也被称为G缓冲。G缓冲区存储了我们所关心的表面的其他信息,例如该表面的法线、位置、用于光照计算的材质属性等。
延迟渲染原理
延迟渲染主要包含了两个Pass。在第一个Pass中,我们不进行任何光照计算,而是仅仅计算哪些片元是可见的,这主要是通过深度缓冲技术来实现,当发现一个片元是可见的,我们就把它的相关信息存储到G缓冲区中。然后,在第二个Pass中,我们利用G缓冲区的各个片元信息,例如表面法线、视角方向、漫发射系数等,进行真正的光照计算。
延迟渲染的过程大致可以用下面的伪代码来描述:
Pass1{ //第一个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); } } } } Pass2{ //利用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有两种延迟渲染路径,一种是Unity5之前使用的延迟渲染路径,而另一种是Unity5.x中使用的延迟渲染路径。新旧延迟渲染路径之间的差别很小,只是使用了不同的技术来权衡不同的需求
当使用延迟渲染时,Unity 要求我们提供两个Pass:第一个Pass用于渲染G缓冲。在这个Pass中,我们会把物体的漫反射颜色、高光发射颜色、平滑度、法线、自发光和深度等信息渲染到屏幕空间的G缓冲区中。对于每个物体来说,这个Pass仅会执行一次。
第二个Pass用于计算真正的光照模型。这个Pass会使用上一个Pass中渲染的数据来计算最终的光照颜色,再存储到帧缓冲中。
默认的G缓冲区(注意,不同Unity版本的渲染纹理存储内容会有所不同)包含了以下几个渲染纹理(Render Texture,RT)。
- RT0:格式是ARGB32,RGB通道用于存储漫反射颜色,A通道没有被使用。
- RT1:格式是ARGB32,RGB通道用于存储高光反射颜色,A通道同于用于存储高光反射的指数部分。
- RT2:格式是ARGB2101010,RGB通道用于存储法线,A通道没有被使用。
- RT3:格式是ARGB32,用于存储自发光+lightmap+反射探针
- 深度缓冲和模板缓冲。
可访问的变量和函数
- Unity Shader入门精要总结--渲染路径
- 【Unity Shader入门精要】— 渲染流水线
- Unity Shader入门精要总结--基本光照
- Unity Shader入门精要总结--透明效果
- Unity Shader入门精要总结--光照衰减
- <unity shader入门精要>
- Unity Shader入门精要笔记(一):渲染流水线
- unity shader入门精要 前3章总结
- Unity Shader入门精要读书笔记第一篇
- Unity Shader入门精要读书笔记第二篇
- 【Unity Shader入门精要】学习开篇
- 《Unity shader 入门精要》学习 前言
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要 学习笔记一
- Java 设计模式_观察者模式
- 【剑指offer】面试题39:数组中出现次数超过一半的数字
- [kuangbin带你飞]专题二 搜索进阶 C
- 通过控制台输出文件和启动程序
- Java 设计模式_模板模式
- Unity Shader入门精要总结--渲染路径
- 欢迎使用CSDN-markdown编辑器
- GUI
- 【Leetcode】【python】Unique Binary Search Trees
- html+css小游戏
- 设计模式
- 计算机视觉小实例 No.2 基于形态学的权重自适应图像去噪
- python006 Python3 运算符
- 推介一个Python教程网站