Chapter 6Blurring Things Up之Using Alpha Channel

       该方法将物体绘制到RT时,和上一例子(depth imposter)仅有一个细微的差别,就是将W-buffer计算出来,保存到物体绘制RT的Alpha通道中,这里我们不讲解如何存储到Alpha通道,将重点放在如何根据深度计算Blur Amount

      书中有一个计算Blur Amount的算法:

   float Blur = max(clamp(0,1, 1 - (Depth-Near_Dist)/Near_Range),
                     clamp(0,1, (Depth-(Far_Dist-Far_Range))/Far_Range));

      当时我看了半天也没看明白这个公式的原理,无奈之下,将该公式放在Excel中进行了计算(原谅我不会用其他方法作图),最终得到一个如下的函数图像:

      

  
       图像大概是一个倒着的梯形,
       blur值随深度变化如下:

       blur=1   ________                        _________
                                \                    /
                                  \                /
                                   \              /
                                     \          /
                                      \_____/
                              blur=0
        中间的四个拐点分别是Far_Dist、Far_Dist - Far_Range、Near_Dist + Near_Range、Near_Dist,中间的两条斜线正好是直线,随Depth的变化线性变化。

        公式推导的主要难点在于两个clamp函数的最后一个参数,其实仔细想想,它跟纹理坐标变换到屏幕坐标是同一个类型的线性mapping。

        不做推导了,纹理坐标变换到屏幕坐标推导已经很清晰了,唯一要做的就是改变下mapping变换前后的范围 :)

        我们将RenderTarget的RGB图像经过三次盒型模糊,一次水平高斯模糊,一次垂直高斯模糊,此时的图像存放在Blur表面中,然后我们将Blur表面和RenderTarget表面进行blend,blend因子就是RenderTarget的α通道内的blur amount.

         最后一个需要强调的是,return lerp(SceneColor,BlurColor,SceneColor.a)中若将SceneColor和BlurColor颠倒,会出现只在模糊范围内是清晰的,而原本是清晰的位置确实模糊的。为什么要将SceneColor放在前边,请仔细参阅lerp函数的原型(blur amount为零时,SceneColor占总体颜色的100%)。

        时间不早了,赶紧睡觉了。。。。

There is no future, we create it.
原文地址:https://www.cnblogs.com/infintyward/p/3194725.html