2017-09-12 4 views
1

J'essaie de porter mon moteur sur DirectX et j'ai actuellement des problèmes de reconstruction de profondeur. Cela fonctionne parfaitement dans OpenGL (même si j'utilise une méthode un peu coûteuse). Chaque partie à part la reconstruction de profondeur fonctionne jusqu'à présent. J'utilise GLM parce que c'est une bonne bibliothèque mathématique qui n'a pas besoin d'installer de dépendances ou quoi que ce soit pour l'utilisateur.Problèmes de reconstruction de profondeur DirectX + GLM

Donc, fondamentalement, je reçois mes matrices de 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()); 

Puis en HLSL, j'utilise simplement ce qui suit:

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; 

Voici le résultat:
image1 Cela ressemble des couleurs aléatoires multiplié avec la profondeur.

Ironie du sort lorsque je retire interversion, je reçois quelque chose de plus proche de la vérité, mais pas tout à fait:
image2 Vous êtes à la recherche de Crytek Sponza. Comme vous pouvez le voir, la zone verte se déplace et tourne avec le bas de la caméra. Je n'ai aucune idée du pourquoi.

La version correcte, avec Albedo, spéculaire et normales.
image3

+0

un coup d'oeil [ici] (https://stackoverflow.com/a/11804446/8597205) –

Répondre