为什么在变化阴影贴图中需要时刻

时间:2013-04-14 04:59:38

标签: shader shadow

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 个答案:

答案 0 :(得分:1)

如果你不过滤纹理,这是真的,但这种阴影贴图的主要思想是可以线性过滤。过滤(深度^ 2)不等于过滤(深度)^ 2。这就是差异的来源。

非常感谢作者清理它。