Images and mask in OpenGL ES 2.0

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-18 05:45:09

问题


I'm learning OpenGL ES 2.0 and I'd like to create an App to better understand how it works. The App has a set of filter that the user can apply on images (I know, nothing new :P).

One of this filter takes two images and a mask and it mixes the two images showing them through the mask (here an image to better explain what I want to obtain)

At the moment I'm really confused and I don't know where to start to create this effect. I can't understand wether I have to work with multiple textures and multiple FrameBuffers or I can just work with a single shader.

Do you have any hint to help me in doing this project?

EDIT--------

I've found this solution, but when I use as mask lines instead of circles the result is really "grungy", especially if lines are rotated.

precision highp float;

varying vec4 FragColor;
varying highp vec2 TexCoordOut;

uniform sampler2D textureA;
uniform sampler2D textureB;
uniform sampler2D mask;

void main(void){
    vec4 mask_color = texture2D(mask, TexCoordOut);

    if (mask_color.a > 0.0){
        gl_FragColor =  texture2D(textureA, TexCoordOut);
    }else {
        gl_FragColor =  texture2D(textureB, TexCoordOut);
    }
}

Is it probably better to use Stencil buffer or blending?


回答1:


You can apply the mask in one line without using the costly if:

gl_FragColor = step( 0.5, vMask.r ) * vColor_1 + ( 1.0 - step( 0.5, vMask.r ) ) * vColor_2;

Or, better just interpolate between two colors:

gl_FragColor = mix( vColor_1, vColor_2, vMask.r );

In this case the mask can be smoothed (i.e. with Gaussian blur) to produce less aliasing. This will yield very good results compared to a single value thresholding.




回答2:


There is no need for multiple shaders or framebuffers, just multiple texture units. Simply use 3 texture units which are all indexed by the same texture coordinates and use the Mask texture to select between the other two textures. The fragment shader would look like this:

uniform sampler2D uTextureUnit_1;
uniform sampler2D uTextureUnit_2;
uniform sampler2D uTextureMask;
varying vec2 vTextureCoordinates;

void main()
{
    vec4 vColor_1 = texture2D(uTextureUnit_1, vTextureCoordinates);
    vec4 vColor_2 = texture2D(uTextureUnit_2, vTextureCoordinates);
    vec4 vMask = texture2D(uTextureMask, vTextureCoordinates);

    if (vMask.r > 0.5)
        gl_FragColor = vColor_1;
    else
        gl_FragColor = vColor_2;
}

You can see that using a third texture unit just to do a binary test on the Red channel is not very efficient, so it would be better to encode the mask into the alpha channels of Textures 1 or 2, but this should get you started.



来源:https://stackoverflow.com/questions/18550226/images-and-mask-in-opengl-es-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!