🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Issues with floating origin

Started by
58 comments, last by dragonmagi 2 years, 3 months ago

JoeJ said:
And i don't want to write a templated replacement, because it would be slower a bit.

Just discussed this with the dev of Newton Physics, which i'm using. Newton math lib has both float and double SIMD optimizations, so i can use just use that and my search is over.

But the interesting thing is he also tried a templated approach, which gave him the same issues i saw with GLM: MSVC fails to generate good SIMD code form it, and constructors are big issue needing a lot of special care. He ended up not using templates.

Advertisement

JoeJ said:
So SIMD is doomed to be a close to the metal optimization

I think what's been lost here is that I'm using C#, so these kinds of intrinsics are inaccessible for me. So SIMD and all that is meaningless to my question. One of the reasons I don't want to jump to double is that I'm using the System.Numerics vectors which do use SIMD instructions under the hood, and the math is all set up and battle tested. Whereas if I write my own double version of vectors, then that adds a whole other layer of maintenance and testing that I am just not interested in doing - and, trust me, my math skills are utter shite so I can be sure I'd mess it up somehow.

Now, with that said, I did set it up to use doubles for position tracking and for the floating origin stuff and things seem to be working (mostly - I have one issue regarding floating point rectangles).

So while the doubles did help, I found other issues with other types that rely on single precision floats (e.g. float rectangles, which I use for targeting regions in space). And since I don't want to rewrite every little damned thing to make this work (it's not that important, it's just a hobby after all), I decided to give some thought to other approaches.

I decided to use a sector based approach where distant objects are not displayed until I'm in the sector. This way I can place all the “distant” objects nearer to 0x0 and display them when I'm the sector. So far, it works perfectly in that I don't need doubles, or floating origins, or anything else. I'm sure there are drawbacks to this approach, like anything, but this is just a hobby after all, not looking to make it AAA or polished Indie worthy.

For giggles, here's a screenshot after “jumping” to the sector with Jupiter in it:

Jupiter is Stupider

@Tape_Worm Hi there,

I'm curious why you think there is “there's actually precious little about continuous floating origin).”

Is the y offset code correct?:

"_x = (decimal)-_offset.X;

_y = (decimal)-_offset.X;

"

looks like the second line should end with _offset.Y

And, yes, doubles can't solve the real issues when the underlying system is float based.

BTW, since you are using 2D, don't you just keep Z=0f; all the time?

There really is quite a bit of information on this algorithm because it is the same as published in 2005. However, it is understandable that you may think there is not much information available because, from 2010, most information on what was called “floating origin” was not the correct method, it was in fact the opposite from a conceptual and algorithm point of view.

Summary of information on continuous floating origin

Continuous Floating Origin (CFO) is an algorithm that was originally termed floating origin in a formal (peer reviewed) publication in 2005: https://www.researchgate.net/publication/331628217_Using_a_Floating_Origin_to_Improve_Fidelity_and_Performance_of_Large_Distributed_Virtual_Worlds.

Floating origin was renamed to continuous floating origin in 2019:

https://www.researchgate.net/publication/337759338_Healing_Cracks_in_Cyberspace_towards_best_practice​ because a number of very different algorithms were later informally published under the same name.

For concepts, terms and techniques relating to Continuous Floating Origin, please refer to the glossary: https://www.researchgate.net/publication/352871447_Relative_Computation_glossary_of_terms.

There are many related articles on the same research page: https://www.researchgate.net/profile/Chris-Thorne-2/research.

For videos on CFO, related techniques, experiments and implementations please refer to:https://www.youtube.com/channel/UCpi9nP_1DumSTkPMhfniimw​ or https://www.youtube.com/user/glyphmancer/playlists​.

A full implementation of CFO is available:

https://assetstore.unity.com/packages/templates/packs/continuous-floating-origin-195971.

I hope that clears things up a bit ?

dragonmagi said:

@Tape_Worm Hi there,

