首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ShadowMap peter-panning和错误的方向

ShadowMap peter-panning和错误的方向
EN

Computer Graphics用户
提问于 2019-03-08 18:05:11
回答 1查看 216关注 0票数 1

我正在创建前向渲染的DX11引擎,我在阴影映射算法方面有一些问题,因为它不像想象的那样工作。

如你所见-影子是彼得-潘宁,看起来完全没有释放。基本上,正如我所测试的,PixelShader中的比较没有任何效果。如果语句不做任何操作,则只返回投影阴影贴图纹理。

MyVertexShader:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
}
EN

回答 1

Computer Graphics用户

回答已采纳

发布于 2019-03-13 17:57:25

我发现在将和弦转换为0,1时,只需去掉阴影中的负号就可以解决方向问题。但规模仍在缩小--以下是一个例子:

代码语言:javascript
复制
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);
}

编辑实际解决方案-忽略以前的帖子:

我遵循了PaulHK解决方案(谢谢,这是您第二次帮助我)再次检查视图/投影矩阵。基本上我的计算是错的。我调试了从模型到光空间的转换,并将顶点着色器从:

代码语言:javascript
复制
output.lightViewPosition = mul(input.position, worldMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightViewMatrix);
output.lightViewPosition = mul(output.lightViewPosition, g_lightProjectionMatrix);

纠正:

代码语言:javascript
复制
matrix lightViewProj = mul(g_lightProjectionMatrix, g_lightViewMatrix);
output.lightViewPosition = mul(input.position, lightViewProj);

那个简单的改变了我的结果。下面使用简单的像素着色器代码,我得到了以下结果:

代码语言:javascript
复制
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);

然而,即使这似乎是正确的,我的怀疑是,我需要比较我的阴影地图与轻型Z-缓冲器,所以我修改了我的像素阴影,并增加了一点色彩:

代码语言:javascript
复制
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;

我可能是不对的,但如果没有这个检查,你会得到错误与更复杂的阴影。因为我以前的PixelShader代码基本上只是在平面上投影阴影图,而没有任何实际的深度检查。因此,它会在所有它能做的事情上放置阴影地图,甚至不检查它是否正确。

票数 1
EN
页面原文内容由Computer Graphics提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://computergraphics.stackexchange.com/questions/8664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档