5

I'm trying to achieve the following blending when the texture at one vertex merges with another:

Image drawn in Paper iPad App by FiftyThree

Here's what I currently have:

enter image description here

I've enabled blending and am specifying the blending function as:

    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

I can see that the image drawn in the paper app is made up of a small circle that merges with the same texture before and after and has some blending effect on the color and the alpha.

How do I achieve the desired effect?

UPDATE:

What I think is happening is that the intersected region of the two textures is getting the alpha channel to be modified (either additive or some other custom function) while the texture is not being drawn in the intersected region. The rest of the region has the rest of the texture drawn. Like so:

enter image description here

I'm not entirely sure of how to achieve this result, though.

kajham
  • 1,241
  • 15
  • 19

2 Answers2

1

You shouldn't need blending for this (and it won't work the way you want).

I think as long as you define your texture coordinate in the screen space, it should be seamless between two separate circles.

To do this, instead of using a texture coordinate passed through the vertex shader, just use the position of the fragment to sample the texture, plus or minus some scaling:

float texcoord = gl_FragCoord / vec2(xresolution_in_pixels, yresolution_in_pixels);`
gl_FragColor = glTexture2D(papertexture, texcoord);

If you don't have access to GLSL, you could do something instead with the stencil buffer. Just draw all your circles into the stencil buffer, use the combined region as a stencil mask, and then draw a fullscreen quad of your texture. The color will be seamlessly deposited at the union of all the circles.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • Hmm - I dont think I completely understand the solution :(. Given that I'm creating an iOS app to support openGL ES 1.1, I'd have to stick to stencil buffers since I don't have access to GLSL. Secondly, what I'm trying to do is avoid the edges from showing up as overlapping, but instead, show up as a smooth stroke, as you would if you painted. How would drawing a fullscreen quad of the texture solve this problem? – kajham Jul 18 '12 at 00:17
  • It seems to be that the intersection of two textures has additive or an average of the alpha for the pixel data already in the intersected region, but there is no texture drawn over the intersected region. Instead, the remaining of the texture is drawn in the unintersecting region. – kajham Jul 18 '12 at 01:12
  • 1
    @kajham : the purpose of the stencil buffer is to create a mask over the entire area that you wish to be textured. When you're using the stencil buffer, every time you draw a shape, every pixel that it covers will be marked in the stencil buffer. Then once you've drawn all your circles, the stencil buffer will contain an outline of the intersection of all the circles. You can then use this outline to mask the full screen quad, which contains your texture. After drawing this quad, only the area covered by the stencil will be drawn. – Tim Jul 18 '12 at 04:13
  • Thanks so much! This makes total sense. I was able to use a stencil buffer to ensure that dont draw over a region where there's already something drawn. This helped ensure that I was not overlapping textures. One thing that I have not been able to figure out is how to alter just the alpha of the texture already drawn. Is this possible in openGL ES 1.1? It seems to me that its being done in the paper app (screenshot above) using pixel shaders. – kajham Jul 19 '12 at 23:36
1

You can achieve this effect with max blending for alpha. Or manual (blending off) with shader (OpenGL ES 2.0):

#extension GL_EXT_shader_framebuffer_fetch : require
precision highp float;

uniform sampler2D texture;
uniform vec4      color;

varying vec2 texCoords;

void main() {
    float res_a =gl_LastFragData[0].a;
    float a = texture2D(texture, texCoords).a;
    res_a = max(a, res_a);
    gl_FragColor = vec4(color.rgb * res_a, res_a);
}

Result:

enter image description here

George
  • 938
  • 3
  • 11
  • 34