Planar Reflections issue

Started by
9 comments, last by yonisi 5 years, 10 months ago

Hi,

I have a terrain engine where the terrain and water are on different grids. So I'm trying to render planar reflections of the terrain into the water grid. After reading some web pages and docs and also trying to learn from the RasterTek reflections demo and the small water bodies demo as well. What I do is as follows:

1. Create a Reflection view matrix  - Technically I ONLY flip the camera position in the Y direction (Positive Y is up) and add to it 2 * waterLevel. Then I update the View matrix and I save that matrix for later. The code:


void Camera::UpdateReflectionViewMatrix( float waterLevel )
{
    mBackupPosition = mPosition;
    mBackupLook = mLook;
    mPosition.y = -mPosition.y + 2.0f * waterLevel;
    //mLook.y = -mLook.y + 2.0f * waterLevel;
    UpdateViewMatrix();
    mReflectionView = View();
}

2. I render the Terrain geometry to a 512x512 sized Render target by using the Reflection view matrix and an opposite culling (My Terrain is using front culling by nature so I'm using back culling for the Reflction render pass). Let me say that I checked with the Graphics debugger and the Reflection Render target looks "OK" at this stage (Picture attached). I don't know if the fact that the terrain is shown only at the top are of the texture is expected or not, but it seems OK.

LRy2pKU.png

3. Render the Reflection texture into the water using projective texturing - I hope this step is OK code wise. Basically I'm sending to the shader the WorldReflectionViewProj matrix that was created at step 1 in order to use it for the projective texture coordinates, I then convert the position in the DS (Water and terrain are drawn with Tessellation) to the projective tex coords using that WorldReflectionViewProj matrix, then I sample the reflection texture after setting up the coordinates in the PS. Here is the code:


//Send the ReflectionWorldViewProj matrix to the shader:
XMStoreFloat4x4(&mPerFrameCB.Data.ReflectionWorldViewProj, XMMatrixTranspose( ( mWorld * pCam->GetReflectedView() ) * mProj ));

//Setting up the Projective tex coords in the DS:
Output.projTexPosition = mul(float4(worldPos.xyz, 1), g_ReflectionWorldViewProj);

//Setting up the coords in the PS and sampling the reflection texture:
float2 projTexCoords;
projTexCoords.x = input.projTexPosition.x / input.projTexPosition.w / 2.0 + 0.5;
projTexCoords.y = -input.projTexPosition.y / input.projTexPosition.w / 2.0 + 0.5;
projTexCoords += normal.xz * 0.025;
float4 reflectionColor = gReflectionMap.SampleLevel(SamplerClampLinear, projTexCoords, 0);
texColor += reflectionColor * 0.25;

I'll add that when compiling the PS I'm getting a warning on those dividing by input.projTexPosition.w for a possible float division by 0, I tried to add some offset or some minimum to the dividing term but that still not solved my issue.

Here is the problem itself. At relatively flat view angles I'm seeing correct reflections (Or at least so it seems), but as I pitch the camera down, I'm seeing those artifacts which I have no idea where are coming from. I'm culling the terrain in the reflection render pass when it's lower than water height (I have heightmaps for that).

 

Any help will be appreciated because I don't know what is wrong or where else to look.

Advertisement

Seems like it is a bad sampling out of the texture range. Because if I change the sampling to WRAP instead of CLAMP sampler, I'm getting different kind of artifacts (Wide lines due to WRAP instead of vertical lines from sampling border - I guess its borders). Problems are still though:

1. Why I have sampling out of texture?

2. I tried to set borders to 0 for the CLAMP sampler, but still I get the same artifacts.

OK current status is much better after updating the camera Look.y vector to be always positive and changing the address mode the sampler to BORDER and setting the border to 0, no more such anomalies.

However, something is still somewhat off, I seem to get wrong reflections (i.e terrain doesn't look exactly same above ground and in reflection, like there is some shift somewhere).

 

19 hours ago, yonisi said:

also trying to learn from the RasterTek reflections demo

A link will help us see where, and if, you went wrong.

32 minutes ago, Scouting Ninja said:

A link will help us see where, and if, you went wrong.

Sure! My sources were:

RasterTek Reflection tutorial: http://rastertek.com/dx11tut27.html

RasterTek small water bodies tutorial: http://rastertek.com/tertut16.html

This blog here: http://archive.gamedev.net/archive/reference/articles/article2138.html

And also Habib's lake water tutorial: https://habibs.wordpress.com/lake/

But honestly, I think I did some kind of a mix of all :)

For example, RasterTek tutorial suggest to set the Look.y of the reflection camera to the position.y, but for me that doesn't work.

Current state is:

If I count the problems, seems like I have 4 which I can't understand (Timing references to the above vid):

1. At the start you can see as I pitch down the camera, the reflection of the sky color is removed and the natural color of the water takes place.

2. After that you can see how getting closer and further cause the reflections to "bounce" in a crazy way, I have no idea why this is happening.

3. At ~40 seconds, I show how the reflection of the terrain is somewhat off in terms of textures don't match the above rendered terrain, I think the geometry is OK though, so it could be something with my terrain textures coords, maybe I should flip them for reflections or something...

4. At ~55 seconds I show an edge issue that I have at flat angles when pitching the camera down. Pitching back up where Look.y is slightly above 0, and those edges issues are gone.

Something else which I don't understand. Realizing that my Reflection texture is 512x512 in size, I'm trying to set the Projection matrix to have a 1:1 aspect ration instead of the default ratio (full screen Width:Height), but when I do that I'm getting weirder behavior, like reflections are way off (Of course I'm putting back the correct projection matrix before rendering to back buffer). So I wonder if I even should touch that at all...

