Images and mask in OpenGL ES 2.0

I am studying OpenGL ES 2.0 and I would like to create an application to better understand how it works. The application has a set of filters that the user can apply on images (I know, nothing new: P).

One of these filters takes two images and a mask and mixes the two images, displaying them through the mask (here the image better explains what I want to get)

enter image description here

I'm really confused at the moment, and I don't know where to start creating this effect. I canโ€™t understand that I need to work with several textures and several FrameBuffers, or I can just work with one shader.

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

EDIT --------

I found this solution, but when I use masks instead of circles as lines, the result is really โ€œgrungyโ€, especially if the lines rotate.

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

Perhaps it is better to use a stencil buffer or mix?

+8
source share
2 answers

You can apply the mask on a single line without using the expensive if :

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

Or itโ€™s better to simply interpolate between the 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 get less overlap. This will give very good results compared to a single threshold.

+12
source share

No need for multiple shaders or framebuffers, just a few texture blocks. Just use 3 texture units that are all indexed at the same texture coordinates and use the Mask texture to choose between two other textures. The fragment shader will 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 the third texture unit just for a binary test on the red channel is not very efficient, so it would be better to encode the mask into alpha channels of textures 1 or 2, but it should work, you started.

+1
source share

All Articles