I'm curious why you think there is “there's actually precious little about continuous floating origin).”

Is the y offset code correct?:

"_x = (decimal)-_offset.X;

_y = (decimal)-_offset.X;"

looks like the second line should end with _offset.Y

And, yes, doubles can't solve the real issues when the underlying system is float based.

BTW, since you are using 2D, don't you just keep Z=0f; all the time?

Wow, I was hoping you were on here and would respond.

So, regarding x/y: Yeah, that's a bug, but those two variables were used for display purposes only, I didn't use them for anything else. It's kind of a leftover, pay it no mind.

Regarding Z: I do use the Z because I use a depth buffer to help with sorting the sprites and keeping batching sane, those Z values + the depth buffer allow me to layer things and have them interact with post processing effects such as bloom. Regardless, this has no effect on my positioning of objects in the world.

And finally, yeah, when I said precious little, I meant that the only things I've found are your comments, videos and research papers. Any sample code I've found is not actually floating origin (at least, according to what I've read from your comments to other people). It's pretty difficult to find a working implementation to see if I'm on the right track or not. I'm aware you have an implementation up on the Unity asset store. However, I don't use Unity, just my own custom thing that I've built up over time, it just looks Unity-like.

The issue was that I had an object at ~800,000 x 200x000 in space, and I wanted to teleport to that object. Using my (probably quite bastardized) floating origin, I found that I could end up near the object (although the motion was not jittery either, so that part worked fine). However, I could never exactly land directly onto it, it shifted around (and quite randomly too, sometimes to the left, or north east, etc…) My guess was due to floating point inaccuracies that built up as I moved around a bit before teleporting. When I switched to doubles, it worked exactly as it should have, but of course that introduced other issues.

@Tape_Worm

oh, ok so it sounds like you had seen some of the fake implementations.

“However, I could never exactly land directly onto it, it shifted around (and quite randomly too, sometimes to the left, or north east, etc…)”

That sounds a lot like jitter of some form, if there are any objects with large coordinates then that would do it. Or it could be what I call distant relative jitter: you can at the origin but something nearby jumps around (or slides away from you) and you cannot approach it or a precise point on it (examples of this problem: the wandering tower (after about 1:40):

and after about 1:10 in this one:

)

because they is connected to something with large coordinate or it uses large coordinates in its vertices.

So I use the technique I call Dynamic Resolution Spaces to solve it. As you say, doubles improve it but don't solve it.

Another case that can happen for full scale is when a single object, such as a planet, is not broken up into small meshes. One mesh with all vertices that have coordinates greater than, say, 5 digits, is too hard to deal with in single precision.

To give you a little more insight:

Whether the objects nearby are jittering or your your view point is jittering, interactive motion towards something can exhibit a loss of degrees of motion freedom in one or more axis direction. In the wandering tower example, I had travelled the greater distance just in the Z direction, and consequently lost motion freedom in the z direction. The proof of this is simply your motion speed. if you can't move at a very slow speed, you have lost too much resolution in the direction of movement. Increasing your speed will allow movement but you will jump past/through something you want to approach accurately.

dragonmagi said:

And, yes, doubles can't solve the real issues when the underlying system is float based.

That depends on what you mean. They certainly can solve it even with a 32 bit float GPU. You just can't go to wold space in 32 bits, but that's solvable. This is how my code works. Also Unigine works in double, as does Star Citizen, but I can't comment on exactly how they use it.

@Gnollrunner “They certainly can solve it even with a 32 bit float GPU”

Well that is not double precision, is it? Can you describe an algorithm or design for what you mean?

In my experience, the solution is in the design and algorithms of World and code. I have a lot of documents, code and videos that explain what I mean.

The floating origin algorithms, designs and related methods provide a single unified general approach to positional jitter and high fidelity interaction independent of precision.

Just throwing precision at a wrong designs and algorithms can help with some things and is not a general solution.

This topic is closed to new replies.

Advertisement