3D Graphics Quality and Floating Point Accuracy on Android

I am working on a 3D RPG game for the Android called Heroes Of Honesty http://www.PompiPompi.net.

My Galaxy Note Android phone got less than 16M concurrent colors. I am not sure how many, maybe 64K colors, maybe a bit more. The point is that on 3D graphics, gradients look a bit coarse color wise.
There is nothing much you can do about it, this is a hardware limitation although you might be able to choose a different color palette.

However, there is another issue. Floating point accuracy.

There is a limitation to floating point accuracy on the programmable shaders of GLES2.0, and you can even reduce the accuracy on compile time.
This might cause artifacts, and it might be worse than you realize.

The following images were taking from my Galaxy Note phone. You will notice that the top image’s gradients are more coarse. This is exactly the same scene.

Bad Float Accuracy

Good Float Accuracy

You can see the gradients on the fog at the back, and also if you look carefully at the ground you will see at the top picture that it’s more jagged.

So why does this happen? This is the exact same scene.

When drawing a 3D scene you need to set the position of the objects to draw and the position of the camera and light sources.

At this scene the characters are somewhere on the world map away from its center. This mean I am setting the camera look at 3D coordinate to something such as (-1000, 0, 1000).
The character on the center is at the same position of the camera look at coordinate, so it’s position is also set to (1000, 0, -1000).

What if we would draw the same scene, but now we move all the objects, camera and light source so the main player will be at position (0, 0, 0). It doesn’t matter for the scene since we always look from the viewpoint of the camera.

It turns out that doing this improve the floating point accuracy.

Since positioning the camera and characters at (1000, 0, -1000) makes the floating point contain a large number(1000), all the calculations relative to it are done relative to a big number. Therefore there are fewer bits in the floating point assigned to the smaller values.

Such smaller values might be the vertex coordinates of the character’s mesh, but now instead of being 1000.01 they are 0.01 which leaves more room for accuracy.

The top image is rendered when everything is placed relative to the map’s center, and the bottom image is rendered when everything is placed relative to the character’s center.

2 thoughts on “3D Graphics Quality and Floating Point Accuracy on Android

  1. I guess this would explain why cell shading has become so popular lately.

    Apparently the Galaxy Note gets a lot of criticism for banding issues (e.g. http://forum.xda-developers.com/showthread.php?t=1513838 ). It’s supposed to be a 24-bit screen, but LCD makers have a long history of using 18 or 21-bit screens and trying to use temporal dithering to blend colors. If you’re target market includes cheaper devices, you may have to assume that many people will be playing with 16-bit (65k color) screens, and try to mitigate that somehow 😦

    An easy fix may be to minimize the use of point lights and dynamic lights on non-textured or flat surfaces, such as the landscape and ground plane.

    Regardless, using float16s to hold positions/normals seems like a recipe for trouble. They only have an effective 11 bits of precision, so their level of error is about 0.05%. That means they can’t represent numbers between, e.g. 1000 and 1000.5. OTOH, A float32 would be able to represent about 2^13 numbers in this interval. Specular lighting is often the most obviously affected by low-precision normals, as the exponentiation amplifies the level of error.

    Still, good to see you’re making progress. Can’t wait to see this in the market 🙂

    • Thanks, that is some good info.

      The reason why people use cell shader is different though(I think). The big issue is that mobile phones can’t perform very well when the fragment shader have more than trivial calculations.
      That means full phong shading is going to be slow on the phone.
      I am talking about this in an article I haven’t released yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s