Add detection/support for reverse-z projection matrices. Refs #169

This commit is contained in:
baldurk
2016-01-20 19:58:24 +01:00
parent 01bffe6a09
commit ae91bdcde2
4 changed files with 49 additions and 4 deletions
+17 -2
View File
@@ -4118,6 +4118,8 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
Vec4f *pos0 = (Vec4f *)byteData;
bool found = false;
for(UINT64 i=1; numPosComponents == 4 && i < numPrims.NumPrimitivesWritten; i++)
{
//////////////////////////////////////////////////////////////////////////////////
@@ -4140,7 +4142,7 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
Vec4f *pos = (Vec4f *)(byteData + i*stride);
if(fabs(pos->w - pos0->w) > 0.01f)
if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f)
{
Vec2f A(pos0->w, pos0->z);
Vec2f B(pos->w, pos->z);
@@ -4153,10 +4155,21 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
nearp = -c/m;
farp = c/(1-m);
found = true;
break;
}
}
// if we didn't find anything, all z's and w's were identical.
// If the z is positive and w greater for the first element then
// we detect this projection as reversed z with infinite far plane
if(!found && pos0->z > 0.0f && pos0->w > pos0->z)
{
nearp = pos0->z;
farp = FLT_MAX;
}
m_pImmediateContext->Unmap(m_SOStagingBuffer, 0);
m_PostVSData[idx].vsin.topo = topo;
@@ -4698,7 +4711,9 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
{
// the derivation of the projection matrix might not be right (hell, it could be an
// orthographic projection). But it'll be close enough likely.
Matrix4f guessProj = Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect);
Matrix4f guessProj = cfg.position.farPlane != FLT_MAX
? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect)
: Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect);
if(cfg.ortho)
{
+17 -2
View File
@@ -2795,6 +2795,8 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
Vec4f *pos0 = (Vec4f *)byteData;
bool found = false;
for(GLuint i=1; posidx != -1 && i < primsWritten; i++)
{
//////////////////////////////////////////////////////////////////////////////////
@@ -2817,7 +2819,7 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
Vec4f *pos = (Vec4f *)(byteData + i*stride);
if(fabs(pos->w - pos0->w) > 0.01f)
if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f)
{
Vec2f A(pos0->w, pos0->z);
Vec2f B(pos->w, pos->z);
@@ -2829,11 +2831,22 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
nearp = -c/m;
farp = c/(1-m);
found = true;
break;
}
}
// if we didn't find anything, all z's and w's were identical.
// If the z is positive and w greater for the first element then
// we detect this projection as reversed z with infinite far plane
if(!found && pos0->z > 0.0f && pos0->w > pos0->z)
{
nearp = pos0->z;
farp = FLT_MAX;
}
gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer);
// store everything out to the PostVS data cache
@@ -3426,7 +3439,9 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
{
// the derivation of the projection matrix might not be right (hell, it could be an
// orthographic projection). But it'll be close enough likely.
Matrix4f guessProj = Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect);
Matrix4f guessProj = cfg.position.farPlane != FLT_MAX
? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect)
: Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect);
if(cfg.ortho)
{
+14
View File
@@ -391,3 +391,17 @@ Matrix4f Matrix4f::Perspective(const float degfov, const float N, const float F,
return Matrix4f(persp);
}
Matrix4f Matrix4f::ReversePerspective(const float degfov, const float N, const float A)
{
const float radfov = degfov * (3.1415926535f/180.0f);
float S = 1/tanf(radfov * 0.5f);
float persp[16] = { S/A, 0.0f, 0.0f, 0.0f,
0.0f, S, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, N, 0.0f,
};
return Matrix4f(persp);
}
+1
View File
@@ -60,6 +60,7 @@ class Matrix4f
static Matrix4f RotationZYX(const Vec3f &rot);
static Matrix4f Orthographic(const float nearplane, const float farplane);
static Matrix4f Perspective(const float degfov, const float nearplane, const float farplane, const float aspect);
static Matrix4f ReversePerspective(const float degfov, const float nearplane, const float aspect);
inline float operator[](const size_t i) const
{