Ogre::Real, floats vs double, sliding origin and more ;)

Problems building or running the engine, queries about how to use features etc.
Post Reply
awishformore
Kobold
Posts: 32
Joined: Sun Sep 07, 2008 11:48 pm

Ogre::Real, floats vs double, sliding origin and more ;)

Post by awishformore »

Hello there.

As I've just finished the structure of my application and got to the implementation part of the "game", I realized a big issue I didn't consider in the abstract planning phase: Ogre::Real seems to be a typedef for float. Now, I found out I can switch that to double, but apparently most 3D hardware works with floats anyways, so it wouldn't solve anything.

The universe in which my story plays is huge, so on the server-side, I use double as coordinates. That way, you would have to travel into one direction for over a hundred years in real time to reach the bounds. This means I can use 3 decimal precision in all operations I do.

Once this information gets to the client, it obviously has to be converted to floats. Taking into account both precision of the Z buffer and precision of operations made on coordinates client side, I decided to make the origin a sliding one, thus relatively adjusting all other coordinates. I want to switch origins as soon as the player gets a distance of 4096 away from the current origin, and thus a maximum of 4096 of change in one coordinate. With the far clipping distance being set at 8192, this means the maximum coordinate any node can have is 12288. Is this low enough to guarantee absolute precision when it comes to Ogre operations with floats? I don't know the exact inner workings of the engine, so I can't know for sure.

The other issue is the Z buffer. I want to go somewhere mid-way between great close precision and good far precision, because objects are rather simple (mostly spheres), so that should be enough to get rid of any artifacts. Does 16 make sense as a near clipping distance? This would mean vertexes are visible inside the 16-8192 range.

One last problem I have is objects that are further away than 8192 but that I still want to draw. Is there any common technique used to do this? For instance, I want all stars (maybe around 10) to be visible anywhere you are as orientation cues. They are simple light emitting entities with a certain colour. I thought that I would just place a placeholder for each star at a fix 8192 distance until the real star gets into reach. If it's too visible that the entity doesn't change in size as we approach until it enters our far clipping distance, I could scale it down accordingly. This however seems like quite the cheap work-around, so if anyone knows a better way, I would really appreciate.

Greetings, Max.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Ogre::Real, floats vs double, sliding origin and more ;)

Post by Kojack »

this means the maximum coordinate any node can have is 12288. Is this low enough to guarantee absolute precision when it comes to Ogre operations with floats?
At 12288, a float will roughly be accurate to around 0.001 (I tested it).
The other issue is the Z buffer. I want to go somewhere mid-way between great close precision and good far precision, because objects are rather simple (mostly spheres), so that should be enough to get rid of any artifacts. Does 16 make sense as a near clipping distance? This would mean vertexes are visible inside the 16-8192 range.
Unfortunately z buffers have awesome close precision and crap far precision. Half of the entire z buffer range covers just the distance from near to 2*near.
With 16-8192, the z buffer will be accurate to around 0.0000009 at 16 distance and 0.2495 at 8192 distance. Not too bad in this case. For a better spread, you might want to look at a logarithmic z buffer: http://outerra.blogspot.com/2009/08/log ... uffer.html
One last problem I have is objects that are further away than 8192 but that I still want to draw. Is there any common technique used to do this? For instance, I want all stars (maybe around 10) to be visible anywhere you are as orientation cues.

One thing you can do is put the distant objects into a different render queue, then use a render queue listener to change the far plane before/after rendering them. Distant stars won't need accurate z buffering with the rest of the scene, so messing with the far plane and disabling depth write should let you render them in the distance without worrying about the normal far plane distance.
Although that's just a guess, I haven't done it myself. :)
awishformore
Kobold
Posts: 32
Joined: Sun Sep 07, 2008 11:48 pm

Re: Ogre::Real, floats vs double, sliding origin and more ;)

Post by awishformore »

Kojack wrote:At 12288, a float will roughly be accurate to around 0.001 (I tested it).
From my text I thought it would be clear that I know the precision of a float (2^23 = 8388608, to be precise). The question was however whether this allows me to have Ogre computations and operations done in sufficient (or complete) precision. I assume that certain operations will operate on fractions of fractions of my coordinates; adding a very small resulting fraction to my coordinates would mean a huge portion of the decimal part of the solution would be lost. As i have no idea in how far this happens, I'm asking whether my coordinates allow for sufficient precision in such operations.
Unfortunately z buffers have awesome close precision and crap far precision. Half of the entire z buffer range covers just the distance from near to 2*near.
With 16-8192, the z buffer will be accurate to around 0.0000009 at 16 distance and 0.2495 at 8192 distance. Not too bad in this case. For a better spread, you might want to look at a logarithmic z buffer: http://outerra.blogspot.com/2009/08/log ... uffer.html
This is wrong as far as I know. From what I have learnt, the precision of both close and far objects is a function of the near and far clipping distance. Hence the question. The scenario where half of the z buffer range covers the distance from near to 2*near should only be a very specific case.
One thing you can do is put the distant objects into a different render queue, then use a render queue listener to change the far plane before/after rendering them. Distant stars won't need accurate z buffering with the rest of the scene, so messing with the far plane and disabling depth write should let you render them in the distance without worrying about the normal far plane distance.
Although that's just a guess, I haven't done it myself. :)
Will give it a try, thanks!
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Ogre::Real, floats vs double, sliding origin and more ;)

Post by Kojack »

This is wrong as far as I know. From what I have learnt, the precision of both close and far objects is a function of the near and far clipping distance.
Try it yourself in the z buffer calculator:
http://www.sjbaker.org/steve/omniv/love ... uffer.html

The far plane has a very minor effect compared to the near plane. With 16-8192 for the planes, distances of 16-32 covers 0.50098 of the total z buffer range. Moving the far plane back to just 1000 makes distances 16-32 cover 0.50813 of the z buffer. Moving the far plane out to 100000 makes the same distances cover 0.50008 of the z buffer. It's not exactly near*2 == zmax/2, but pretty damn close.

With a logarithmic buffer, the far plane is what controls the distribution and the near plane doesn't do much. On the Outerra page, he had a near plane of 0.0001m and a far plane of 10000000m.
awishformore
Kobold
Posts: 32
Joined: Sun Sep 07, 2008 11:48 pm

Re: Ogre::Real, floats vs double, sliding origin and more ;)

Post by awishformore »

Kojack wrote:Try it yourself in the z buffer calculator:
http://www.sjbaker.org/steve/omniv/love ... uffer.html

The far plane has a very minor effect compared to the near plane. With 16-8192 for the planes, distances of 16-32 covers 0.50098 of the total z buffer range. Moving the far plane back to just 1000 makes distances 16-32 cover 0.50813 of the z buffer. Moving the far plane out to 100000 makes the same distances cover 0.50008 of the z buffer. It's not exactly near*2 == zmax/2, but pretty damn close.

With a logarithmic buffer, the far plane is what controls the distribution and the near plane doesn't do much. On the Outerra page, he had a near plane of 0.0001m and a far plane of 10000000m.
However, the distribution of precision on everything between very close and very far changes drastically with both near and far plane, for a good illustration check here. A near plane of 0.0001 is a very bad idea in either case.
Post Reply