directx 11全向阴影贴图阴影投影错误

时间:2018-02-11 10:24:18

标签: point directx-11 hlsl light shadow-mapping

我使用c ++ directx 11编写全方位阴影映射。我从书中获取算法:Doron Feinstein的“HLSL Development Cookbook”。但是如果我的屏幕分辨率和所有依赖性与阴影贴图的分辨率不同,则阴影位于错误的位置并进行预测。我怎么解决它?

XMMATRIX* PointLight::GetCubeViewProjection()
{
  XMMATRIX lightProjection, positionMatrix, spotView, toShadow;

  RebuildWorldMatrixPosition();
  XMFLOAT3 worldPosition = this->GetWorldPosition();

  positionMatrix = XMMatrixTranslation(-worldPosition.x, -worldPosition.y, -worldPosition.z);
  lightProjection = XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0f, SHADOW_NEAR_PLANE, m_radius);

  // Cube +X
  spotView = XMMatrixRotationY(XM_PI + XM_PIDIV2);
  toShadow = positionMatrix * spotView * lightProjection;
  m_cubeViewProjection[0] = XMMatrixTranspose(toShadow);

  // Cube -X
  spotView = XMMatrixRotationY(XM_PIDIV2);
  toShadow = positionMatrix * spotView * lightProjection;
  m_cubeViewProjection[1] = XMMatrixTranspose(toShadow);

  // Cube +Y
  spotView = XMMatrixRotationX(XM_PIDIV2);
  toShadow = positionMatrix * spotView * lightProjection;
  m_cubeViewProjection[2] = XMMatrixTranspose(toShadow);

  // Cube -Y
  spotView = XMMatrixRotationX(XM_PI + XM_PIDIV2);
  toShadow = positionMatrix * spotView * lightProjection;
  m_cubeViewProjection[3] = XMMatrixTranspose(toShadow);

  // Cube +Z
  toShadow = positionMatrix * lightProjection;
  m_cubeViewProjection[4] = XMMatrixTranspose(toShadow);

  // Cube -Z
  spotView = XMMatrixRotationY(XM_PI);
  toShadow = positionMatrix * spotView * lightProjection;
  m_cubeViewProjection[5] = XMMatrixTranspose(toShadow);

  return m_cubeViewProjection;
}


cbuffer WorldMatrixBuffer : register( b0 )
{
    matrix worldMatrix;
};

//vertex shadow gen shader
float4 PointShadowGenVS(float4 Pos : POSITION) : SV_Position
{
    Pos.w = 1.0f;
    return mul(Pos, worldMatrix);
}

//geometry shadow gen shader

cbuffer ShadowMapCubeViewProj : register( b0 )
{
    float4x4 cubeViewProj[6] : packoffset(c0);
};

struct GS_OUTPUT
{
    float4 Pos: SV_POSITION;
    uint RTIndex : SV_RenderTargetArrayIndex;
};

[maxvertexcount(18)]
void PointShadowGenGS(triangle float4 InPos[3] : SV_Position, inout TriangleStream<GS_OUTPUT> OutStream)
{
    for (int iFace = 0; iFace < 6; ++iFace)
    {
        GS_OUTPUT output;

        output.RTIndex = iFace;

        for (int v = 0; v < 3; ++v)
        {
            output.Pos = mul(InPos[v], cubeViewProj[iFace]);
            OutStream.Append(output);
        }
        OutStream.RestartStrip();
    }
}

//point light pixel shader

float PointShadowPCF(float3 toPixel)
{
    float3 toPixelAbs = abs(toPixel);
    float z = max(toPixelAbs.x, max(toPixelAbs.y, toPixelAbs.z));
    float depth = (lightPerspectiveValues.x * z + lightPerspectiveValues.y) / z;
    return pointShadowMapTexture.SampleCmpLevelZero(PCFSampler, toPixel, depth).x;
}

float shadowAttenuation = PointShadowPCF(worldPosition - lightPosition);

1 个答案:

答案 0 :(得分:0)

问题出在不正确的视口中。它必须与阴影贴图具有相同的宽度和高度。我创建它不正确。