<p>I found out that simply removing minus sign in shader in converting coords to [0, 1] solved direction problem. But scale is still off - here is an example:</p>

<p><a href="https://i.sstatic.net/v6lK0.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/v6lK0.png" alt="Wrong scale - peter panning"></a></p>

<pre><code>void LightClass::GenerateViewMatrix()
{
    XMVECTOR eyePos = { m_position.x, m_position.y, m_position.z };
    XMVECTOR focusPos = { m_lookAt.x, m_lookAt.y, m_lookAt.z };
    XMVECTOR upVec = { 0, 1, 0 };

    m_viewMatrix = XMMatrixLookAtLH(eyePos, focusPos, upVec);
}

void LightClass::GenerateProjectionMatrix(float screenDepth, float screenNear)
{
    float fieldOfView = (float)3.14f / 2.0f;
    float screenAspect = 16.0f / 9.0f;

    m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);
}
</code></pre>

<p><strong>Edit [Actual solution - ignore previous posts]:</strong></p>

<p>I followed PaulHK solution (thanks, it's second time you've helped me) about checking once again View/Projection matrix. Basically my calculations were wrong. I debugged my convertions from model to lightspace and changed <strong>Vertex Shader</strong> from:</p>

<pre><code>output.lightViewPosition = mul(input.position, worldMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightViewMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightProjectionMatrix);
</code></pre>

<p>To correct:</p>

<pre><code>matrix lightViewProj = mul(g_lightProjectionMatrix, g_lightViewMatrix);
output.lightViewPosition = mul(input.position, lightViewProj);
</code></pre>

<p>That simple changed fixed my results. With simple <strong>Pixel shader</strong> code below I am getting this results:</p>

<pre><code>input.lightViewPosition.xyz /= input.lightViewPosition.w;

tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

depthValue = shadowMap.Sample(SampleType, tex).r;
return color = float4(depthValue, depthValue, depthValue, 1.0f);
</code></pre>

<p><a href="https://i.sstatic.net/ylu0o.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ylu0o.png" alt="Correct shadow-map"></a>
However, even if it seems correct, my suspicion is that I need to compare my shadowmap to light Z-buffer so I modified my Pixel Shader and added little tint:</p>

<pre><code>input.lightViewPosition.xyz /= input.lightViewPosition.w;

tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

depthValue = shadowMap.Sample(SampleType, tex).r;
color = float4(depthValue, depthValue, depthValue, 1.0f);

lightDepthValue = input.lightViewPosition.z - bias;
if(lightDepthValue &lt; depthValue)
{
    lightIntensity = saturate(dot(input.normal, input.lightPos));

    if(lightIntensity &gt; 0.0f)
    {
        // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
        color += (ambientColor * lightIntensity);

        // Saturate the final light color.
        color = saturate(color);
    }
}
return color;
</code></pre>

<p>I may not be right, but without this checking, you would get errors with more complicated shadows. Because my previous PixelShader code basically just project shadowmap on plane without any actual depth checking. Therefore it would lay shadowmap on everything it can without even checking if that's correct.</p>

<p><a href="https://i.sstatic.net/X5fzu.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/X5fzu.png" alt="Correct shadow-map with depth checking"></a></p>

CC BY-SA 4.0
2019-03-13T17:57:25.150Z
2019-03-14T18:03:04.743Z
2019-03-14T18:03:04.743Z
DirectX_Programmer
<p>I am creating Forward-Rendering DX11 engine and I have some troubles with shadow-mapping algorithm as it doesn't work as supposed.</p>

<p><a href="https://i.sstatic.net/N2ZcY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/N2ZcY.png" alt="Shadowmap texture"></a></p>

<p><a href="https://i.sstatic.net/Ehipa.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Ehipa.png" alt="Rendered scene"></a></p>

<p>As you can see - shadow is peter-panning and looks totally not releated. Basically as I have tested, comparision in PixelShader has no effect. Only projected shadowmap texture is returned, <em>if statement</em> doesn't do anything.</p>

<p><strong>MyVertexShader:</strong></p>

