OpenGL ES 2.0中的抗锯齿?

Viv*_*vam 5 android opengl-es irrlicht ios opengl-es-2.0

有没有办法在OpenGL ES 2.0中实现Anitaliasing技术?我已经护目镜并找到了一些方法,但输出没有变化.

在最糟糕的情况下,我计划通过显示每个像素周围像素的平均颜色来实现多次传递渲染,以平滑片段着色器中的边缘,但是它需要更高的GPU性能.

有什么建议 ?

Ret*_*adi 21

许多设备都支持MSAA(多样本抗锯齿).要利用此功能,您必须选择EGLConfig具有多重采样的功能.

在Android上,如果使用GLSurfaceView,则必须实现自己的EGLConfigChooser.然后,您可以使用EGL函数,尤其eglChooseConfig()是查找您喜欢的配置.

以下代码未经测试,但至少应该草拟如何实现.在GLSurfaceView派生类的构造函数中,调用之前setRenderer(),添加:

setEGLConfigChooser(new MyConfigChooser());
Run Code Online (Sandbox Code Playgroud)

然后实施MyConfigChooser.你可以在你的内部使这成为一个嵌套类GLSurfaceView:

class MyConfigChooser implements GLSurfaceView.EGLConfigChooser {
    @Override
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        int attribs[] = {
            EGL10.EGL_LEVEL, 0,
            EGL10.EGL_RENDERABLE_TYPE, 4,  // EGL_OPENGL_ES2_BIT
            EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER,
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_DEPTH_SIZE, 16,
            EGL10.EGL_SAMPLE_BUFFERS, 1,
            EGL10.EGL_SAMPLES, 4,  // This is for 4x MSAA.
            EGL10.EGL_NONE
        };
        EGLConfig[] configs = new EGLConfig[1];
        int[] configCounts = new int[1];
        egl.eglChooseConfig(display, attribs, configs, 1, configCounts);

        if (configCounts[0] == 0) {
            // Failed! Error handling.
            return null;
        } else {
            return configs[0];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您显然希望替换配置所需的特定值.实际上,eglChooseConfig()使用一小组严格必要的属性调用它会更加健壮,让它枚举与这些属性匹配的所有配置,然后实现自己的逻辑以选择其中最好的.已定义的行为eglChooseConfig()已经很奇怪了(参见文档),并且没有人知道GPU供应商是如何实现它的.

在iOS上,您可以在您的上设置此属性GLKView以启用4x MSAA:

[view setDrawableMultisample: GLKViewDrawableMultisample4X];
Run Code Online (Sandbox Code Playgroud)

您可以考虑其他抗锯齿方法:

  • 超级采样:渲染到每个方向上最终渲染表面大小(通常是两倍)的纹理,然后对其进行下采样.这会占用大量内存,而且开销很大.但如果它符合您的性能要求,质量将非常出色.
  • 旧学校:使用轻微偏移多次渲染帧,并对帧进行平均.这通常是在OpenGL早期使用累积缓冲区完成的.累积缓冲区已过时,但您可以对FBO执行相同的操作.有关方法的说明,请参阅原始红皮书中 "The Framebuffer"下的"场景抗锯齿"部分.