Monday, May 30, 2016

c# - Overcoming float limitations for planet-sized worlds in Unity


As far as I know, going further than 1M units from the world origin in Unity is hardly possible due to floating point precision issues.


Making a world more than 1M units in radius would require either using double vars for coordinates or utilizing some space division technique to divide a massive scene into hierarchical chunks with the smallest of them being around 10 000 units, i.e. each world-space position would be expressed by the chunk hierarchy the object's in and a bunch of float vars representing its local position (and possibly rotation and scaling) inside the last chunk.


Either way, doing this would require implementing a completly new coordinate system, so I'd like to know whether or not that is possible in Unity, and if so, how may I make it work with existing Unity systems like physics and so on.


P.S I can't just move the world into origin as the player moves since I want to have things going on simultaneously around the planet.


Thanks!



Answer



You're thinking in very static terms.


Just because an object is half a world away doesn't necessitate any issues. If entity coordinates are stored relative to chunk rather than relative to world, this is trivial to achieve. Welcome to the way you'd have to do it if you were writing a voxel world in native code.



So let's assume a concept called locales. It's a set of chunks that are in close proximity to one another. What matters is the float space internal to a given locale never exceeds the safety limit. You need to determine what your discrete processing locales are, start by taking all chunks that fall within a radius of the position of entity n (could be the player or something else). In my current engine, I make sure that if even one chunk of two different locales is overlapping, that these locales merge into one locale / set of unique chunks. This ensures that you never process all the entities in any single chunk more than once, in a given frame.


Now that you have your locales/chunk-sets, you can perform game logic on them and their contents. And it doesn't matter how far they are away from the player or from origin. What matters is that you get a chunk that is roughly central to each set, treat that as the origin i.e. float [0.0,0.0,0.0], and work your way outward from there. Given typical view range in a game, I guarantee you that you will never need to see more than a few kms, which is very doable with float, without serious issues.


Aside from Unity, one option is to write an engine from scratch, I guess, and use something like libfixmath, where you can still use decimal points but because they do not float, they will never have these accuracy issues. But I guarantee you will need chunks and locales for other reasons, so it's probably not worth the effort.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...