How to "unpack" unity_LightShadowBias and _WorldSpaceLightPos0 values?

Hi,

The title might be a bit confusing. I am trying to understand the internal values of the listed variables. This is what I found so far:

====================================================

Bias variable seems most complicated:
unity_LightShadowBias.z - Normal Bias?
unity_LightShadowBias.x - Bias value ?
unity_LightShadowBias.y - What is here?

====================================================

_WorldSpaceLightPos0.xyz - location of the light source
_WorldSpaceLightPos0.w - what is this?

For example:

// Computes world space light direction, from world space position
inline float3 UnityWorldSpaceLightDir( in float3 worldPos )
{
    #ifndef USING_LIGHT_MULTI_COMPILE

       // LINE OF INTEREST
        return _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w;
    #else
        #ifndef USING_DIRECTIONAL_LIGHT
        return _WorldSpaceLightPos0.xyz - worldPos;
        #else
        return _WorldSpaceLightPos0.xyz;
        #endif
    #endif
}

My crazy guess _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w normalizes vector somehow. Am I correct?

_WorldSpaceLightPos0.w is either 0 or 1, and xyz is either a normalized world direction or a world space position. If it’s a direction, and the w is 0, the worldPos is ignored as you already have a world space direction for directional lights. If it’s a 1 the worldPos is subtracted from the world position, and the normalized result would be the world space direction for point / spot lights.

Cool thanks for the link. This is very helpful. Though any ideas what unity_LightShadowBias.y might be for? What is inside?

The code I am referring to is this:

float4 UnityApplyLinearShadowBias(float4 clipPos)
{
#if defined(UNITY_REVERSED_Z)
    clipPos.z += clamp(unity_LightShadowBias.x/clipPos.w, -1, 0);
    float clamped = min(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);
#else
    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;
}

Still trying to figure out unity_LightShadowBias components. Any clues on this?

unity_LightShadowBias.x = Bias (the top one) * 2 for point + spot. Somehow related linearly to min(cam.farClip, shadow distance - shadow near plane offset) for directional

unity_LightShadowBias.y = ?
The only thing I’ve found so far is that it’s 0 for point and spot, and 1 for directional. Switching to area doesn’t change it (the value stays with whichever the last value was). It also seems to be using the value of the most “important” light. No other clues at the moment though, sorry.

unity_LightShadowBias.z = something with normal bias, too busy to investigate further though :confused:

why unity_LightShadowBias.x is divided by clipPos.w in UnityApplyLinearShadowBias()?
Isn’t it will be divide by clipPos.w by perspective divide later, so it’s divide by clipPos.w twice, why?

The bias should be propotional to change rate of the nonlinear z, which is in form of (a/z + b). Its derivative is -2a/(z^2),where the twice division come from.