本文不是延迟渲染原理的陈述,阅读本文之前,建议先了解了延迟渲染的底层实现原理:替换帧缓冲,绑定缓冲附件之类。
哪怕你对OpenGL的延迟渲染已经很了解了,你对Unity中如何使用延迟渲染可能也是一脸懵逼,下面直接正文
Unity中使用延迟渲染需要了解一些Unity ShaderLab的内置变量。这里只说延迟渲染相关的比较重要的几个:
sampler2D _CameraGBufferTexture0;
sampler2D _cameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
类推...
在Unity中
Tags {"LightMode" = "Deferred"}
的Pass,在Unity的RenderPath设定为Deferred时,或者在摄像机的RenderPath设定为Deferred时,Unity会自动将该Pass渲染输出到缓冲附件中。而输出语义设定为SV_TARGET0, SV_TARGET1, SV_TARGET2...(或者COLOR0, COLOR1, COLOR2)
因为不同的输出信息实际上需要不同的精度,而Unity这几个输出语义似乎并没有给出具体的精度信息(我确实没找到,如果有请指出),但是Unity有给出几个建议的用法,陈列如下:
SV_TARGET0:diffuse color
SV_TARGET1:RGB:specular + A:roughness
SV_TARGET2:normalWorld
SV_TARGET3:emission/lighting
例如:
//ShaDe_r
//下面只以像素着色器代码为例
#pragma fragment frag
struct FragmentOutput{
float4 diffuseCol : SV_TARGET0;
float4 specular : SV_TARGET1;
float4 norWorld : SV_TARGET2;
float4 emission : SV_TARGET3;
};
FragmentOutput frag(){
FragmentOutput o;
o.diffuseCol = computeDiffuse();
o.specular.rgb = computeSpecularCol();
o.specular.a = computeSpecularRoughness();
o.norWorld = computeNorWorld();
o.emission = computeEmission();
return o;
}
至此,缓冲附件渲染完毕,接下来就是缓冲附件的应用,计算光照
Unity的延迟渲染通道的末尾就进入正向渲染通道,在正向渲染通道中使用缓冲附件来计算光照,在CGPROGRAM中声明:
sampler2D_CameraGBufferTexture0;
sampler2D _CameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
_CameraGBufferTexture0对应SV_TARGET0
_CameraGBufferTexture1对应SV_TARGET1
以此类推...
而后就像采样普通纹理一样采样这几个纹理缓冲,得到像素信息,进行光照计算即可。
如有错误请指正,谢谢。