Page 1 of 1

Mixing terrain-nodes impossible!

Posted: Tue Apr 19, 2005 8:13 am
by Suliman
Hi I asked this a long time ago but do it again now in a own thread. Plz answer if you know how to solve this...

Water:
I try to make a water-plane (as geomipmap or irrlicht waternode, i've tried both) but the edge between the terrain and the water is really ugly, even if the water is frozen/not animated. the water gets "cut-up" just when going under the terrain, like shards of it is seen. I have a pic of it but there is no way to upload here.

Here is a screenshot of the mix between waterplane and terrain. It looks really... well... ugly.

http://www.gamedev.se/projekt/screenshot.php?id=26



Another strange thing:
When loading a heightmap, it loads mirrored. One dimension (the former y and now z) works while the x-dim is backwards. How should I handle this?See below:

Bitmap:

1 2

3 4


Geomipmap drawn

2 1

4 3



Posted: Tue Apr 19, 2005 8:56 pm
by dopyiii
I've had the same problem with the terrain and water thing. Sorry I don't have any ideas to fix it, though. I've tried changing the scale, culling, different textures, etc. Nothing has worked for me yet.

I didn't try turning on bi/trilinear filtering. Does that help?

Okay, I guess I had ONE suggestion for you :wink:

Posted: Wed Apr 20, 2005 10:40 am
by Guest
Looks like a classic case of z-fighting.

The pixels (fragments) coming from the water are at virtually the same depth (measured from the viewer) and you don't get enough precision in the depth buffer.
It's worse because most video cards use a non-linear formula. There's more precision near the camera than there is far from the camera.

There are a couple of ways to solve it, but most of them are at a lower level (OpenGL or Direct3D).

The one thing I know you can do with Irrlicht is increase the camera's nearvalue, (or reduce the far value).

One more low-level method would be basically rendering your objects in "layers": render distant objects first with different near/farvalues, then reset the depth buffer and render the near objects. There's some extra setup needed (user clip planes) but the results are, apparently, good.

Another is to use w-buffering (although I don't know how you would calculate good w values) - which allows you to use a different distribution.
Operation Flashpoint can be switched to use w-buffering, and that solves precisely the same problem that you're having.

Yet another is using a depth bias for the water, to make it more likely to "win". Although it's quite possible that that just shifts the trouble further inland.

Posted: Wed Apr 20, 2005 11:05 am
by Guest
Allow me to correct myself.

It seems that the depth bias in OpenGL is not applied during rendering but only when reading and writing textures/pixels. I seem to remember reading somewhere that it was possible to use a bias when rendering.
However, it's more useful for decals anyway (roads rendered on top of terrain, for example). Those don't intersect but coincide.

Posted: Thu Apr 21, 2005 1:57 am
by Spintz
I've got to test out what I think the fix, but I think the problem is that the terrain node is rendered, mixed in with all other default scene nodes ( which the water scene node is also rendered as ). When I implemented the GeoMipMapSceneNode in my modified engine, I created a new E_SCENE_NODE_RENDER_PASS for the terrain, so the order would be -

Lights and Camera
SkyBox
Terrain
Solid
Shadow
Transparent

As a quick fix, you can change the line #222 in CTerrainSceneNode.cpp from

Code: Select all

SceneManager->registerNodeForRendering(this);
to

Code: Select all

SceneManager->registerNodeForRendering(this,ESNRP_SKY_BOX);
I believe the correct fix would be to add the terrain to render between the skybox and the solid objects, I guess, if it happens to render before the skybox, you could have the same Z issues between the skybox and the terrain. Make sure you add the sky before the terrain to make sure the sky is drawn before the terrain. Also, you could make sure the terrain node is the first node added to the scene and not change the code in the engine.

Hope it fixes the problem.

EDIT: Nope, didn't fix the problem, I'll keep looking into it.

Posted: Thu Apr 21, 2005 10:47 am
by Guest
I don't think rendering the terrain in a separate pass can ever fix the issue:

Either you clear the depthbuffer, in which case the waterplane will always show completely.

Or you don't clear the depthbuffer, in which case you get z-fighting.

There are three "proper" ways to render deep scenes:
1. clip the waterplane so you don't get intersecting triangles. Any z-fighting will be limited to the waterline.
2. render in layers based on distance to viewer. The downside is that vertex shaders disable user clipping planes, so no hw accelerated skinning at a distance.
3. use a different depth-formula (w-buffering)

You could also try rendering the water in the same pass as the terrain, with a large nearvalue (maybe 10 or so). That way, z-fighting could be reduced for this sort of situation. Of course, that _is_ a very specific fix.

Useful link: http://www.sjbaker.org/steve/omniv/love ... uffer.html

Re: Mixing terrain-nodes impossible!

Posted: Fri Apr 22, 2005 5:42 am
by Midnight
Suliman wrote:I have a pic of it but there is no way to upload here.
You mean like this?

Image

Posted: Sat Apr 23, 2005 1:40 pm
by Suliman
I dont use any skybox.

Is there no fairly easy way to put two nodes close without the flimmer effect? Two terrainNodes cannot do it either (that waterNode is nice-looking but cost enourmous CPU on even a small map).

Posted: Mon Apr 25, 2005 8:40 am
by William Finlayson
I have seen this problem before and the fix was to simply use a 24/32 bit z-buffer rather than a 16 bit one. I don't know how you can force z-buffer size in Irrlicht, you may have to dive into the engine code and tweak it.

Posted: Tue Apr 26, 2005 3:31 am
by Spintz
Thanks a ton William, that's the fix.

For DirectX8 and DirectX9, a 16 bit depth buffer is used, only if you pass true to the createDevice function to enable stencil buffers. If you do not enable stencil buffers, then a D3DFMT_D16 format buffer is used which gives you a 16 bit depth buffer only. Maybe there should be a change to createDevice, so you can specify the depth buffer bits without enabling stencil buffer. You could change

Code: Select all

if (!StencilBuffer)
		present.AutoDepthStencilFormat = D3DFMT_D16;
to

Code: Select all

if (!StencilBuffer)
		present.AutoDepthStencilFormat = D3DFMT_D24X8;
for 24 bit zbuffer or

Code: Select all

if (!StencilBuffer)
		present.AutoDepthStencilFormat = D3DFMT_D32;
for 32 bit zbuffer

to get the water and terrain scene nodes working well together at a distance, or you could just enable the stencil buffer.

I'll look into how to do this for OpenGL and submit a suggested change to be able to configure the depth buffer without having to enable the stencil buffer.

Here's a screenshot with the fix....

http://irrlicht.spintz.com/terrainandwaternode.bmp

The screenshot is with a 24 bit zbuffer, all my video card supports, but seems sufficient

Posted: Tue Apr 26, 2005 6:48 am
by Suliman
Great!

Ill try it first thing when I get home

Posted: Wed Apr 27, 2005 5:32 am
by Suliman
If enambling stencil-buffer, the mix works in windowed mode but not in fullscreen.

The other thing, changing that code, I haven't tried that one, as I do not find that peice of code to be changed... Where is it?

Posted: Wed Apr 27, 2005 1:45 pm
by Spintz
Yes, the fullscreen problem is the reason I changed the engine code, because in fullscreen, stencilbuffers do not work right. With the above changed code, if you enable fullscreen and disable stencil buffers, it looks great ( that screenshot I posted was in fullscreen mode ).

Anyways, that code is in the initDriver function in CVideoDirectX8.cpp and CVideoDirectX9.cpp. For OpenGL, in the initDriver function in CVideoOpenGL.cpp, in the definition of the PIXELFORMATDESCRIPTOR structure, change

Code: Select all

16,		// 16Bit Z-Buffer (Depth Buffer)
to

Code: Select all

24,		// 24Bit Z-Buffer (Depth Buffer)
The engine should allow you to specify the size of the depth buffer you want to use. I'll post some code on that later. And maybe look into why the problem still occurs with stencil buffers enabled in full-screen mode, I think some posts about full-screen and stencil buffers have been posted before.