|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| [MDX] Water Reflection Clipping Problem |
|
![]() jameswren Member since: 10/15/2003 From: Oxford, United Kingdom |
||||
|
|
||||
I can't seem to get user clip planes working correctly to clip geometry below the water surface. Here is an extract of my code, I use HLSL for rendering:device.ClipPlanes[0].Enabled = true; Plane planeWater = new Plane(0f, 1f, 0f, 0f); device.ClipPlanes[0].Plane = planeWater; device.RenderState.Clipping = true; terrain.Render(Matrix.Scaling(1.0f, -1.0f, 1.0f)) //render terrain upside-down The clip plane seems dependent on the camera view matrix maybe, as the clip plane seems to move with the camera. Thanks for any help, James |
||||
|
||||
![]() remigius Member since: 5/4/2005 From: Oirsbeek, Netherlands |
||||
|
|
||||
| Well, I'm not entirely sure what the problem might be exactly, as it's been a while since I worked on water reflection. But maybe the sample on this page can help you out. It does use the FFP to render the reflection, but the clipping code should be the same for any HLSL approach. Hope this helps, Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ Blogthing ] - Do yourself a favor and bookmark this excellent free online D3D/shader book! |
||||
|
||||
![]() Promit Moderator - Graphics Programming and Theory Member since: 7/29/2001 From: Baltimore, MD, United States |
||||
|
|
||||
| Clip planes are always in eye space, keep that in mind. If you're using a world space clip plane, you need to transform it accordingly. |
||||
|
||||
![]() remigius Member since: 5/4/2005 From: Oirsbeek, Netherlands |
||||
|
|
||||
| Are you sure that holds true for Managed DirectX, Promit? I've done some searching on MSDN, but I can't find anything useful on it. My little sample project however suggests that user clipping planes in MDX can be defined in world-space and will get converted properly to eye space, using the View and Projection matrix set on the device. Here's my code to create the clipping plane, maybe the FromPointNormal method makes the difference? [source=c#] Plane clipPlane = Plane.FromPointNormal( Vector3.Empty, new Vector3(0, 1, 0)); device.ClipPlanes[0].Plane = clipPlane; device.ClipPlanes[0].Enabled = true; device.RenderState.Clipping = true; Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ Blogthing ] - Do yourself a favor and bookmark this excellent free online D3D/shader book! |
||||
|
||||
![]() jamesw Member since: 7/4/2005 From: Raleigh, NC, United States |
||||
|
|
||||
| I had a similar problem recently and I was able to fix it. See this thread for details. |
||||
|
||||
![]() jameswren Member since: 10/15/2003 From: Oxford, United Kingdom |
||||
|
|
||||
| Remigius - Your example is where I got my clip plane code from at first, but it seems clips planes are different in hlsl. jamesw - thanks for the link..I have now added code to transform the plane by the camera view and projection matrices, but it sill doesn't work correctly. Infact the blue band in the 2nd image never shows reflection, and sky is never reflected (unless I reverse the clip plane to point y=-1). ![]() [source lang=c#] rtsWater.BeginScene(rSurfaceWater); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Transparent, 1.0f, 0); device.RenderState.CullMode = Cull.Clockwise; device.ClipPlanes[0].Enabled = true; Plane planeWater = Plane.FromPointNormal(new Vector3(0,0,0), new Vector3(0, 1, 0)); device.ClipPlanes[0].Plane = planeWater; device.RenderState.Clipping = true; Vector3 pos = camera.GetPosition(); pos.Y = 0f; skybox.Render(Matrix.Translation(pos) * Matrix.Scaling(1.0f, -1.0f, 1.0f)); //render skybox using FFP planeWater.Transform(camera.GetViewingFrustum()); //transform plane for hlsl device.ClipPlanes[0].Plane = planeWater; terrain.Render(Matrix.Scaling(1.0f, -1.0f, 1.0f) * camera.GetViewingFrustum()); //render terrain using hlsl device.RenderState.Clipping = false; device.ClipPlanes[0].Enabled = false; device.RenderState.CullMode = Cull.CounterClockwise; rtsWater.EndScene(Filter.None); |
||||
|
||||
![]() remigius Member since: 5/4/2005 From: Oirsbeek, Netherlands |
||||
|
|
||||
| Hmmm... To test this, I've converted my sample project to use a simple shader and spent the last 2 hours trying to get it to work, but the transform on the plane just doesn't seem to work out... Download the sample project, with this rendering code: [source lang=c#] device.RenderState.CullMode = Cull.None; effect.SetValue("ViewProjection", camera.ViewMatrix * camera.ProjectionMatrix ); Plane clipPlane = Plane.FromPointNormal( Vector3.Empty, new Vector3(0, 1, 0)); clipPlane.Transform( camera.ViewMatrix * camera.ProjectionMatrix ); device.ClipPlanes[0].Plane = clipPlane; device.ClipPlanes[0].Enabled = true; device.RenderState.Clipping = true; int numPasses = effect.Begin( FX.None ); for (int i = 0; i < numPasses; i++) { effect.BeginPass(i); mesh.DrawSubset(0); effect.EndPass(); } effect.End(); This code does seem to transform the clipping plane, but it doesn't move along with the camera... In fact it seems to be moving (or rather rotating) to the exact opposite direction of the camera. Messing around with the view matrix (inverting, remapping) doesn't work and should be redundant anyway, right? Can anyone tell me what I'm doing wrong? Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ Blogthing ] - Do yourself a favor and bookmark this excellent free online D3D/shader book! |
||||
|
||||
![]() sirob XNA/DirectX MVP Member since: 11/2/2002 From: Haifa, Israel. |
||||
|
|
||||
| When transforming the clip planes, are you using the normal world matrix or the reflected matrix (I hope I'm not completely off here :))? |
||||
|
||||
![]() remigius Member since: 5/4/2005 From: Oirsbeek, Netherlands |
||||
|
|
||||
If you're referring to my project, you're a bit off I made this project to test the clip plane transform with a simple teapot, so I'm not doing any reflection rendering. From what I can tell, my code is doing the same as the OP's and I'm not getting the right result at all... So I guess if you can fix my code, that should solve the OP's problem too.Thanks in advance :) Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ Blogthing ] - Do yourself a favor and bookmark this excellent free online D3D/shader book! |
||||
|
||||
![]() jamesw Member since: 7/4/2005 From: Raleigh, NC, United States |
||||
|
|
||||
Here is the code that I am using which is working, maybe it will help. //normalize the plane which is required for the transforms D3DXPLANE tempPlane = worldSpacePlane; D3DXPLANE viewSpacePlane; D3DXPlaneNormalize(&tempPlane, &tempPlane); //transform the plane into view space D3DXMATRIX tempMatrix = dxAppSettings.matView; D3DXMatrixInverse(&tempMatrix, NULL, &tempMatrix); D3DXMatrixTranspose(&tempMatrix, &tempMatrix); D3DXPlaneTransform(&viewSpacePlane, &tempPlane, &tempMatrix); //transform the plane into clip space, or projection space tempMatrix = dxAppSettings.matProj; D3DXMatrixInverse(&tempMatrix, NULL, &tempMatrix); D3DXMatrixTranspose(&tempMatrix, &tempMatrix); D3DXPlaneTransform(&clipSpacePlane, &viewSpacePlane, &tempMatrix); Before I got this working i set up a slider that controlled the d value of the clip plane. Adjusting the slider helped me to figure out exactly what was going on in realtime. |
||||
|
||||
![]() sirob XNA/DirectX MVP Member since: 11/2/2002 From: Haifa, Israel. |
||||
|
|
||||
Right, so following jamesw's latest post, this line works in remigius's code:
clipPlane.Transform(Matrix.TransposeMatrix(Matrix.Invert(camera.ViewMatrix)) *
Matrix.TransposeMatrix(Matrix.Invert(camera.ProjectionMatrix)));
I'm not too sure what the logic behind it is :). |
||||
|
||||
![]() remigius Member since: 5/4/2005 From: Oirsbeek, Netherlands |
||||
|
|
||||
Hehe, I don't get it one bit at all, but it works like a charm ![]() [source lang=c#] Plane clipPlane = Plane.FromPointNormal( Vector3.Empty, new Vector3(0, 1, 0)); clipPlane.Normalize(); Matrix tempMatrix = camera.ViewMatrix; tempMatrix.Invert(); tempMatrix.Transpose( tempMatrix ); clipPlane.Transform( tempMatrix ); tempMatrix = camera.ProjectionMatrix; tempMatrix.Invert(); tempMatrix.Transpose( tempMatrix ); clipPlane.Transform( tempMatrix ); device.ClipPlanes[0].Plane = clipPlane; device.ClipPlanes[0].Enabled = true; device.RenderState.Clipping = true; Thanks for helping both of us out! Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ Blogthing ] - Do yourself a favor and bookmark this excellent free online D3D/shader book! |
||||
|
||||
![]() jamesw Member since: 7/4/2005 From: Raleigh, NC, United States |
||||
|
|
||||
Quote: Sure thing! In the C++ docs for D3DXPlaneTransform() it says the plane has to be normalized and the matrices have to be inverted and transposed before sending them to the function. Gotta go to class. |
||||
|
||||
![]() jameswren Member since: 10/15/2003 From: Oxford, United Kingdom |
||||
|
|
||||
| Thanks for your help guys, I managed to sort it too. Unfortunately a new problem seems apparent with the displacement of texture coords. I decided to start a new thread though: link to thread |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|