Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

android - Antialiasing in OpenGL ES 2.0?

Is there a way to implement Antialiasing technique in OpenGL ES 2.0? I have goggled and found few methods but there was no change in the output.

In the worst case, I've planned to implement multiple pass rendering, to smooth the edges in fragment shader, by displaying average colour of the pixels around every pixel, but it costs more GPU performance.

Any suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A lot of devices support MSAA (Multi-Sample Anti-Aliasing). To take advantage of this feature, you have to choose a EGLConfig that has multisampling.

On Android, if you use GLSurfaceView, you will have to implement your own EGLConfigChooser. You can then use EGL functions, particularly eglChooseConfig() to find a config you like.

The following code is untested, but it should at least sketch how this can be implemented. In the constructor of your GLSurfaceView derived class, before calling setRenderer(), add:

setEGLConfigChooser(new MyConfigChooser());

Then implement MyConfigChooser. You can make this a nested class inside your 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];
        }
    }
}

You will obviously want to substitute the specific values you need for your configuration. In reality, it's much more robust to call eglChooseConfig() with a small set of strictly necessary attributes, let it enumerate all configs that match those attributes, and then implement your own logic to choose the best among them. The defined behavior of eglChooseConfig() is kind of odd already (see documentation), and there's no telling how GPU vendors implement it.

On iOS, you can set this property on your GLKView to enable 4x MSAA:

[view setDrawableMultisample: GLKViewDrawableMultisample4X];

There are other antialiasing approaches you can consider:

  • Supersampling: Render to a texture that is a multiple (typically twice) the size of your final render surface in each direction, and then downsample it. This uses a lot of memory, and the overhead is substantial. But if it meets your performance requirements, the quality will be excellent.
  • Old school: Render the frame multiple times with slight offsets, and average the frames. This was commonly done with the accumulation buffer in the early days of OpenGL. The accumulation buffer is obsolete, but you can do the same thing with FBOs. See the section "Scene Antialiasing" under "The Framebuffer" in the original Red Book for a description of the method.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...