When using larger and larger coordinates, there comes a point where Unity displays a warning that “precision limits” have been reached, see bottom right of image below. However, a simple experiment showed that even sensitive physics simulation can scale well beyond these limits if the right algorithm is used.
These results lead me to believe that the limits do not exist in Unity rendering pipelines and only in the application algorithms.
What are your thoughts?
This is a basic computer science problem. Floating point numbers have a limited amount of precision. The usual 32 bit floating point number has roughly 7 digits of precision. What that means is larger numbers have less precision, or there’s a larger jump between what numbers can be represented. So, for example, once you get up to values over 8.5 million, the values are whole integer numbers only.
This issue exist both on the GPU and CPU representations of the scene. But if you keep the camera near the world origin, the issues of the scene precision for far away objects isn’t visible since at that point they’re too small to see.
Thanks @bgolus for trying to help. I wrote my 2007 PhD thesis on this so I’m well aware of the comp sci basics I was not asking about why this occurs. I was making a statement about the warning message and how it implies that Unity cannot scale to larger single precision floats. It can scale to 10^25 and still be functional. You can find proof in my links.
cheers
It’ll depend on the hierarchy though. If you’re doing stuff on objects that are super far away, you better believe their positions are going weird. If you are offsetting a child object back relative to center, then there’s a good chance the floating point error on both sides works out to match. If you have that root object slightly rotated and scaled … well, it’s going to be less pretty as the precision limits won’t match.
Thanks @bgolus , although a little off the topic I wanted to talk about, I appreciate your comments and these things are worth discussing.
** Correction: this is actually on topic because bgolus is describing, praticularly in the next post, algorithms that handle precision limitations.
Distant objects will jitter, as you say. However, the beauty of floating origin is that perspective foreshortening reduces jitter in proportion to the distance and therefore it is generally not a noticeable problem in the rendering. I do understand there are exceptions like when two surfaces are too close for the z depth to be resolved correctly.
Not quite sure what you are saying here. With continuous floating origin the scene root is only used for translation of the scene and should not be scaled or rotated. Scaling the entire scene, does nothing to solve the relative jitter within the scene: it stays the same. Although, if the camera is outside the hierarchy, jitter will change relative to the observer - but everything would also either too big or too small.
I guess my point is the limitations absolutely exist, but by keeping the camera near the world pivot you just avoid being able to see some of them. That doesn’t mean they’re not there. If you have a root that’s 8.5 million units away, the root is limited to 1 unit movements, since that’s the precision of a float at that point. Any objects that are children of the root that are positioned close to the camera back at the world 0,0,0 are also limited to that same 1 unit of precision. However their children are capable of moving freely without precision issues since their positions are stored relative to their parent. But if that child is also huge, it’ll have precision issues.
A good example of where these problems still exist is lets say you are trying to simulate the solar system, with the sun as the floating root. If you keep the camera at 0,0,0 and try to move smoothly, it’s not possible since you can only move the root in 1 unit increments. Now you can of course move the camera within some range and snap the root back, and that is indeed what a lot of infinite runner type games do. But what if you want to simulate the earth to scale? Well, presumably the earth needs to move and rotate as a child of the floating root, and the camera needs to be able to move smoothly across the surface of the earth. Now you’ve got two competing, and unaligned floating point precision problems, so you’re going to see jittering.
The real solution that many space-scale games use is internally they keep all objects’ positions stored at double precision. Using double precision the camera relative positions are calculated and then actual game object positions are set, keeping the camera at or near 0,0,0. This avoids all of the visible precision problems since most of the heavy lifting is being done with 64 bit floats, and any remaining floating point problems are mostly made invisible. Games like Kerbal go a few steps beyond this and actually uses multiple cameras for different scale representations of the universe. A “full size” one for the ship, and for planet surfaces when on or near the ground of a planet. A planet scale one for orbiting a planet but not close enough to interact with the ground, and a universe / solar system scale for everything else. Usually with anything really far away represented as single sprites or very simple meshes since they no longer need anything more.
Agreed, this is what I meant by perspective foreshortening: you won’t normally see the distant jitter. When you move the objects close, they don’t jitter. This is not a problem for rendering. It could be a protential problem for some calculations but there are ways to solve that too.
Hmm, full-scale earth modelling with floating origin is not a problem, whether it is CFO or POS versions. Perhaps you are thinking that I was saying it can all be done in single precision?
I am not suggesting that single precision be used for the entire world model. For a large scale app, I use doubles and only convert to single precision when moving to a double precision view point or placing a double precision object - after subtracting the double precision view position (i.e. current world/view origin), of course.
Yes, that is what I have always done: use doubles at the back end and single precision at the front end.
and the KSP guy plagiarised verbatim from my work in his presentation. The planet-express quote was in my thesis printed 2007.
BTW, I made a correction to the post where I said the discussion was a little off-topic. This is actually on topic because bgolus is describing algorithms that accommodate precision limitations and low resolution induced jitter.
And that is the point of my original post: with the right application algorithms, Unity handles large single precision numbers perfectly well. The message that Unity displays in my example might mislead developers into thinking that the limitation is within Unity and it does not point to a knowledgebase or guide about useful methods for handling large spaces.
First I would like to apologize for ‘upping’ this topic again and for not speaking English well. But from what I’ve read and understood, you have a solid background on the issue I run into in my prototype.
However, I should point out, my knowledge is ‘shallow’, little on the topic of ‘scalar quantities in Unity’.
I will try to formulate the question in a simple way, using the game ‘Infinite Lagrange’ (1 - link below) as an example.
From what I understand, they used a relatively large size of ‘space’, but scaled that entire space to something ‘smaller’, and the objects contained in that space, such as ‘planets’, ‘spaceships’, ‘asteroids’, as small elements. But ‘small’ to the point of having a certain (good) quality of textures, producing good results in terms of aesthetics and, essentially (this is where I want to go) on ‘movement’.
All movement seen ‘in game’, of the object called ‘player’ and/or AIs, is extremely ‘smooth’. There is nothing ‘shaking’ on the screen, like an extreme ‘low mov’ (frame by frame).
It is very complicated for me to know ‘where to start’. My idea was to make a prototype, nothing abusive, according to my objective, material limitations around it. Regarding the subjective, I don’t think I need to go back to college (mine was Piano, music ) I’m a little old for that, I think and study a lot (and ask a lot). I ask, where to start to understand how Unity works on the topic of ‘scalar magnitude’? What can I use as a safe reference to start something when, in this something, I will have to think about aesthetics in general, physics or just oriented movement (no physics in this case) and, mainly, performance? Plus, this question and itself, is it correct?
Thanks @jeroll3d , you do not need to apologize. These are important topics and I have devoted a large part of my life to them.
Thinking, reading and asking before going too far on prototypes is very commendable. I spend more time thinking and designing than coding myself :).
The resources I provide that address your and similar questions are as follows:
Research covering concepts, theory, design and experiments can be found here.
Unity assets that implement the above start with this asset that implements continuous floating origin. That and [Dynamic Resolution Spaces](http:// https://assetstore.unity.com/packages/slug/198907) are the most relevant to your questions.
I cannot comment on games I have not researched, like the one you linked. In general, most of what you say about scaling is correct for the many examples I have reviewed, so it may be the case for this game. Hopefully, you can ask them directly, or they may have a forum where you can find out.
Although the floating point values for coordinates are scalar, you should think of 3D space as variable resolution geometric space. The formula for positional error is geometric (and relative), not scalar.
The references I gave above, and the code, cover movement and orientation, and time as separate (origin-centred) concepts and with the goal of optimising everything: quality, scale and performance. This concept-oriented programming (my term) builds an optimisation algorithm (e.g. continuous floating origin or rotation floating origin) around a specific positional representation (e.g. 3D coordinate space or rotation space respectively) with common goals (better performance, accuracy, quality, scale).
I hope my answers and references help in some way,
good luck.
@jerroll3d There is one answer in the video on that site. The video starts with a zoom out, nice and smooth, then gets progressively shakier. This is a possible case of increased jitter with the increase in scale.
I watched your videos, read a few things. But they are quite complicated for me to understand, at least the more technical aspects in English - the problem is not English itself, but dealing with many topics at the same time - after all, this will involve everything from camera elements, physics, mathematics, the engine and how everything applies to the engine. It’s an infinity of things that, I suppose, would only have mastery or a more solid knowledge in a few years (and I’m being optimistic).
Anyway, I’ll keep reading and researching. But I think we can handle things - for now - like that. Let’s say a ‘planet’ is 10 units of Unity measurement (10 meters, abstractly speaking) a spacecraft is 10 centimeters - speaking of what we have today in Unity. I’ll start my private tests with this. Two things will stop me for now - a simple movement (still uncontrolled) of any axis - how it behaves over multiple speeds (using, of course, timeDeltatime to test the same idea on two different devices). The other will be ‘texture, light and shadows’ at the same time - here comes another theme, also vast and that will require more knowledge (about shaders in Unity).
My goal will be to produce this simple prototype, really simple, and find out what happens to motion at small scales - say, 0.001 or even smaller (if possible). another will be to see how light and shadow, of course, textures will behave using a simple zoom. My observation windows will be two, the common viewport and the engine viewport.
I know the idea sounds ridiculous, but I think it’s a good start. Wish me luck and thanks again.
@jeroll3d , I understand there are so many things to learn. Starting simple and coding and testing is one of the best ways to gain a good grasp of the concepts and what is involved in solving each issue. So good luck :). BTW, your city renderings look very impressive.