2

I am trying to do simple PCF with Unity but I am facing some issues and I don't know where they come from. If anybody has an idea...

Here are two examples

// C#
GetTemporaryRT(_shadowMapProperty, _shadowSettings.shadowAtlasWidth, _shadowSettings.shadowAtlasHeight, _depthBufferBits, FilterMode.Bilinear, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear);

// CG
sampler2D_float _ShadowMap;
float4 _ShadowMap_TexelSize;

half ShadowAttenuation(float3 shadowCoord)
{
    float depth = tex2D(_ShadowMap, shadowCoord).r;
#if defined(UNITY_REVERSED_Z)
    return step(depth - _ShadowData.y, shadowCoord.z);
#else
    return step(shadowCoord.z, depth + _ShadowData.y);
#endif
}

/////// EXAMPLE 1 /////// 

float shadow = ShadowAttenuation(half3(shadowCoord.xy, shadowCoord.z));
return shadow;

/////// EXAMPLE 2 ///////

float3 UnityCombineShadowcoordComponents(float2 baseUV, float2 deltaUV, float depth)
{
    float3 uv = float3(baseUV + deltaUV, depth);
    uv.z += dot(deltaUV, receiverPlaneDepthBias.xy);
    return uv;
} 

half shadow = 1;
const float2 offset = float2(0.5, 0.5);
float2 uv = (shadowCoord.xy * _ShadowMap_TexelSize.zw) + offset;
float2 base_uv = (floor(uv) - offset) * _ShadowMap_TexelSize.xy;
float2 st = frac(uv);

float2 uw = float2(3 - 2 * st.x, 1 + 2 * st.x);
float2 u = float2((2 - st.x) / uw.x - 1, (st.x) / uw.y + 1);
u *= _ShadowMap_TexelSize.x;

float2 vw = float2(3 - 2 * st.y, 1 + 2 * st.y);
float2 v = float2((2 - st.y) / vw.x - 1, (st.y) / vw.y + 1);
v *= _ShadowMap_TexelSize.y;

half sum = 0;

sum += uw[0] * vw[0] * ShadowAttenuation(UnityCombineShadowcoordComponents(base_uv, float2(u[0], v[0]), shadowCoord.z));
sum += uw[1] * vw[0] * ShadowAttenuation(UnityCombineShadowcoordComponents(base_uv, float2(u[1], v[0]), shadowCoord.z));
sum += uw[0] * vw[1] * ShadowAttenuation(UnityCombineShadowcoordComponents(base_uv, float2(u[0], v[1]), shadowCoord.z));
sum += uw[1] * vw[1] * ShadowAttenuation(UnityCombineShadowcoordComponents(base_uv, float2(u[1], v[1]), shadowCoord.z));

shadow = sum / 16.0f;
return shadow;

Here are the results.

enter image description here

MaT
  • 1,219
  • 10
  • 21
  • If you solved the problem yourself, please undelete the question and explain what fixed it. That will help anyone else with a similar problem. – Dan Hulme Jul 27 '17 at 08:58

1 Answers1

1

It seems that sampler2D_float doesn't allow to interpolate shadow lookup linearly. So I had to do it by hand. Here's an example of interpolated shadowing.

float texture2DCompare(sampler2D depths, vec2 uv, float compare){
    float depth = texture2D(depths, uv).r;
    return step(compare, depth);
}

float texture2DShadowLerp(sampler2D depths, vec2 size, vec2 uv, float compare){
    vec2 texelSize = vec2(1.0)/size;
    vec2 f = fract(uv*size+0.5);
    vec2 centroidUV = floor(uv*size+0.5)/size;

    float lb = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 0.0), compare);
    float lt = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 1.0), compare);
    float rb = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 0.0), compare);
    float rt = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 1.0), compare);
    float a = mix(lb, lt, f.y);
    float b = mix(rb, rt, f.y);
    float c = mix(a, b, f.x);
    return c;
}
MaT
  • 1,219
  • 10
  • 21