2
$\begingroup$

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

$\endgroup$
1
  • $\begingroup$ If you solved the problem yourself, please undelete the question and explain what fixed it. That will help anyone else with a similar problem. $\endgroup$ – Dan Hulme Jul 27 '17 at 8:58
1
$\begingroup$

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;
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.