2013-04-14 113 views
2

This article中需要的瞬間描述瞭如何使用方差陰影貼圖來渲染陰影。爲什麼在方差陰影貼圖

它說,將場景渲染到陰影貼圖時,應該存儲深度和深度的平方(使用偏導數進行偏置調整)。

float2 ComputeMoments(float Depth) 
{ 
    float2 Moments; 
    // First moment is the depth itself. 
    Moments.x = Depth; 
    // Compute partial derivatives of depth. 
    float dx = ddx(Depth); 
    float dy = ddy(Depth); 
    // Compute second moment over the pixel extents. 
    Moments.y = Depth*Depth + 0.25*(dx*dx + dy*dy); 
    return Moments; 
} 

您再檢查您的深處對陰影貼圖是這樣的:

float ChebyshevUpperBound(float2 Moments, float t) 
    { 
     // One-tailed inequality valid if t > Moments.x 
     float p = (t <= Moments.x); 
     // Compute variance. 
     float Variance = Moments.y – (Moments.x*Moments.x); 
     Variance = max(Variance, g_MinVariance); 
     // Compute probabilistic upper bound. 
     float d = t – Moments.x; 
     float p_max = Variance/(Variance + d*d); 
     return max(p, p_max); 
    } 

    float ShadowContribution(float2 LightTexCoord, float DistanceToLight) 
    { 
     // Read the moments from the variance shadow map. 
     float2 Moments = texShadow.Sample(ShadowSampler, LightTexCoord).xy; 
     // Compute the Chebyshev upper bound. 
     return ChebyshevUpperBound(Moments, DistanceToLight); 
    } 

然後文章說,您可以用不偏深的平方在所有的,只是確保脫身將方差限制到最小值。在本書附帶的源代碼中,計算偏差的代碼已被註釋掉,並且只是爲了限制到最小方差。

那麼爲什麼要將深度平方存儲在第一位呢?此外,爲什麼不跳過方差的計算,並且總是使用最小方差?如果第1時刻是深度,第2時刻是深度的平方,那麼方差是不是總是達到0?

float Variance = Moments.y – (Moments.x*Moments.x); 

回答

1

如果不過濾紋理,這將是真實的,但這種類型的陰影貼圖的主要想法是,它可以線性濾波。已過濾(深度^ 2)不等於已過濾(深度)^ 2。這是差異來自的地方。

非常感謝作者對此進行清理。