Original Post
I am having problems with my planar reflection to a water plane in my scene. For the most part I think I have got this correct including the projection of the scene (render texture) to the water plane itself. I have read through this thread as a as well as Yanns article. My issue arises when I modify the projection matrix to do the oblique culling (using the water plane) before the texture render. The depth of the rendered objects is totally screwed. I will show you a few pictures: In the below images I do not modify the projection matrix to do the oblique culling. This works perfectly but, as expected, I get artifacts on the water from certain angles. "Working" scene with no oblique technique "Working" scene render texture with no oblique culling If I modify the projection matrix my scene turns out like this: Broken scene with oblique technique used Broken scene render texture You can see in the broken scenes render texture that the depth is totally messed up. I don't get visual artifacts other than this problem with the depth of rendered items. Do I have to do something to the depth buffer before rendering the scene to the texture? I have reversed the cull mode before the texture render etc. The code I am using to modify the view matrix with a reflection matrix, make a clip plane in camera space and then modify the projection matrix to use the oblique frustum technique is: After this code I flip the cull mode and render the scene to a texture. After that I set the view and projection matrices back, reflip the culling order and then render the scene as normal to the back buffer. For the water plane I project this rendered texture on to it. The render texture comes out with what I think are depth related problems though. Can anyone help me [smile]? I am using DirectX 9. The matrix class is 4X4 and the vector class is 4D. The water level is (0.0f, -2.0f, 0.0f) and the water plane normal is of course (0.0f, 1.0f, 0.0f) [Edited by - __Daedalus__ on January 1, 2005 5:28:34 PM]
HEMatrix Reflect, View, Proj, ViewReflect, Temp;
HEVector Point, Normal, PP, PN, ClipPlane, q;
Reflect.Identity();
View.Identity();
Proj.Identity();
ViewReflect.Identity();
Temp.Identity();
// Use off-screen render target
HADES->m_pRenderDevice->UseRenderTarget( App->m_RenderTargetID );
// Get the current view and projection matrix
HADES->m_pRenderDevice->GetMatrix( HEMAT_PPROJ0, Proj );
HADES->m_pRenderDevice->GetMatrix( HEMAT_VIEW3D, View );
/// Build and set reflection matrix on the XZ plane
Reflect._22 = -1.0f;
Reflect._42 = 2.0f * -2.0f;
ViewReflect = View * Reflect;
HADES->m_pRenderDevice->SetMatrix( HEMAT_VIEW3D, ViewReflect );
// Modify the projection matrix
Point.Set( 0.0f, -2.0f, 0.0f, 1.0f ); // Point on plane
Normal.Set( 0.0f, 1.0f, 0.0f, 1.0f ); // Water plane normal
// Copy modified view matrix to temporary variable for 3X3 config.
memcpy( &Temp._11, &ViewReflect._11, sizeof(float)*16 );
// Make temporary matrix 3X3 of ViewReflect
Temp._14 = 0.0f;
Temp._24 = 0.0f;
Temp._34 = 0.0f;
Temp._44 = 1.0f;
Temp._41 = 0.0f;
Temp._42 = 0.0f;
Temp._43 = 0.0f;
PP = Point * ViewReflect;
PN = Normal * Temp;
PN.Normalise();
// This is in camera space
ClipPlane.Set( PP.x, PP.y, PP.z, -(PP*PN) );
// 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
q.x = App->sgn(ClipPlane.x) / Proj._11;
q.y = App->sgn(ClipPlane.y) / Proj._22;
q.z = 1.0f;
q.w = (1.0f - Proj._33) / Proj._43;
// Calculate the scaled plane vector
HEVector c = ClipPlane * (1.0f / (ClipPlane * q));
// Replace the third column of the projection matrix
Proj._13 = c.x;
Proj._23 = c.y;
Proj._33 = c.z;
Proj._43 = c.w;
// Set this as the projection matrix
HADES->m_pRenderDevice->SetMatrix( HEMAT_PPROJ0, Proj );
// Store the modified projection matrix
HADES->m_pRenderDevice->GetMatrix( HEMAT_PPROJ0, App->m_ModProj );