Reputation: 445
I seem to be loosing considerable precision toward the lower end of the color spectrum only when using hardware accelerated rendering on my Android emulator.
With hardware acceleration (ANGLE D3D11 or Desktop Native OpenGL):
Without hardware acceleration (SwiftShader):
The banding is clearly non linear and becomes quite obtrusive when trying to render smooth lighting.
I've set getWindow().setFormat(PixelFormat.RGBA_8888);
and am using precision highp float;
in my fragment shader.
This us using Android Studio 3.1.1, Windows 10, OpenGL ES 3.0.
*Edit: Here's a side by side with increased brightness and contrast
Upvotes: 2
Views: 928
Reputation: 4325
This looks like sRGB colors are being stored in a linear 8-bit format at some point, then are converted back to sRGB. It would lead to exactly the kind of low-brightness imprecision you are observing.
When calling eglCreateWindowSurface, try passing {EGL_COLORSPACE_KHR, EGL_COLORSPACE_SRGB_KHR, EGL_NONE}
in the attrib_list
parameter. If you are using GLSurfaceView
, this will require implementing EGLWindowSurfaceFactory
and calling setEGLWindowSurfaceFactory
. This requires the EGL_KHR_gl_colorspace
extension to be present.
public class EGLFactory implements GLSurfaceView.EGLWindowSurfaceFactory {
private static final int EGL_GL_COLORSPACE_KHR = 0x309D;
private static final int EGL_GL_COLORSPACE_SRGB_KHR = 0x3089;
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
final int[] attribList = {
EGL_GL_COLORSPACE_KHR,
EGL_GL_COLORSPACE_SRGB_KHR,
EGL10.EGL_NONE
};
return egl.eglCreateWindowSurface(display, config, nativeWindow, attribList);
}
public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
egl.eglDestroySurface(display, surface);
}
}
Here is a good post if you want to learn more about sRGB: http://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/
Upvotes: 1