libgdx / box2dlights

Fork of box2dlights by Kalle Hamalainen
Apache License 2.0
257 stars 82 forks source link

Color banding on Android #93

Closed ApprenticeSoft closed 8 years ago

ApprenticeSoft commented 8 years ago

The desktop version of my project renders very well, but when I port it on Android, the light gradient is not smooth, with a color banding effect.

image

To use Box2DLights in my game, I use this code in my GameScreen :

rayHandler = new RayHandler(world); 
rayHandler.resizeFBO(Gdx.graphics.getWidth()/5, Gdx.graphics.getHeight()/5); 
rayHandler.setBlur(true);   
RayHandler.useDiffuseLight(true); 
rayHandler.setAmbientLight(new Color(0.15f, 0.15f, 0.15f, 0.1f));

I also tried to play with different parameters such as diffuseBlendFunc or shadowBlendFunc but I wasn't able to remove or reduce this effect.

I observed the exact same problem on my 2 Android devices. Is there a trick to remove color banding on Android devices or is that a know issue of Box2DLights ?

Thanks in advance.

ApprenticeSoft commented 8 years ago

Finally, here is the solution :

The problem was linked to a low bit depth on Android. If you look to the code of AndroidApplicationConfiguration.java, you'll notice at lines 30 and 31 this code :

    /** number of bits per color channel **/
    public int r = 5, g = 6, b = 5, a = 0;

Thus, Android applications with libGDX render, by default, low bit images. This can be easily modified in the AndroidLauncher.java of your application.

The default AndroidLauncher.java of your app looks like this :

    public class AndroidLauncher extends AndroidApplication {
        @Override
        protected void onCreate (Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
            initialize(new MyGdxGame(), config);
        }
    }

All you have to do, to have a render format of RGBA8888 for your Android app is :

    public class AndroidLauncher extends AndroidApplication {
        @Override
        protected void onCreate (Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
            config.r = 8;
            config.g = 8;
            config.b = 8;
            config.a = 8;
            initialize(new MyGdxGame(), config);
        }
    }

Et voilà ! Here is a comparative screenshot of Android RGB565 VS Android RGBA8888 VS Desktop : image1

You can see that the Android RGBA8888 is very close to the desktop version.