Android 具有硬件加速 OpenGL ES 3.0 的模拟器色带

Android Emulator Color Banding with Hardware Acceleration OpenGL ES 3.0

只有在我的 Android 模拟器上使用硬件加速渲染时,我似乎才在色谱的低端失去相当大的精度。

使用硬件加速(ANGLE D3D11 或桌面原生 OpenGL):

没有硬件加速(SwiftShader):

条带显然是非线性的,在尝试渲染平滑光照时变得相当突兀。

我已经设置 getWindow().setFormat(PixelFormat.RGBA_8888); 并在我的片段着色器中使用 precision highp float;

我们使用 Android Studio 3.1.1,Windows 10,OpenGL ES 3.0。

*编辑:这是亮度和对比度增加的并排图

这看起来像是 sRGB 颜色在某个时候以线性 8 位格式存储,然后被转换回 sRGB。它会导致您所观察到的那种低亮度不精确。

调用时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。这需要存在 EGL_KHR_gl_colorspace 扩展名。

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);
  }
}

如果您想了解有关 sRGB 的更多信息,这里有一个很好的post:http://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/