渲染路径
决定了光照如何应用到Unity Shader中
整个项目设置渲染路径:
使用多个渲染路径,可以在每个摄像机的渲染路径设置中设置该摄像机使用的渲染路径,覆盖Project Settings中的设置
如果当前显卡不支持所选择的渲染路径 ,Unity会自动使用更低一级的渲染路径
Pass块内可选择的渲染路径:
前向渲染路径(Forward)
是传统的渲染方式。
原理:渲染该对象的渲染图元,计算两个缓冲区信息(颜色缓冲区、深度缓冲区)。利用深度的缓冲判断片元是否可见,可见就更新颜色缓冲,否则就丢弃。
描述前向渲染路径的大致过程:
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);
}
}
}
}
如果有N个物体受M个光源影响就需要N*M个Pass。渲染引擎通常会限制每个物体的逐像素光照数目
前向渲染有3种处理光照方式:
- 逐顶点处理。
- 逐像素处理。
- 球谐函数(Spherical Harmonics, SH)处理。
Unity使用的判断规则:
- 场景中最亮的平行光按逐像素处理。
- Render Mode 为 Not Important的光源,会逐顶点或者SH处理。
- Render Mode 为 Important的光源,会逐像素处理。
- 如果上面得到的逐像素光源小于Quality Setting中的逐像素光源数量,会有过更多光源以逐像素的方式进行渲染。
前向渲染两种Pass: - Base Pass。一般一个Unity Shader定义一个(双面渲染的话两个),执行一次。
- Additional Pass。如果有N个光源影响该物体,就会执行N次。
注:在Additional Pass的渲染设置中,开启和设置了混合模式。这是因为,我们希望每个Additional Pass可以和上一次的光照结果在帧缓存中进行叠加,从而得到最终的有多个光照的渲染效果。如果没有开启和设置渲染混合模式,那个Additional Pass的渲染结果会覆盖掉之前的渲染结果,看起来就好像该物体只受该光源的影响。通常情况下,我们选择的混合模式是Blend One One
前向渲染可以使用的内置光照变量和函数:
顶点照明渲染路径(Vertex)
逐顶点计算光照。硬件配置要求最低,运算性能最高,效果最差的类型,不支持逐像素效果(如:阴影、法线映射、高精度高光反射等)。
延迟渲染路径(Deferred)
前向渲染问题是:当场景中包含大量实时光源时,前向渲染的性能会急速下降。
使用额外的缓冲区(G缓冲,Geometry-buffer),存储离摄像机最近的表明的其他信息(表面法线、位置、材质属性等)。避免前向渲染在大量实时光照下时的性能急速下降。实现就用两个Pass,与场景光源数目无关,而是和屏幕空间大小有关。
主要包含两个Pass:
- 第一个Pass:只计算哪些片元可见(深度缓冲技术),可见的就存到G缓冲中。
- 第二个Pass:利用G缓冲中的片元信息,计算光照。
延迟渲染的整个过程大致可以用下面的伪码来描述:
Pass1{
for(each primitive in this model){
for(each fragment covered by this primitive){
if(failed in depth test){
discard;
}else{
writeGBuffer(materialInfo, pos, normal);
}
}
}
}
Pass2{
for(each pixel in the screen){
if(the pixel is valid){
// 如果该像素是有效的
// 读取它对应G缓存中的数据
readGBuffer(pixel, materialInfo, pos, normal);
// 根据数据进行光照计算
float4 color = Shading(...);
writeFrameBuffer(pixel, color);
}
}
}
缺点:
- 不支持真正的抗锯齿(anti-aliasing)功能。
- 不能处理半透明物体。
- 显卡必须支持MRT(Multiple Render Targets)、Shader Mode3.0及以上、深度渲染纹理以及双面的模版缓冲。
G缓冲区所包含的渲染纹理:
延迟渲染可以使用的内置变量:
Unity中的延迟渲染
Unity中有两种延迟渲染,在此我们不讨论遗留的延迟渲染。如果游戏中含有大量的实时光照,那么我们可能希望选择延迟渲染路径,但需要一定的硬件支持。
对于延迟渲染路径来说,它适合场景光源数目多、如果使用前向渲染会造成性能瓶颈的情况下使用。但是,延迟渲染有一些缺点:
不支持真正的抗锯齿(anti-aliasing)功能
不能处理半透明物体
对显卡有一定要求。如果要使用延迟渲染的话,显卡必须支持MRT(Multiple Render Targets)、Shader Mode 3.0及以上、深度渲染纹理以及双面的模板缓冲。
当使用延时渲染时,Unity要求我们提供两个Pass。
第一个Pass用于渲染G缓存。在这个Pass中,会把物体的漫反射颜色、高光反射颜色、平滑度、法线、自发光和深度等信息渲染到屏幕空间的G缓冲区中。对每个物体来说,这个Pass仅会执行一次。
第二个Pass用于计算真正的光照模型。这个Pass会使用上一个Pass中的渲染数据来计算最终光照颜色,存储到帧缓冲中。
默认的G缓冲中渲染目标(Render Target, RT)列举如下(括号内字母表示通道),不同版本可能不同:
RT0,ARGB32格式,(RGB)存储漫反射颜色,(A)没有被使用
RT1,ARGB32格式,(RGB)存储高光反射颜色(RGB),(A)存储高光反射的指数部分
RT2,ARGB2101010格式,(RGB)存储世界空间的法线信息,(A)没有被使用
RT3,ARGB2101010(非HDR)或ARGBHalf(HDR)格式,用于存储自发光+lightmap + 反射探针(reflection probes)
深度缓冲+ 模板缓冲(Stencil buffer)