engine bahaviour with very large distances

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
chamile
Posts: 9
Joined: Thu Jun 05, 2008 4:38 pm

engine bahaviour with very large distances

Post by chamile »

Hi,

Maybe first my intention: the subject is to realize is a space simulation game like "Elite". Therefore it's necessary to move objects with the size of some meters and a resolution of centimeters in a system with several million up to some billion kilometers. After solving a relatively easy camera beginner problem (http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=28895), I have two more advanced questions for which I have to find a solution before implementation:

1. as seen in tests, the camera (or the render engine?) switches off everything when setting the FarValue to 18.000.000 or more (I don't investigate the exact value but it's located between 1.6E+7 and 1.8E+7). Is this a defined or a technical restriction?

2. When I place an object to a coordinate with a distance of e.g. 1 billion km from centre, I expected a less smooth moving, when incrementing the position by 0.001 because of the float precission of f32. This was what happens at our first DirectX implementation, so we had to switch all vectors to double precission values. Surprisingly when I tested it, this doesn't happen with Irrlich, even at points for example P=(1E+12,0,0) I got the same movement behaviour than at the (0,0,0,). So mapping the "real" distance of the solar system to a vector3df should not be a problem. Can anybody agree with that or have I missed a problem here?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Re: engine bahaviour with very large distances

Post by rogerborg »

chamile wrote:1. as seen in tests, the camera (or the render engine?) switches off everything when setting the FarValue to 18.000.000 or more (I don't investigate the exact value but it's located between 1.6E+7 and 1.8E+7). Is this a defined or a technical restriction?
It's a precision limitation in matrix4::buildProjectionMatrixPerspectiveFovLH(). The values of M[10] and M[14] are being rounded to (f32)1.f. Upping the precision of the calculation arguments doesn't help, it's the casting to (T) that drops the fractions.

I don't see an obvious technical solution. To ameliorate it, you could set a larger near value for the camera, i.e. 10 lets you have a far value of at least 150,000,000.

However, with that large a range, you're going to have a very coarse Z buffer, so might see some unpleasant Z artifacts.

You can't just typedef f32 as double instead of float, as that causes ambiguity (as well as thousands of cast warnings).

Do you really need an accurate simulation though? For very distant objects, you could move their visual position to a point on the edge of your visual sphere, scaling them as necessary. Any differences in apparent position should be negligible.

chamile wrote: 2. When I place an object to a coordinate with a distance of e.g. 1 billion km from centre, I expected a less smooth moving, when incrementing the position by 0.001 because of the float precission of f32. This was what happens at our first DirectX implementation, so we had to switch all vectors to double precission values. Surprisingly when I tested it, this doesn't happen with Irrlich, even at points for example P=(1E+12,0,0) I got the same movement behaviour than at the (0,0,0,). So mapping the "real" distance of the solar system to a vector3df should not be a problem. Can anybody agree with that or have I missed a problem here?
I'd expect to see the problems that you described.

Code: Select all

	vector3df pos ((f32)1E+12, 0, 0);
	(void)printf("%.10f\n", pos.X);
	pos.X += 0.001f;
	(void)printf("%.10f\n", pos.X);
Result:

Code: Select all

999999995904.0000000000
999999995904.0000000000
You may want to check your test result. For the size of simulation you're describing, I'd fully expect to have to store and manipulate the world data myself using double (f64), and to accept that the Irrlicht f32 representation would be a coarse approximation.
Last edited by rogerborg on Fri Jun 20, 2008 7:49 pm, edited 1 time in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
chamile
Posts: 9
Joined: Thu Jun 05, 2008 4:38 pm

Post by chamile »

However, with that large a range, you're going to have a very coarse Z buffer, so might see some unpleasant Z artifacts.

You can't just typedef f32 as double instead of float, as that causes ambiguity (as well as thousands of cast warnings).

Do you really need an accurate simulation though? For very distant objects, you could move their visual position to a point on the edge of your visual sphere, scaling them as necessary. Any differences in apparent position should be negligible.
The only real need is the star in a solar system. It's the only object visible over such far distances. And of course the star background, but with that I'm completely unsure at the moment how to realize this. Everything else I plan to check against a maximum distance to the camera and remove it from the scene if this is too far away. For the star I really think I will map it to a virtual coordinate more near to the camera.

999999995904.0000000000
999999995904.0000000000
Exactly what I mean! I did the same test and saw at 50 AU distance a float resolution of some kilometers, when I expect that a 1.0f = 1km!
So I was really surprised when I render a model so far out and it makes no different moves than at (0,0,0).
Your suggestion to calculate the positions manually with double was also my idea. I think it will be the only way to ensure the correct objects positions. For the scene, I plan to move the coordinate system together with the players ship. He will always be at 0,0,0, so every rendered object (except the star) should be near the coordinate root, which will prevent any precission loss. I think there shouldn't be a large calculation overhead. It shouldn't matter if the position is changed from a scene object or from another storage object. And I will have to store each object outside the scene manager to manage it states, so this is no problem, I think.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

chamile wrote:For the scene, I plan to move the coordinate system together with the players ship. He will always be at 0,0,0, so every rendered object (except the star) should be near the coordinate root, which will prevent any precission loss.
That's a great idea, if you have a single player. I would have suggested it, but I was afraid of just diving in too fast and rough. I see you're already experienced and flexible though. Hopefully pre-lubed as well.

I think that all astronomical bodies will have to use a virtual position / scaled solution. Even with that, there's a precision issue. Jupiter has a radius of 71,492,000 metres. With a 1m = 1 unit scale, that's on the order of your far value.

Still sure you want a realistic simulation? ;)
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
chamile
Posts: 9
Joined: Thu Jun 05, 2008 4:38 pm

Post by chamile »

That's a great idea, if you have a single player. I would have suggested it, but I was afraid of just diving in too fast and rough.
Fortunately I plan only single player. But also for multiplayer this would be no problem if I move only the system for rendering coordinates with the player and the rest is calculated "in real".
And the renderer needs only the objects which are in range of the current player, so I will not use the automatic clipping but remove unseen objects manually. An additional distance check against all present object probably once per second will not decrease the performance, I think.
I think that all astronomical bodies will have to use a virtual position / scaled solution. Even with that, there's a precision issue. Jupiter has a radius of 71,492,000 metres. With a 1m = 1 unit scale, that's on the order of your far value.
Yep, you are right when using a 1m resolution. Currently I plan with 1 km. which would be enough to show even large planets. If this is practicable, a first implementation will show, but I think for the game unit resolution 5 places after the comma (1cm) are enough precission and should be good handled by f32.
The real problem is, nearly all 3D games (and so all examples) are located in a limited system. There is always a border you cannot cross. My game will have no border, it has an infinite ballroom ;). In theory you could fly until you die (or the fuel runs out what leads to the same result), of course this makes no sense in game, it's not planned to reach anything outside a solar system with this strategy.

But even if this is not enough, I have to realize a virtual position of the star. If I can do this for the star, I can do this with very low effort for all other objects. So if practical implemented, it would result in only one additional line of code in object position algorithm (maybe implementing this configurable ...)

However, it's a challenge

The realistic character of the simulation is undermined by the planned ship engine, which can move faster than Einstein postulates ;)
I see you're already experienced and flexible though.
Makes me possible to see such problems before running into the worst case scenery. I have lots of programming experience but these are my first steps in 3D. So currently I try out the engine and try to find problematic points.
Post Reply