Streak演示程序中的fliter值得我们研究一下,书中描述如下:

       

      这个fliter并不好理解,S究竟是一个什么东西?对着代码研究了半天,才发现S实际上就是采样器而已。图片中下边的文字描述,也不是很清晰,仔细看源码会发现Texcoord和weight两个公式中的S根本就不是同一个值,而是属于采样器数组的不同元素,作者真是太懒了,不把这个玩意写清楚。

      根据从Demo中拷贝出来采样器代码:    

 1 sampler Texture0;
 2 float fInverseViewportWidth;
 3 float fInverseViewportHeight;
 4 const float FliterFactor = 0.96;
 5 const float FliterOffset = 1;
 6 const float4 samples[4] = {
 7 0.0, 0.0,  0, 0,
 8 1.0, -1.0, 0, 1,
 9 2.0, -2.0, 0, 2,
10 3.0, -3.0, 0, 3
11 }; 
12 
13 float4 ps_main(float2 tex : TEXCOORD0) : COLOR0
14 {  
15    float4 col = float4(0,0,0,0);
16    for(int i = 0; i < 4; i++)
17    {
18       float4 color = pow(FliterFactor, 
19                          FliterOffset*samples[i].w)*tex2D(Texture0, tex + FliterOffset*float2(samples[i].x * fInverseViewportWidth,
20                                                                                               samples[i].y * fInverseViewportHeight));
21       col += color;                                                                           
22    }  
23    return col; 
24 }

       会发现samples[4]的作用如下图:

      

       然后再根据公式:      

    float4 color = pow(FliterFactor, 
                       FliterOffset*samples[i].w)*tex2D(Texture0, tex + FliterOffset*float2(samples[i].x * fInverseViewportWidth,
                                                                                            samples[i].y * fInverseViewportHeight)); ---------------公式1
这样我们就找到了Sample中每一个元素在公式中对应的位置及其作用。samples[i]x,samples[i].y我们之前就已经接触过了,用来计算Render to texture时,与当前像素相邻的像素对应的纹理坐标。

samples[i].w
代表每一个所采样的像素所占的比重,我们假设FliterOffset为1,FliterFactor为0.96,带入到pow(FliterFactor, FliterOffset*samples[i].w)公式有:
pow(0.96, 1*samples[i].w),由于指数函数的底小于1,它是一个减函数,samples[i].w越大,它的值越小。

我们再来把所有参数都带入公式1(我们假设FliterOffset为1,FliterFactor为0.96,跟上边一样),得到:
float4 color = pow(0.96,1 * samples[i].w) * tex2D(Texture0,
tex +
1 * float2(samples[i].x * fInverseViewportWidth, samples[i].y * fInverseViewportHeight));
由于上述的公式是处在一个循环中,我们可以看到,随着i的增加,采样像素离当前像素每次增加1,越来越远,但是采样点的亮度受到前边pow的制约,也越来越暗,恰巧说明了Steak现象,离光源越远,光带越暗。
现在我们分析完了FliterOffset为1的时候的采样,即Pass1中,书中说FliterOffset是随着Pass的增加而正比例增加的,在Pass2中FliterOffset取4,在Pass2中FliterOffset取16,在Pass2中FliterOffset取16,在Pass3中FliterOffset取64,
我们来看下在Pass2中公式是什么样子,只要将上边公式中的1改成4就行了
float4 color = pow(0.96,4 * samples[i].w) * tex2D(Texture0,
tex +
4 * float2(samples[i].x * fInverseViewportWidth, samples[i].y * fInverseViewportHeight));
可以看到随着Pass的增加,采样点距离当前像素越来越远,而且受Pow亮度因子控制越来越暗。说明光带越来越长,离当前像素越远,越暗,暗过前一个Pass中的亮度。

FliterFactor我们始终采用的是0.96,也可以采取其他值,它只不过用来控制距离当前像素越远的点,亮度衰减的快慢,它取值越大,衰减越慢,取值越小,衰减越快。

PS:到目前为止,我都没有看懂书中的表述,直接分析了源代码,回头在看书中的表述,还是头晕看不懂,于是我决定写下这个采样器的分析,让其他读者不至于在这个地方感到困惑。

  

//end....




 

posted on 2013-08-10 11:39  infinityward  阅读(207)  评论(0编辑  收藏  举报