If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.
![]() |
|
|
#1 |
|
Junior Member
Join Date: Mar 2007
Posts: 68
|
Hi,
I am trying to modify my projection matrix in order to perform near-plane clipping (http://www.terathon.com/code/oblique.html). However, in one of my project I use the reversed depth buffer trick (similar to what Humus explains here : http://www.humus.name/index.php?page...ID=255&start=0). Now, basically, without any modification, the trick doesn't work. So, I have tried to modify to technique, mainly, I tried to modify the clip-space corner calculation, and replaced (I am using the D3D variant): Code:
v = (sgn(vPlaneEq.x), sgn(vPlaneEq.y), 1.0, 1.0); Code:
v = (sgn(vPlaneEq.x), sgn(vPlaneEq.y), 0.0, 1.0); Has anybody already tried to mix these both techniques ? I can't really figure out what's wrong... |
|
|
|
|
|
#2 |
|
Junior Member
Join Date: Mar 2007
Posts: 68
|
deleted
Last edited by gjaegy; 20-Jun-2012 at 14:35. |
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Mar 2007
Posts: 68
|
Hmm, I think I have it.
Still have to test, but at least it is looking good visually. Need to check the depth distribution though. Code:
void ObliqueFrustumCulling( imPlaneTemplate<T>& _oClipPlane, imBool _bReversed )
{
imSVector4DTemplate<T> vPlaneEq;
_oClipPlane.GetEquation(vPlaneEq);
// Calculate the clip-space corner point opposite the clipping plane
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
// transform it into camera space by multiplying it
// by the inverse of the projection matrix
imSVector4DTemplate<T> q;
q.x = (sgn(vPlaneEq.x) - m_Values[2][0]) / m_Values[0][0];
q.y = (sgn(vPlaneEq.y) - m_Values[2][1]) / m_Values[1][1];
q.z = 1.0f;
q.w = (1.0f - m_Values[2][2]) / m_Values[3][2];
// Calculate the scaled plane vector
imSVector4DTemplate<T> c = vPlaneEq * (1.0f / imSVector4DTemplate<T>::DotProduct(vPlaneEq, q));
// HERE ARE THE CHANGES
if (_bReversedZBuffer)
{
m_Values[0][2] = -c.x;
m_Values[1][2] = -c.y;
m_Values[2][2] = -c.z;
m_Values[3][2] = c.w;
}
else
{
m_Values[0][2] = c.x;
m_Values[1][2] = c.y;
m_Values[2][2] = c.z;
m_Values[3][2] = c.w;
}
};
|
|
|
|
|
|
#4 |
|
Junior Member
Join Date: Mar 2007
Posts: 68
|
Humus suggested me a much simpler, and hence much better, solution. Thanks a lot man
Basically, he suggested to apply the oblique near-plane clipping on the regular projection matrix (i.e. without any depth flip). Depth flipping is applied after that, by multiplying the projection matrix by a simple Z flip matrix (z = w - z as I am using Direct3D). Code:
imSMatrix4D matProjReversedZ, matFlipZ; matFlipZ.SetIdentity(); matFlipZ.m_33 = -1.0f; matFlipZ.m_43 = 1.0f; imSMatrix4D::Multiply(*m_pMatrixProjection, matFlipZ, *m_pMatrixProjectionForShader); And my whole pipeline is much simpler now, as I am not tracking both projection and reversed depth projection matrices anymore; I am applying the depth flip to the projection matrix just before feeding the shader. Much easier than building the projection matrix by swapping zfar/znear, which causes many side effects at the engine level, and add confusion to the developer as soon as he has to use the projection matrix. This was the kind of day where you realize you are somewhat stupid |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|