<p>It seems that <code>sampler2D_float</code> doesn't allow to interpolate shadow lookup  linearly. So I had to do it by hand. Here's an example of <a href="http://codeflow.org/entries/2013/feb/15/soft-shadow-mapping/#interpolated-shadowing" rel="nofollow noreferrer">interpolated shadowing</a>.</p>

<pre><code>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;
}
</code></pre>

CC BY-SA 3.0
2017-07-28T10:46:14.160Z
2017-07-28T10:46:14.160Z
MaT
<p>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...</p>

<p>Here are two examples</p>

<pre><code>// 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;
</code></pre>

<p>Here are the results.</p>

<p><a href="https://i.sstatic.net/4NJ9e.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/4NJ9e.jpg" alt="enter image description here"></a></p>

CC BY-SA 3.0
2017-07-27T08:58:46.333Z
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
<shader><shadow><shadow-mapping><unity><directx>
DX9 Shadow map PCF issue
MaT
# DX9 Shadow map PCF issue

(Asked by: username_0 on 2017-07-26)

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](https://i.sstatic.net/4NJ9e.jpg)](https://i.sstatic.net/4NJ9e.jpg)

**Tags:** shader, shadow, shadow-mapping, unity, directx

> **Comments:**
> **username_1**: If you solved the problem yourself, please undelete the question and explain what fixed it. That will help anyone else with a similar problem.  

---

## 1 answers

### Answer by username_0 on 2017-07-28. Score: 1 | Accepted answer

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](http://codeflow.org/entries/2013/feb/15/soft-shadow-mapping/#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;
}

```


---