Cheers!

 

OK for issue "2" above, I think I know what is the problem, and its actually not related to Graphics, but to the physics of my terrain, My water heightmap follows the terrain pretty close, so if I have a hill on the terrain, the water will climb with such hill, even though the water is covered by the hill anyway, hence I'm getting a bad reading on "Water level" that goes up and down and that explains the bouncing. So reason for issue "2" is known.

1.) This looks like it could be the clamping. Or some kind of Fresnel effect.

2.)This looks like it is losing the position of the camera, so you are struggling to track it. Maybe too much difference between current frame and backed up frame.

3.)Depth here. The reflection is too "deep" it is further away than the actual mesh. By as much as 4%-6%. If you could also flatten the projection matrix a bit it should feel more like a reflection.

4.) I don't see this but maybe some atmospheric filtering could solve this.

 

1 hour ago, yonisi said:

But honestly, I think I did some kind of a mix of all :)

The best thing I think would be to first implement them one by one, then make changes slowly. As is your code is too much of a mix, making it hard to find bugs. It could also be that data shared is snowballing into bugs.

 

It will take me a day or two review this code, before I can be of more help. As I will need to do each tutorial to see what does what.

40 minutes ago, Scouting Ninja said:

1.) This looks like it could be the clamping. Or some kind of Fresnel effect.

2.)This looks like it is losing the position of the camera, so you are struggling to track it. Maybe too much difference between current frame and backed up frame.

3.)Depth here. The reflection is too "deep" it is further away than the actual mesh. By as much as 4%-6%. If you could also flatten the projection matrix a bit it should feel more like a reflection.

4.) I don't see this but maybe some atmospheric filtering could solve this.

 

The best thing I think would be to first implement them one by one, then make changes slowly. As is your code is too much of a mix, making it hard to find bugs. It could also be that data shared is snowballing into bugs.

 

It will take me a day or two review this code, before I can be of more help. As I will need to do each tutorial to see what does what.

OK. It seems actually like 1) and 2) are caused by the same issue:

As I stated in above post, it's a physical issue with my terrain and water grids, as the reflection render pass depends on the water level I sent to it, the reflection will apparently match only if the camera position is at the height of the reflecting surface (This case the water grid). And because my water heightmap is "following the terrain" at areas where the water height is below the terrain height, I have different readings of the "current water level" at different camera position. That effect is for sure the cause of 2) and I suspect also of 1) because when I hover with the camera above the water surface, I don't have such anomalies.

For issue 4) I solved it by adding some offset to the w component of the projected tex position. i.e I did:


projTexCoords.x = input.projTexPosition.x / (input.projTexPosition.w + 0.1) / 2.0 + 0.5;
projTexCoords.y = -input.projTexPosition.y / (input.projTexPosition.w + 0.1) / 2.0 + 0.5;

Added a 0.1 factor. That probably distorting a bit the reflection, but it solves the edges issue I have (Can be clearly seen in the vid at ~55 seconds, the edges are "cut", make sure to watch at 1080 resolution).

For 3) I'm not sure if I understand what do you mean by "too deep" ? it means that the reflection is "sticking out" too much further into the water? If yes then I can see the 0.1 factor I added helps also with that (i.e the reflection is more "attached" to the water edges this way)

Also, how can I flatten the projection matrix? Sorry if a stupid question, but I'm still a "starter" with Graphics so not familiar with all the terms.

Thanx a lot for all the help! But I wouldn't want you to try those samples I linked just for helping me on this! You are a great help already and helped me with most of the issues without such painful effort :)

2 hours ago, yonisi said:

For 3) I'm not sure if I understand what do you mean by "too deep" ? it means that the reflection is "sticking out" too much further into the water? If yes then I can see the 0.1 factor I added helps also with that

Yes, I meant it looked like the reflections where further away than the actual object. Reads like you fixed it, good work.

 

By flatten I mean you would make a matrix facing the camera, then scale it on a local axis to pancake it into a rectangle. This you will then use to flatten/ pancake the projection matrix.

My study on materials proved that we perceive depth into materials as "drawn on the surface" so we perceive the reflection to have less depth than the actual world. The less reflective a object is the less depth it has. It's a small detail but can lead to convincing results.

2 hours ago, yonisi said:

OK. It seems actually like 1) and 2) are caused by the same issue...

Looks like you fixed most of your problems now, that is good to read :)

12 minutes ago, Scouting Ninja said:

By flatten I mean you would make a matrix facing the camera, then scale it on a local axis to pancake it into a rectangle. This you will then use to flatten/ pancake the projection matrix.

My study on materials proved that we perceive depth into materials as "drawn on the surface" so we perceive the reflection to have less depth than the actual world. The less reflective a object is the less depth it has. It's a small detail but can lead to convincing results.

OK OK I think I understand what you mean, I'll try to improve, thanx for all the advices and time! :)

This topic is closed to new replies.

Advertisement