View, projection issues

rated by 0 users
This post has 27 Replies | 2 Followers

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
ggblake Posted: 03-03-2009 5:09 PM

(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 Reflection

Vector3 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 public

void 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 ?

Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

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 tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
I'd really appreciate it. What is the best way to forward the files? And do you need all the content files ? Perhaps a transfer via email ?? GGB
Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

Hi ggb,

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.

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
Placed my plane in the example windmill scene and it behaves the same as in my project-- floats with the camera. Should be in your email . Thank again
Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

Hi ggb,

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.

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
If you get close to an object then move in the Y axis(up) then look down (the palne will be higher on the object. I will let you know if this corrects after I follow your suggestions GGB
Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
That has made a huge difference. Can't thank you enough. I still have some clipping issues which I will mess with and I have to work on the refelctionmaps, but I see a light at the end of the tunnel. THanks GGB
Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
OK.now in the right spot. Been working all weekend on the water. My refraction map is perfect but something is wrong with my reflection and the palne Y-position. The water level rises and falls with camera position so I am guessing the input is changing a view matrix somewhere. Just can't find it. The reflections aren't even close.....likely because we never have the correct camera to water level distance. ??more ideas Also note that the editor crashes if I launch it with water drawing enabled, but runs fine of i skip the water rednering.
Top 10 Contributor
Posts 765
Employee
SunBurn_Studio_Licensee

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)?

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee
The editor crashes. The plane movement has improved a lot by changing the near clip amoimnt to .01f in the view matrix. Still not great tho' 09/03/2009 3:52:18 PM Error mscorlib Failed to connect to an IPC Port: The system cannot find the file specified. Server stack trace: at System.Runtime.Remoting.Channels.Ipc.IpcPort.Connect(String portName, Boolean secure, TokenImpersonationLevel impersonationLevel, Int32 timeout) at System.Runtime.Remoting.Channels.Ipc.ConnectionCache.GetConnection(String portName, Boolean secure, TokenImpersonationLevel level, Int32 timeout) at System.Runtime.Remoting.Channels.Ipc.IpcClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream) at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at SynapseGaming.LightingSystem.Editor.IBaseLightRemote.set_Selected(Boolean value) at G.G.K(TreeNodeCollection , List`1 , Boolean )
Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

Hi ggb,

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).

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee

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

 

Top 10 Contributor
Posts 765
Employee
SunBurn_Studio_Licensee

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.

Top 25 Contributor
Posts 196
SunBurn_Pro_Licensee

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 ?

GGB

Page 1 of 2 (28 items) 1 2 Next > | RSS