<pre><code>PixelInputType ColorVertexShader(VertexInputType input)
{
    PixelInputType output;
    float4 worldPosition;

    input.position.w = 1.0f;
    worldPosition = mul(input.position, worldMatrix);
    output.normal = input.normal;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);

    //Calculate object seen by light
    output.lightViewPosition = mul(input.position, worldMatrix);
    output.lightViewPosition = mul(output.lightViewPosition, g_lightViewMatrix);
    output.lightViewPosition = mul(output.lightViewPosition, g_lightProjectionMatrix);

    //Calculate light-object vector
    output.lightPos = g_lightPosition.xyz - worldPosition.xyz;
    output.lightPos = normalize(output.lightPos);

    return output;
}
</code></pre>

<p><strong>MyPixelShader:</strong></p>

<pre><code>float4 ColorPixelShader(PixelInputType input) : SV_TARGET
{
    float4 color = float4(0.0, 0.0, 0.0, 1.0);
    float depthValue;
    float lightDepthValue;
    float bias = 0.001f;
    float4 textureColor = float4(1.0, 1.0, 1.0, 1.0);
    float4 ambientColor = float4(1.0, 0.0, 1.0, 1.0);
    float2 tex;
    float lightIntensity = 0.0f;

    input.lightViewPosition.xyz /= input.lightViewPosition.w;

    tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
    tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

    return depthValue = shadowMap.Sample(SampleType, tex).r;
    color = float4(depthValue, depthValue, depthValue, 1.0f);

    lightDepthValue = input.lightViewPosition.z;// / input.lightViewPosition.w;
    lightDepthValue = lightDepthValue - bias;
    if(lightDepthValue &lt; depthValue)
    {
        lightIntensity = saturate(dot(input.normal, input.lightPos));

        if(lightIntensity &gt; 0.0f)
        {
            // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
            color += (ambientColor * lightIntensity);

            // Saturate the final light color.
            color = saturate(color);
        }
    }
    return color;
}
</code></pre>

CC BY-SA 4.0
2019-03-13T08:25:52.553Z
How is g_lightViewMatrix & g_lightProjectionMatrix calculated ? I would guess it has a inverse view-projection matrix to convert from camera to world space in there too ?
PaulHK
<shadow><directx11><shadow-mapping>
ShadowMap peter-panning and wrong direction
DirectX_Programmer
# ShadowMap peter-panning and wrong direction

(Asked by: username_0 on 2019-03-08)

I am creating Forward-Rendering DX11 engine and I have some troubles with shadow-mapping algorithm as it doesn't work as supposed.

