(seem to have lost white space on the post...........) All objects submitted to the renderManager behave as they should. But ,my water is a plane which I draw with a water.fx like this:// Render the scene.sceneState.BeginFrameRendering(view, projection, gameTime, environment); editor.BeginFrameRendering(sceneState);renderManager.BeginFrameRendering(sceneState);renderManager.Render();renderManager.EndFrameRendering();editor.EndFrameRendering();sceneState.EndFrameRendering();water.DrawWater(gameTime, new Vector3(0, 0, 1));base.Draw(gameTime);In Update, I pass :water.view = view;water.projection = projection;water.viewPosition = viewPosition;water.viewRotation = viewRotation;before the Draw.These are derived from the ProcessInput method and are needed in the shader. ReflectionView is calculated in the call to Draw ReflectionVector3 reflCameraPosition = viewPosition;reflCameraPosition.Y = -viewPosition.Y;Matrix rotation = Matrix.CreateFromYawPitchRoll(viewRotation.X, viewRotation.Y, viewRotation.Z);Vector3 target = viewPosition + Vector3.Transform(Vector3.Backward, rotation);Vector3 reflTargetPos = target;reflTargetPos.Y = -target.Y ;rotation = Matrix.CreateFromYawPitchRoll(viewRotation.X, viewRotation.Y, viewRotation.Z);Vector3 cameraRight = Vector3.Transform(new Vector3(1, 0, 0), rotation);Vector3 invUpVector = Vector3.Cross(cameraRight, reflTargetPos – reflCameraPosition);reflection = Matrix.CreateLookAt(reflCameraPosition, reflTargetPos, invUpVector);Here's the shader://------- Constants -------- float4x4 xView;float4x4 xReflectionView;float4x4 xProjection;float4x4 xWorld;float3 xLightDirection;float xWaveLength;float xWaveHeight;float3 xCamPos; float xTime; float xWindForce; float3 xWindDirection; //------- Texture Samplers -------- Texture xReflectionMap; sampler ReflectionSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;}; Texture xRefractionMap; sampler RefractionSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;}; Texture xWaterBumpMap; sampler WaterBumpMapSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;}; //------- Technique: Water -------- struct WVertexToPixel { float4 Position : POSITION; float4 ReflectionMapSamplingPos : TEXCOORD1; float2 BumpMapSamplingPos : TEXCOORD2; float4 RefractionMapSamplingPos : TEXCOORD3; float4 Position3D : TEXCOORD4; }; struct WPixelToFrame { float4 Color : COLOR0; }; WVertexToPixel WaterVS(float4 inPos : POSITION, float2 inTex: TEXCOORD) { WVertexToPixel Output = (WVertexToPixel)0; float4x4 preViewProjection = mul (xView, xProjection); float4x4 preWorldViewProjection = mul (xWorld, preViewProjection); float4x4 preReflectionViewProjection = mul (xReflectionView, xProjection); float4x4 preWorldReflectionViewProjection = mul (xWorld, preReflectionViewProjection); Output.Position = mul(inPos, preWorldViewProjection); Output.ReflectionMapSamplingPos = mul(inPos, preWorldReflectionViewProjection); Output.RefractionMapSamplingPos = mul(inPos, preWorldViewProjection); Output.Position3D = mul(inPos, xWorld); float3 windDir = normalize(xWindDirection); float3 perpDir = cross(xWindDirection, float3(0,1,0)); float ydot = dot(inTex, xWindDirection.xz); float xdot = dot(inTex, perpDir.xz); float2 moveVector = float2(xdot, ydot); moveVector.y += xTime*xWindForce; Output.BumpMapSamplingPos = moveVector/xWaveLength; return Output; } WPixelToFrame WaterPS(WVertexToPixel PSIn) { WPixelToFrame Output = (WPixelToFrame)0; float4 bumpColor = tex2D(WaterBumpMapSampler, PSIn.BumpMapSamplingPos); float2 perturbation = xWaveHeight*(bumpColor.rg - 0.5f)*2.0f; float2 ProjectedTexCoords; ProjectedTexCoords.x = PSIn.ReflectionMapSamplingPos.x/PSIn.ReflectionMapSamplingPos.w/2.0f + 0.5f; ProjectedTexCoords.y = -PSIn.ReflectionMapSamplingPos.y/PSIn.ReflectionMapSamplingPos.w/2.0f + 0.5f; float2 perturbatedTexCoords = ProjectedTexCoords + perturbation; float4 reflectiveColor = tex2D(ReflectionSampler, perturbatedTexCoords); float2 ProjectedRefrTexCoords; ProjectedRefrTexCoords.x = PSIn.RefractionMapSamplingPos.x/PSIn.RefractionMapSamplingPos.w/2.0f + 0.5f; ProjectedRefrTexCoords.y = -PSIn.RefractionMapSamplingPos.y/PSIn.RefractionMapSamplingPos.w/2.0f + 0.5f; float2 perturbatedRefrTexCoords = ProjectedRefrTexCoords + perturbation; float4 refractiveColor = tex2D(RefractionSampler, perturbatedRefrTexCoords); float3 eyeVector = normalize(xCamPos - PSIn.Position3D); float3 normalVector = (bumpColor.rbg-0.5f)*2.0f; float fresnelTerm = dot(eyeVector, normalVector); float4 combinedColor = lerp(reflectiveColor, refractiveColor, fresnelTerm); float4 dullColor = float4(0.3f, 0.3f, 0.5f, 1.0f); Output.Color = lerp(combinedColor, dullColor, 0.2f); float3 reflectionVector = -reflect(xLightDirection, normalVector); float specular = dot(normalize(reflectionVector), normalize(eyeVector)); specular = pow(specular, 256); Output.Color.rgb += specular; return Output; } technique Water { pass Pass0 { VertexShader = compile vs_1_1 WaterVS(); PixelShader = compile ps_2_0 WaterPS(); } } and the call to DrawWater publicvoid DrawWater(GameTime gameTime, Vector3 sundir){ device.RenderState.AlphaBlendEnable = false; device.RenderState.DepthBufferEnable = false; device.SamplerStates[0].AddressU = TextureAddressMode.Clamp; device.SamplerStates[0].AddressV = TextureAddressMode.Clamp; DrawReflectionMap(gameTime); DrawRefractionMap(gameTime); float time = (float)gameTime.TotalGameTime.TotalSeconds; effect.CurrentTechnique = effect.Techniques["Water"]; Matrix worldMatrix = Matrix.Identity ; effect.Parameters["xWorld"].SetValue(world ); effect.Parameters["xView"].SetValue(view); effect.Parameters["xReflectionView"].SetValue(reflection); effect.Parameters["xProjection"].SetValue(projection); effect.Parameters["xReflectionMap"].SetValue(reflectionMap); effect.Parameters["xRefractionMap"].SetValue(refractionMap); effect.Parameters["xWaterBumpMap"].SetValue(waterBumpMap); effect.Parameters["xWaveLength"].SetValue(0.02f); effect.Parameters["xWaveHeight"].SetValue(0.1f); effect.Parameters["xCamPos"].SetValue(viewPosition); effect.Parameters["xTime"].SetValue(time); effect.Parameters["xWindForce"].SetValue(0.004f); effect.Parameters["xWindDirection"].SetValue(windDirection); effect.Parameters["xLightDirection"].SetValue(sundir); effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.Vertices[0].SetSource(waterVertexBuffer, 0, VertexPositionTexture.SizeInBytes); device.VertexDeclaration = waterVertexDeclaration; int noVertices = waterVertexBuffer.SizeInBytes / VertexPositionTexture.SizeInBytes; device.DrawPrimitives(PrimitiveType.TriangleList, 0, noVertices / 3); pass.End(); } effect.End(); } The problem is, the water plane does not stay fixed in the scene. It seems to be following the "camera". This is driving me nuts (hours and hours) It's the only item I have imported from other projects that doesn't work, and the water is soo0 beautiful in them. Any suggestions ?
Hi ggb,
Is this a small project? Is there a chance you could just send me a test case and I'll test it out here?
Thanks!
Follow me on Twitter – development and personal tweetsAwesome XNA Videos – Lighting, Rendering, and game videos
If the zip is under 6 - 7 megs you can send it to my email address.
I don't need all of the content, only the content related to the water and maybe a single object, so I can see the camera moving. You can probably include the default kit content instead of your own, that zips down to like ~1.5M - please make sure the project builds and runs after the modification though.
I'm not seeing the water follow the camera, but I am seeing it pass through other objects - is that what's happening for you too?
There are two things causing this - both related to the depth buffer. The first is in Water.Draw, line 180 disables the depth test, which needs to stay on in order to clip against other objects. The second is in the Water.Draw<Reflect/Refract> methods - these are clearing the depth buffer, which is needed for the reflect/refract passes, but also affects the final water draw.
You could use a separate depth buffer for the reflect/refract passes, but here's something to consider:
On Xbox the contents of a render target (depth and back buffer included) are lost when switching to a different target (please note: it's the contents of the render target that are lost, the automatically resolved texture associated with the target still contains the image you just finished drawing - this can get a little confusing), so in the instance of the reflect/refract render target switch all of the previous back buffer data (the entire scene) is lost.
The best way to avoid this is to render the reflect/refract render targets first, so instead of calling those methods in Water.Draw you can call them before SceneState.BeginFrameRendering. This also saves depth buffer switching and video memory. But again only necessary for Xbox.
I'm not sure on the reflection view matrix, in the past we always used a cubemap to approximated scene reflections.
Does the game crash or the Editor? Can you post the stack trace and exception string (if the editor is crashing it dumps out a crash log in its directory)?
Did you try it using the test project you sent over last week? That seems to be working, though there is a problem in that project where the water render targets are not resized after the editor changes the xna window size (which breaks the render targets' use of the main z-buffer).
I can work on the test project fine in the editor. Only my
new project crashes unless I skip drawing the water. BTW I now have very nice
reflections too, after tweaking a lot of parameters, but my water plane drawing is still
affected by any up/down rotation of the camera. Wierd that it doesn't
happen in my non-Sunburn version of the same project. I don't understand why a small change in my near
plane distance parameter in the projection matrix affects the water height so much. If I take the camera above
the water there is a critical distance at which the water disappears (clips away). Sounds alittle like the problem in post Jan 30 2008 2:43 AM -- could it be the shadowing technique that clips away parts of my water which give the appearance of moving when I look at it from different distances? ( not an expert in rendertargets, buffers and clipping)
Also there must be something different about the camera that is needed by the editor that
affects my otherwise normal water drawing methods.
Is partial transparency in the plans ? My windows are either opaque or blown out.
GGB
Did I mention how much fun I am having with your product. I would strongly recommend it to anyone wanting lighting etc. There needs to be more about it in the Creator's Club and the People at Digital Tutors and XSI for XNA need to be able to point people to you for lighting issues which are less than ideal in XNA itself. I have spent months trying to master deferred rendering and shadow passes. Not any more !!
With the support I have been afforded it well worth the 200.00 bucks
ggblake:Did I mention how much fun I am having with your product. I would strongly recommend it to anyone wanting lighting etc. There needs to be more about it in the Creator's Club and the People at Digital Tutors and XSI for XNA need to be able to point people to you for lighting issues which are less than ideal in XNA itself. I have spent months trying to master deferred rendering and shadow passes. Not any more !! With the support I have been afforded it well worth the 200.00 bucks
Excellent news! You should definitely recommend the product others in the xna world, we would appreciate that a lot!
The water clipping away is likely related to the projection's far distance - in the starter kits the scene far distance (max visible distance) is supplied through the SceneEnvironment object, you can change its visible distance property to change the clipping distance of scene objects.
Is the water following the camera similar to the last time? It could be that the reflect/refract are being rendered after the BeginFrameRendering calls or there are additional device.Clear calls added in the code (again after the BeginFrameRendering calls).
A good way to tell whats going on is to comment out the reflect/refract calls and render the water as a regular flat object - does it look ok or is it floating again? If the same z-buffer issue is still there step through all of the code after RenderManager.Render looking for any Clear calls or places where the DepthBuffer is disabled. If the problem went away then add the reflect/refract back in and step through those looking for the same things.
My water still disappears at critical distances/viewing angles. The reflections are beautiful but also rotate too much on lookup and lookdown. Could the camera target value be the issue?
Any thoughts on why the editor crashes if I draw the water in my project. It does not crash with the test project I sent you. The powerhous example aslo misbehave when you launch the editor. The srceen simply stays black.
The Trigger system in the powerhouse example uses a wtf file. Is this file generated long hand or
is there a parser/editor somewhere ?