SSISO Community

시소당

OpenGL ES Shader to outline 2D images

Would you accept an edge detection filter (such as Sobel), producing an image like that shown in the Wikipedia article, followed by a Gaussian blur on the results of that to soften the edges and give it more of a glow, then composite that image onto your scene?

In practice you could probably just reuse the 3d outlining shaders you've seen — although you could in theory inspect depth quantities (with some extended effort in ES), every one I've ever seen was just a 2d effect on the rendered image.

EDIT: on further consideration, the Laplacian may be a little easier to apply than the Sobel because it can be done as a simple convolution shaders (as described in places like this). Though to be safe on mobile you possibly want to stick to 3x3 kernels at most and write a different shader for each effect rather than doing it with data. So e.g. a rough Gaussian blur, written out at length:

void main()
{
    mediump vec4 total = vec4(0.0);
    mediump vec4 grabPixel;

    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 1.0 / height));

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, -1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, 1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel = texture2D(tex2D, texCoordVarying);
    total += grabPixel * 4.0;

    total *= 1.0 / 16.0;

    gl_FragColor = total;
}

And a Laplacian edge detect ends up looking similar but with different constants.

As an optimisation, you should work out your relative sampling points in the vertex shader rather than in the fragment shader as far as possible given the limit on varyings, as doing so will avoid dependent texture reads.

209 view

4.0 stars