景深和HDR一样,都是post-process,因此他们都需要多个RenderTarget(一般),然后将场景渲染一遍,再进行进一步处理。
景深比HDR简单一些,大体上有三个步骤:1在渲染场景的VS中,将顶点有关深度的信息(例如BlurFactor,或者直接深度)保存在Alpha通道中;2渲染一个模糊的场景图,这里可以采用和HDR中一样的处理;3在PS中利用深度信息将模糊图和普通图进行插值渲染。
下面是FX文件中比较重要的代码:
// Compute blur factor and place in output alpha
fBlurFactor = dot(float4(vViewPosition, 1.0), vFocalPlane)*fHyperfocalDistance;
Output.Diffuse.a = fBlurFactor*fBlurFactor;
计算BlurFactor。
for(int i = 0; i < 3; i++)
{
// Lookup into the rendertarget based on a texture coord.
// See app's SetupQuad() to see how the texture coords are created
Jitter[i] = tex2D(RenderTargetSampler, JitterUV[i]);
// Lerp between original rgb and the jitter rgb based on the alpha value
if( bWithRings )
Jitter[i].rgb = lerp(Original.rgb, Jitter[i].rgb, Original.a);
else
Jitter[i].rgb = lerp(Original.rgb, Jitter[i].rgb, saturate(Original.a*Jitter[i].a));
}
// Average the first two jitter samples
Blurred = lerp(Jitter[0].rgb, Jitter[1].rgb, 0.5);
// Equally weight all three jitter samples
Blurred = lerp(Jitter[2].rgb, Blurred, 0.66666);
采样数为4,注意,这个例子没有采用直接渲染一个模糊场景,而是在PS中进行模糊计算,这样效率应该没有预先渲染的好。