[![Shadowmap texture](https://i.sstatic.net/N2ZcY.png)](https://i.sstatic.net/N2ZcY.png)

[![Rendered scene](https://i.sstatic.net/Ehipa.png)](https://i.sstatic.net/Ehipa.png)

As you can see - shadow is peter-panning and looks totally not releated. Basically as I have tested, comparision in PixelShader has no effect. Only projected shadowmap texture is returned, *if statement* doesn't do anything.

**MyVertexShader:**

```
PixelInputType ColorVertexShader(VertexInputType input)
{
    PixelInputType output;
    float4 worldPosition;

    input.position.w = 1.0f;
    worldPosition = mul(input.position, worldMatrix);
    output.normal = input.normal;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);

    //Calculate object seen by light
    output.lightViewPosition = mul(input.position, worldMatrix);
    output.lightViewPosition = mul(output.lightViewPosition, g_lightViewMatrix);
    output.lightViewPosition = mul(output.lightViewPosition, g_lightProjectionMatrix);

    //Calculate light-object vector
    output.lightPos = g_lightPosition.xyz - worldPosition.xyz;
    output.lightPos = normalize(output.lightPos);

    return output;
}

```

**MyPixelShader:**

```
float4 ColorPixelShader(PixelInputType input) : SV_TARGET
{
    float4 color = float4(0.0, 0.0, 0.0, 1.0);
    float depthValue;
    float lightDepthValue;
    float bias = 0.001f;
    float4 textureColor = float4(1.0, 1.0, 1.0, 1.0);
    float4 ambientColor = float4(1.0, 0.0, 1.0, 1.0);
    float2 tex;
    float lightIntensity = 0.0f;

    input.lightViewPosition.xyz /= input.lightViewPosition.w;

    tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
    tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

    return depthValue = shadowMap.Sample(SampleType, tex).r;
    color = float4(depthValue, depthValue, depthValue, 1.0f);

    lightDepthValue = input.lightViewPosition.z;// / input.lightViewPosition.w;
    lightDepthValue = lightDepthValue - bias;
    if(lightDepthValue < depthValue)
    {
        lightIntensity = saturate(dot(input.normal, input.lightPos));

        if(lightIntensity > 0.0f)
        {
            // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
            color += (ambientColor * lightIntensity);

            // Saturate the final light color.
            color = saturate(color);
        }
    }
    return color;
}

```

**Tags:** shadow, directx11, shadow-mapping

> **Comments:**
> **username_1**: How is g_lightViewMatrix & g_lightProjectionMatrix calculated ? I would guess it has a inverse view-projection matrix to convert from camera to world space in there too ?  

---

## 1 answers

### Answer by username_0 on 2019-03-13. Score: 1 | Accepted answer

I found out that simply removing minus sign in shader in converting coords to [0, 1] solved direction problem. But scale is still off - here is an example:

[![Wrong scale - peter panning](https://i.sstatic.net/v6lK0.png)](https://i.sstatic.net/v6lK0.png)

```
void LightClass::GenerateViewMatrix()
{
    XMVECTOR eyePos = { m_position.x, m_position.y, m_position.z };
    XMVECTOR focusPos = { m_lookAt.x, m_lookAt.y, m_lookAt.z };
    XMVECTOR upVec = { 0, 1, 0 };

    m_viewMatrix = XMMatrixLookAtLH(eyePos, focusPos, upVec);
}

void LightClass::GenerateProjectionMatrix(float screenDepth, float screenNear)
{
    float fieldOfView = (float)3.14f / 2.0f;
    float screenAspect = 16.0f / 9.0f;

    m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);
}

```

**Edit [Actual solution - ignore previous posts]:**

I followed username_1 solution (thanks, it's second time you've helped me) about checking once again View/Projection matrix. Basically my calculations were wrong. I debugged my convertions from model to lightspace and changed **Vertex Shader** from:

```
output.lightViewPosition = mul(input.position, worldMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightViewMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightProjectionMatrix);

```

To correct:

```
matrix lightViewProj = mul(g_lightProjectionMatrix, g_lightViewMatrix);
output.lightViewPosition = mul(input.position, lightViewProj);

```

That simple changed fixed my results. With simple **Pixel shader** code below I am getting this results:

```
input.lightViewPosition.xyz /= input.lightViewPosition.w;

tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

depthValue = shadowMap.Sample(SampleType, tex).r;
return color = float4(depthValue, depthValue, depthValue, 1.0f);

```

[![Correct shadow-map](https://i.sstatic.net/ylu0o.png)](https://i.sstatic.net/ylu0o.png)
However, even if it seems correct, my suspicion is that I need to compare my shadowmap to light Z-buffer so I modified my Pixel Shader and added little tint:

```
input.lightViewPosition.xyz /= input.lightViewPosition.w;

tex.x = input.lightViewPosition.x / 2.0f + 0.5f;
tex.y = -input.lightViewPosition.y / 2.0f + 0.5f;

depthValue = shadowMap.Sample(SampleType, tex).r;
color = float4(depthValue, depthValue, depthValue, 1.0f);

lightDepthValue = input.lightViewPosition.z - bias;
if(lightDepthValue < depthValue)
{
    lightIntensity = saturate(dot(input.normal, input.lightPos));

    if(lightIntensity > 0.0f)
    {
        // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
        color += (ambientColor * lightIntensity);

        // Saturate the final light color.
        color = saturate(color);
    }
}
return color;

```

I may not be right, but without this checking, you would get errors with more complicated shadows. Because my previous PixelShader code basically just project shadowmap on plane without any actual depth checking. Therefore it would lay shadowmap on everything it can without even checking if that's correct.

[![Correct shadow-map with depth checking](https://i.sstatic.net/X5fzu.png)](https://i.sstatic.net/X5fzu.png)


---

