UnityApplyLinearShadowBias -- Unity中计算阴影bias的方法

 

 

作用:

在裁剪空间中的线性增加Z坐标的值

偏移片元在光源空间下的裁剪坐标,用于解决shadow acne(阴影失真)的问题。该偏移作用于光源生成阴影深度图的时候。

原理:

通过减少光源到物体的深度图的数值(距离越远数值越小),从而使光源到物体表面片元的距离更大一些,即阴影深度图里像素数值更小。在接受阴影pass的片元着色器中,比较物体片元到光源的距离和阴影深度图的距离时(片元到光源的距离小于光源阴影深度图里的数值时,片元被照亮。),把处于边界值的片元被照亮。

如下图,如果不启用bias,ad片元能被照射到,而bc片元则不能被照射到。详细说明:https://blog.csdn.net/lawest/article/details/106364935

preview

源码:

float4 UnityApplyLinearShadowBias(float4 clipPos)
{
#if defined(UNITY_REVERSED_Z)
    // We use max/min instead of clamp to ensure proper handling of the rare case
    // where both numerator and denominator are zero and the fraction becomes NaN.
	// Direct3D11-like
    clipPos.z += max(-1, min(unity_LightShadowBias.x / clipPos.w, 0));
    float clamped = min(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);
#else
	// Direct3D9-like OpenGL-like
    clipPos.z += saturate(unity_LightShadowBias.x/clipPos.w); //
    float clamped = max(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);
#endif
    clipPos.z = lerp(clipPos.z, clamped, unity_LightShadowBias.y);
    return clipPos;
}

源码分析:(本人并不确定,望指教)

clipPos.z += saturate(unity_LightShadowBias.x/clipPos.w);:

clipPos是裁剪空间下的齐次坐标:(N * x, N * y, az + b,  -z), 其中x,y,z分别是相机空间下的坐标数值

unity_LightShadowBias.x是一个负数,默认一般是-0.0005,除以clipPos.w也就是除以相机空间下的-z,可以知道为了补偿透视投影,这里除以clipPos.w之后片元距离光源越远偏移量越小。近大远小?至于数学层面的分析本人还不清楚。

float clamped = max(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);:

UNITY_NEAR_CLIP_VALUE是NDC空间下z的最小值。这行代码就是当clipPos.z比近裁切面还要小的时候取近裁切面的值

clipPos.z = lerp(clipPos.z, clamped, unity_LightShadowBias.y);:

unity_LightShadowBias.y, 当光源是平行光的时候该值为1,其他光源为0,当是平行光时最后clipPos直接取clamped的值,这是为了避免在平行光原点背面的片元的深度也保持在0~1,当然平行光并没有原点,这里这是方便计算。当不是平行光的时候该值为0,相当于直接取上面偏移bias之后的clipPos的值。

 

 

应用:

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值