This article describes the "Floating Point Fix" a workaround built into Gaia Pro to deal with floating point precision issues in the Unity Game Engine. You can use this fix to combat issues like flickering shadows and buggy physics/animations that happen when your world exceeds a certain size (starting at 5.000 meters in any direction, with barely visible issues to turning really bad at around 100.000 meters where there are very noticeable visual bugs).
If you have a relatively small world that does not extend past 5000 meters in any direction, you would not need to activate the floating point fix, it will not add any value to you.
Please note that it is entirely optional to use the floating point fix - it is an additional offering to help you to deal with this common issue in the Unity engine, but if you do not like it or its implications, you can just keep it turned off entirely and e.g. develop your own solutions for this issue.
Why do floating point precision issues happen?
In most game engines, position data is stored in variables that use the float data type. The float data type is limited to 4 bytes of storage capacity. If you want to store a floating point number in there, you can use some of the storage space for "numbers before the point" and some for "numbers behind the point", the fractional part of the number. For example, you could store:
1.234567 or the value
123456.7
This is a simplified example, but the point is: For the first number, you would have a higher precision because you use 6 digits for storing the fractional value of the number, whereas in the second number, only one digit is used for the fractional part. The second number is less precise as a result. If those numbers represent meters, the second number would only be able to track steps of 10 centimeters because there is only one digit for fractional values.
If these numbers are used for calculations like lighting, animation, and physics, then these calculations become less and less precise the further the objects are away from the world origin at 0,0,0. The floats might even get multiplied with each other, which further adds to the problem as those inaccuracies are amplified then.
This is not a bug in Gaia or Unity but a fundamental problem in most game engines. Using higher precision variables to avoid or push back this issue is possible, but this also has other drawbacks.
Seeing is believing: Testing floating point precision issues in Unity
You can quickly experience floating point precision issues yourself in Unity. Create a new scene, and place a plane and a cube into it. Position the cube it throws a shadow on the plane, and make it a child of the plane like so:
Move the plane to x=10.000. Double-click on the plane in the scene hierarchy to focus it again in the scene view. Move the scene view camera back and forth towards the cube and watch the shadow of the cube closely. You might see the outline of the shadow flicker due to the decreasing precision, but you may need to watch very closely to see it.
Now increase the distance to x=100.000, double-click the plane in the scene hierarchy, and move the camera back and forth towards the cube again. You should get a very noticeable wobble of the scene view camera and shadow flicker.
Increase to x=1.000.000 and focus on the plane again. You should get a warning in the unity editor, and you should get severe visual issues even with the scene standing still:
You know the drill by now, add one more zero to the x-distance to pretty much break your scene:
You would rarely experience issues this severe in your own project, as you might never get to such extreme distances. However, remember that almost invisible issues at lower distances can add up by being multiplied & amplified with each other. While you might not see completely destroyed geometry, it is not unlikely to see shadows flickering or physics acting weird at higher distances.
How does the Floating Pont Fix in Gaia work?
The floating point fix in Gaia is a simple world shift fix, a common workaround for these precision issues. It measures if the camera moved a certain distance from the world origin (x=0, y=0, z=0). If the distance exceeds the threshold, all objects in the scene are shifted, so the camera is positioned at 0,0,0 again. In this way, all objects are positioned in a spot where the calculations for rendering are "precise" again. This is usually not noticeable for the player because all objects are still in the same (relative) spot to the camera.
Enabling / Disabling the Floating Point Fix
There are multiple ways to enable the fix. The floating point fix can be enabled during the world size selection from the Gaia Manager or the World Designer.
You can also enable the fix at a later point from the Terrain Loader Manager in the scene:
This is also the place to disable the fix again if you set it up already earlier.
When you enable the Floating Point Fix, it does not make many changes to the scene. It mostly adds a "Floating Point Fix" script to the main camera where the logic for the shift happens. All other logic, e.g., that terrains are being loaded into the correct spot in a shifted world, is handled by Gaia automatically.
Integrate your own solutions with the Floating Point Fix
When developing the logic for your game, you would need to be aware that at some point, all objects might shift around to execute the fix. This can create problems e.g., when one of your own scripts works with the positions of objects that are stored in a variable. It might happen that an object is suddenly not at that position anymore because a shift happened.
Likewise, 3rd party assets/scripts might run into issues when the entire world shifts around from one frame to another.
Scripting
You can work around this by accessing the total accumulated shift from the Floating Point Fix.
FloatingPointFix.Instance.totalOffset
gives you a Vector3 for the cumulative offset that the floating point fix has created so far by shifting. E.g. if the offset is 0,0,0 no shift has been made yet, if it is x=5000, y=0, z=2000 the world has been shifted 5000 meters in the direction of the x-Axis and 2000 in the direction of the z-axis. You can use the function
FloatingPointFix.Instance.ConvertToOriginalSpace
to calculate what the original, unshifted position of an object would be in world space.
Main Camera Setup
The logic for the shift happens in the "Floating Point Fix" component. This script is meant to be added to the main camera in the scene. Gaia will automatically add this script to all players created through the runtime setup process in Gaia, or when the custom player setup process is used (either from the Player component or through the Gaia API)
There should only be one instance of this script in the scene to avoid conflicts. The only thing to configure is the "Threshold" value that defines at which distance from the world origin a shift happens.
Adding Custom Objects
Gaia does handle all its own objects it creates in the floating point fix automatically. If you add additional objects to the scene that are not spawned through Gaia, that you want to be shifted as well, you would need to add the component "FloatingPointFixMember" to the Game Object. At the scene start, this object will then "register" with the Floating Point Fix to ensure it is shifted along with all objects in the scene once a shift occurs.
The code in there is very "manageable" and is just registering the object with the fix upon creation and unregistering it once it is destroyed. If you have programmers in your team they can take a look and might be able to integrate your custom objects without having to attach this component.
Particle Systems
Particle Systems that simulate in World space need to have the FloatingPointFixParticleSystem attached to them. It will update the particle simulation to the new location when a shift happens so no particles are " lost ".
Static Objects
It is impossible to keep static objects in the scene to enable the shift since these cannot be moved. (unless they are not relevant for the shift anyways)
- 1
- 1
Recommended Comments
There are no comments to display.