Page 1 of 1

Render to Skybox

Posted: Tue Nov 08, 2005 8:02 pm
by OemmeS
Hi all

I'm having some problems with my z-buffer precision. I am trying to simulate some REALLY huge distances, i.e. a solar system. For object positioning I use vector3d<f64> and a resolution of 1 meter = 1 unit. Before rendering I move every object in the scene by the camera's position-vector. To be able to view really far, i use some scaling tricks. It works quite well, and my range of view is virtually limitless (I am able to see the Sun from Pluto as a tiny little dot).

But one problem remains: if one object, say the Moon lies behind another object, say Earth, I get some flickering effects, which are the result of precision loss in the z-buffer (at least I believe so).

A solution I have thougt of would be to render objects that are far away into the skybox before rendering anything else. This way I might be able to get rid of the flickering.

Unfortunately I have no idea how to do this

Posted: Tue Nov 08, 2005 8:13 pm
by dhenton9000
so kind of a render-to-texture thing where the texture is part of the skybox?

Posted: Thu Nov 10, 2005 3:20 pm
by Ishtm
that would be great!

flik.... problem: Irr uses 16bit buffer for D3D for example you only have to change a constant from 16 to 32 in implementation of D3D9 driver and that work.

Posted: Thu Nov 10, 2005 10:16 pm
by bitplane
how about, as planets approach the back of the z-buffer they start getting smaller and closer together.
or you could put them in to zones and sort all the far zones by the distance from the camera whenever the camera changes zone, then draw them in that order with the z-buffer off

Posted: Fri Nov 11, 2005 12:40 am
by elander
Using 64 bit floating point values will help but it won't solve the problem because the z-buffer is what limits the usable distance.

For a z-buffer of 16 the quotient (far clip plane/near clip plane) must be aprox. 2000. As z-buffer bits increase this quotent will can be bigger but it isn't a linear proprotion.

The best way to render a very large universe is to render it in steps while adjusting the far and near clip planes in order to keep the quotient into an aceptable interval.

That is for example:

Adjust NCP=10^6km and FCP=10^9km so that FCP/NCP < 2000. Render all scene objects in that range.

Adjust NPC=10^3 and FCP=10^6 then render all scene objects in this range on top of the previous render.

Posted: Fri Nov 11, 2005 1:57 pm
by OemmeS
Thanks for the replies!

I like the approach of rendering the objects in several steps, according to their distance. But I have no idea how to do that. I tried to use the clearZBuffer() function after i've rendered one planet. Unfortunately, the engine crashes as soon as I call this function.

@bitplane: Can I turn the z-Buffer on and off dynamically, i.e. rendering the planets with z-Buffer off and then turn it on to render the other objects (space stations, starships, etc)?

@elander: This approach sounds good, but how can I change the near- and farplanes between the rendering of two planets? I thought the camera has to be rendered before anything else, thus using the same planes for the whole rendering process. Or did I misunderstand it? And if it is possible, I don't know how to "compose" the results to one single frame. Actually, I am quite the beginner in 3D-graphics, but of course eager to learn more ;-)

Posted: Tue Jun 12, 2007 9:58 am
by Xaron
Hi,

does someone have a solution for that issue?

How can I render a single node without the zbuffer and render all the other stuff above it?

Example: I have a sun and a spaceship. EMT_ZBUFFER and EMF_ZWRITE_ENABLE are both false for the sun, because I want to avoid zBuffer fighting and sort all far objects by myself.

How would I render the sun if it's really far away (beyond the far clipping plane)?

I tried it quickly that way:

Code: Select all

sun->getNode()->setVisible(false);
sun->getNode()->render();  // render the sun
smgr->drawAll();                // render all the other stuff
This doesn't work.

Regards - Xaron

Posted: Tue Jun 12, 2007 11:04 am
by Kalda
Try this:

Code: Select all

sun->getNode()->setVisible(true); 
sun->getNode()->render();  // render the sun 
sun->getNode()->setVisible(false); 
smgr->drawAll();                // render all the other stuff 

Posted: Tue Jun 12, 2007 11:27 am
by Xaron
Thanks but that does not work for me.

Regards - Xaron

Posted: Tue Jun 12, 2007 11:58 am
by BlindSide
Make a custom scene node and make it register on the skybox renderpass.

Posted: Tue Jun 12, 2007 12:03 pm
by hybrid
If the sun is beyond the far plane you have to turn off clipping: node->setAutomaticCulling(EAC_OFF);
But using a custom scene node might still be better.

Posted: Tue Jun 12, 2007 12:07 pm
by Xaron
Thanks so far. :)

I'm not a newbie in Irrlicht but would you be so kind to point me to an example for a custom scene node and how i could it register to the skybox renderpass? It seems a lot have been changed since Irrlicht 1.0. :lol:

Thanks again and best regards - Xaron

Posted: Tue Jun 12, 2007 12:14 pm
by bitplane
uh.. example 3 is still the custom scene node example, and if you look in CSkyBoxSceneNode.cpp or CSkyDomeSceneNode.cpp you'll see they call SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX) in OnRegisterSceneNode()

Posted: Tue Jun 12, 2007 12:32 pm
by Xaron
Uh, shame on me. :oops:

But I still have the problem to render a single node even if it's not beyond the far clipping plane.

If I render the scene using smgr->drawAll() everything works fine, but if I try to render it using the render()-method, I see nothing:

Code: Select all

sun->getNode()->setVisible(true);
sun->getNode()->render();  // render the sun
sun->getNode()->setVisible(false);
smgr->drawAll();                // render all the other stuff
I just want to do the following. I sort all nodes by distance and start to render the nodes which have the biggest distance from the camera (which is always located at 0,0,0). After rendering all those objects I want to render the near objects (like ships) using drawAll and using the Z-Buffer.

Sorry for these (may be) stupid questions...

Regards - Xaron

Posted: Mon Jun 18, 2007 9:19 am
by Xaron
Ok, got it to work:

So this way you can render a single node using Irrlicht 1.3:

Code: Select all

node->setVisible(true);
node->OnAnimate(0);
node->render();
node->setVisible(false);
smgr->drawAll();    // render all the other stuff 
This might also be useful e.g. if you want to render a cockpit above the 2d hud information...

Regards - Xaron