Making an infinitely large play space in Unity3D [Floating Origin]


  • Share on Google+

Today I am going to walk you through a bug I encountered while creating my most recent project Project Stardust. If a camera in Unity moves too far away from the origin of the play space, things start to break down mathematically. Visual artifacts become very apparent, most often seen in the form of vibrating or flickering meshes/textures.

The Cause: Floating point rounding error

Since the Transform’s  x, y, and z coordinates are of C# float data type there are limitations to ranges in which rounding errors do not occur. For a full write-up of why this happens you must understand the IEEE standard for floating point numbers which you can read about here. A rudimentary calculation based on established ranges listed here show that a play area would be confined to around 10km or ~16k unity units in any direction before things start to deteriorate fairly quickly.

What if you want to allow the player to build an infinitely large play space for your world?

 

The fix: Move the world

I very recently found out about a technique called Floating Origin which is used to keep the origin centered on the player. This continuously offsets the origin on a fixed interval which will recenter the world’s x,y,z coordinates about the player, then take every object in the scene and move it by the distance delta.

The result is the movement of the world around the player, rather than moving the player around the world. If the environment around the player to be shifted around is not optimized well enough then each “movement” of the world will be a computationally intensive thing to compute, resulting in bad CPU performance.

The script shown here is an example of such a movement of the world about the player. Attach it to the player’s camera [source]