Mixing terrain-nodes impossible!
Mixing terrain-nodes impossible!
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
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
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
I didn't try turning on bi/trilinear filtering. Does that help?
Okay, I guess I had ONE suggestion for you
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.
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.
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.
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.
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
to
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.
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);
Code: Select all
SceneManager->registerNodeForRendering(this,ESNRP_SKY_BOX);
Hope it fixes the problem.
EDIT: Nope, didn't fix the problem, I'll keep looking into it.
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
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!
You mean like this?Suliman wrote:I have a pic of it but there is no way to upload here.
-
- Posts: 61
- Joined: Mon Oct 25, 2004 12:11 am
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
to
for 24 bit zbuffer or
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
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;
Code: Select all
if (!StencilBuffer)
present.AutoDepthStencilFormat = D3DFMT_D24X8;
Code: Select all
if (!StencilBuffer)
present.AutoDepthStencilFormat = D3DFMT_D32;
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
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
to
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.
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)
Code: Select all
24, // 24Bit Z-Buffer (Depth Buffer)