How do I blend two textures with different co-ordi

2020-02-09 11:19发布

问题:

I can blend two textures with different blending modes in the fragment shader when both the textures covers the same rectangles. But now my problem is, one texture is a plain rectangle with no rotation and the other texture is another rectangle with a rotation/scale and translation. How do I merge these textures in the way I want? (In the picture)

I know how to do this...

But not sure how to do this...

For blending textures in one rectangle (the first image), I used the following code..

Objective C code...

- (void) display {
    [EAGLContext setCurrentContext:context];

    glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);

    glUseProgram(program);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, textureTop);

    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, textureBot);

    glUniform1i(inputTextureTop, 2);
    glUniform1i(inputTextureBot, 3);

    glUniform1f(alphaTop, alpha);

    glEnable (GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glVertexAttribPointer(position, 2, GL_FLOAT, 0, 0, imageVertices);
    glVertexAttribPointer(inputTextureCoordinate, 2, GL_FLOAT, 0, 0, textureCoordinates);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER];
}

Vertex shader...

 attribute vec4 position;
 attribute vec4 inputTextureCoordinate;

 varying vec2 textureCoordinate;

 void main()
 {
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
 }

Fragment shader...

varying highp vec2 textureCoordinate;

uniform sampler2D inputTextureTop;
uniform sampler2D inputTextureBot;

uniform highp float alphaTop;

void main()
{
    lowp vec4 pixelTop = texture2D(inputTextureTop, textureCoordinate);
    lowp vec4 pixelBot = texture2D(inputTextureBot, textureCoordinate);

    gl_FragColor = someBlendOperation(pixelTop, pixelBot);
}

回答1:

You have to pass 2 texture coordinates to shader and modify shader

Add to ObjectiveC

glVertexAttribPointer(inputTextureCoordinate2, 2, GL_FLOAT, 0, 0, textureCoordinates2);

Vertex Shader

attribute vec4 position;
attribute vec4 inputTextureCoordinate;
attribute vec4 inputTextureCoordinate2;

varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
    textureCoordinate2 = inputTextureCoordinate2.xy;
}

Frag Shader

varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;

uniform sampler2D inputTextureTop;
uniform sampler2D inputTextureBot;

uniform highp float alphaTop;

void main()
{
    lowp vec4 pixelTop = texture2D(inputTextureTop, textureCoordinate);
    lowp vec4 pixelBot = texture2D(inputTextureBot, textureCoordinate2);

    gl_FragColor = someBlendOperation(pixelTop, pixelBot);
}

BTW inputTextureCoordinate is not necessary to be vec4 but it could be vec2



回答2:

If you're blending two textures on the same primitive, then you can mix the colors in the shader.

However if you want to blend two different primitives, then what you really just want to use is hardware blending (GL_BLEND).

Draw the bottom picture by itself, then enable blending and draw the top picture. The alpha value of the top picture controls how transparent it will be.

You don't really want to try to draw both quads in the same draw call, since they don't use the same coordinates.