DirectX + GLM深度重建问题

时间:2017-09-12 18:00:17

标签: directx shader glm-math depth-buffer

我试图将我的引擎移植到DirectX,而我目前在深度重建方面存在问题。它在OpenGL中完美运行(即使我使用了一些昂贵的方法)。除了深度重建之外,每个部分到目前为止都有我使用GLM是因为它是一个很好的数学库,不需要为用户安装任何依赖项或任何东西。

所以基本上我得到了我的GLM矩阵:

struct DefferedUBO {
    glm::mat4 view;
    glm::mat4 invProj;
    glm::vec4 eyePos;
    glm::vec4 resolution;
};

DefferedUBO deffUBOBuffer;
// ...

glm::mat4 projection = glm::perspective(engine.settings.fov, aspectRatio, 0.1f, 100.0f);
// Get My Camera
CTransform *transform = &engine.transformSystem.components[engine.entities[entityID].components[COMPONENT_TRANSFORM]];
// Get the View Matrix
glm::mat4 view = glm::lookAt(
    transform->GetPosition(),
    transform->GetPosition() + transform->GetForward(),
    transform->GetUp()
);

deffUBOBuffer.invProj = glm::inverse(projection);
deffUBOBuffer.view = glm::inverse(view);

if (engine.settings.graphicsLanguage == GRAPHICS_DIRECTX) {
    deffUBOBuffer.invProj = glm::transpose(deffUBOBuffer.invProj);
    deffUBOBuffer.view = glm::transpose(deffUBOBuffer.view);
}

// Abstracted so I can use OGL, DX, VK, or even Metal when I get around to it.
deffUBO->UpdateUniformBuffer(&deffUBOBuffer);
deffUBO->Bind());

然后在HLSL中,我只使用以下内容:

cbuffer MatrixInfoType {
    matrix invView;
    matrix invProj;
    float4 eyePos;
    float4 resolution;
};

float4 ViewPosFromDepth(float depth, float2 TexCoord) {
    float z = depth; // * 2.0 - 1.0;

    float4 clipSpacePosition = float4(TexCoord * 2.0 - 1.0, z, 1.0);
    float4 viewSpacePosition = mul(invProj, clipSpacePosition);
    viewSpacePosition /= viewSpacePosition.w;

    return viewSpacePosition;
}

float3 WorldPosFromViewPos(float4 view) {
    float4 worldSpacePosition = mul(invView, view);

    return worldSpacePosition.xyz;
}

float3 WorldPosFromDepth(float depth, float2 TexCoord) {
    return WorldPosFromViewPos(ViewPosFromDepth(depth, TexCoord));
}

// ...

// Sample the hardware depth buffer.
float  depth    = shaderTexture[3].Sample(SampleType[0], input.texCoord).r;
float3 position = WorldPosFromDepth(depth, input.texCoord).rgb;

结果如下:
image1 这看起来就像随机颜色乘以深度。

具有讽刺意味的是,当我删除移调时,我会更接近事实,但并不完全:
image2 你在看Crytek Sponza。如您所见,绿色区域随着相机底部移动和旋转。我根本不知道为什么。

正确的版本,以及Albedo,Specular和Normals。
image3

1 个答案:

答案 0 :(得分:1)

我在gamedev.net修复了我的问题。存在矩阵重要性问题以及深度处理问题。

https://www.gamedev.net/forums/topic/692095-d3d-glm-depth-reconstruction-issues