<p>Ok, I got it.
<code>i.shadowMapUV.z</code> is &lt; 0.f because it's mapped to -1;1 between near;far.
Forward is also at -Z, so correct way to calculate <code>shadowPosition</code> is:</p>
<pre><code>float4 shadowPosition= mul( _CustomShadowsMatrix, float4(worldPos, 1.f) );
shadowPosition.xyz /= shadowPosition.w;
shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
shadowPosition.z = -shadowPosition.z * 0.5f + 0.5f;
</code></pre>

CC BY-SA 4.0
2022-03-24T16:33:40.303Z
2022-03-24T16:33:40.303Z
Derag
<p>due to some features in materials I need to create my own directional shadow map.</p>
<p>Everything seems to work ok, until the moment where I compare depths.</p>
<p>First I add camera component to directional light with RenderTexture:</p>
<p><a href="https://i.sstatic.net/qTZMn.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/qTZMn.png" alt="enter image description here" /></a>
<a href="https://i.sstatic.net/WPyh7.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/WPyh7.png" alt="enter image description here" /></a></p>
<p>then in code, I set this texture and camera projection matrix as global variables for shaders:</p>
<pre><code>Camera shadowCaptureCamera = GetComponent&lt;Camera&gt;();
Shader.SetGlobalTexture(&quot;_CustomShadowsTex&quot;, shadowCaptureCamera.targetTexture, UnityEngine.Rendering.RenderTextureSubElement.Depth);
           
Matrix4x4 worldToClipMatrix = shadowCaptureCamera.projectionMatrix * shadowCaptureCamera.worldToCameraMatrix;
Shader.SetGlobalMatrix(&quot;_CustomShadowsMatrix&quot;, worldToClipMatrix);
</code></pre>
<p>Then in shaders I do this:</p>
<pre><code>v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);

    float4 worldPos = mul( unity_ObjectToWorld, float4( v.vertex.xyz, 1.0f) );
    float4 shadowPosition = mul( _CustomShadowsMatrix, worldPos );
    shadowPosition.xyz /= shadowPosition.w;
    shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
    o.shadowMapUV = shadowPosition;
    return o;
}

fixed4 frag(v2f i) : SV_Target
{

    ......

    float shadowDepth = tex2D( _CustomShadowsTex, i.shadowMapUV.xy ).r;             
    float atten = shadowDepth &gt; abs(i.shadowMapUV.z) ? 1.0f : 0.0f;
    return atten;
}
</code></pre>
<p>Everything has value 1.0f.</p>
<p>Any idea what's wrong? It samples shadow at correct place, but something is wrong with values. I'm also not sure why i.shadowMapUV.z is &lt;0.f. Looking at matrix's values it shouldn't be.</p>

<shader><projections><unity><shadow-mapping>
Unity - custom shadow from sun
Derag
# Unity - custom shadow from sun

(Asked by: username_0 on 2022-03-24)

due to some features in materials I need to create my own directional shadow map.

Everything seems to work ok, until the moment where I compare depths.

First I add camera component to directional light with RenderTexture:

[![enter image description here](https://i.sstatic.net/qTZMn.png)](https://i.sstatic.net/qTZMn.png)
[![enter image description here](https://i.sstatic.net/WPyh7.png)](https://i.sstatic.net/WPyh7.png)

then in code, I set this texture and camera projection matrix as global variables for shaders:

```
Camera shadowCaptureCamera = GetComponent<Camera>();
Shader.SetGlobalTexture("_CustomShadowsTex", shadowCaptureCamera.targetTexture, UnityEngine.Rendering.RenderTextureSubElement.Depth);
           
Matrix4x4 worldToClipMatrix = shadowCaptureCamera.projectionMatrix * shadowCaptureCamera.worldToCameraMatrix;
Shader.SetGlobalMatrix("_CustomShadowsMatrix", worldToClipMatrix);

```

Then in shaders I do this:

```
v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);

    float4 worldPos = mul( unity_ObjectToWorld, float4( v.vertex.xyz, 1.0f) );
    float4 shadowPosition = mul( _CustomShadowsMatrix, worldPos );
    shadowPosition.xyz /= shadowPosition.w;
    shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
    o.shadowMapUV = shadowPosition;
    return o;
}

fixed4 frag(v2f i) : SV_Target
{

    ......

    float shadowDepth = tex2D( _CustomShadowsTex, i.shadowMapUV.xy ).r;             
    float atten = shadowDepth > abs(i.shadowMapUV.z) ? 1.0f : 0.0f;
    return atten;
}

```

Everything has value 1.0f.

Any idea what's wrong? It samples shadow at correct place, but something is wrong with values. I'm also not sure why i.shadowMapUV.z is <0.f. Looking at matrix's values it shouldn't be.

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


---

## 1 answers

### Answer by username_0 on 2022-03-24. Score: 0 | Accepted answer

Ok, I got it.
`i.shadowMapUV.z` is < 0.f because it's mapped to -1;1 between near;far.
Forward is also at -Z, so correct way to calculate `shadowPosition` is:

```
float4 shadowPosition= mul( _CustomShadowsMatrix, float4(worldPos, 1.f) );
shadowPosition.xyz /= shadowPosition.w;
shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
shadowPosition.z = -shadowPosition.z * 0.5f + 0.5f;

```


---

