为什么渲染此叠加层时会出现偏移?

时间:2017-01-13 15:02:16

标签: android opengl-es glsl fragment-shader vuforia

我使用Vuforia SDK在屏幕上呈现手机摄像头的视频流。

Phone's camera video stream on screen

所以纹理是由Vuforia库生成的,而不是我。

用于渲染此背景的着色器是:

// Vertex Shader
attribute vec4 a_position;
attribute vec2 a_textureCoords;
varying vec2 v_textureCoords;
uniform mat4 u_projectionMatrix;

void main()
{
    gl_Position = u_projectionMatrix * a_position;
    v_textureCoords = a_textureCoords;
}


// Fragment Shader
varying highp vec2 v_textureCoords;
uniform sampler2D u_currentTexture;

void main()
{
    vec4 currentColor = texture2D(u_currentTexture, v_textureCoords);
    gl_FragColor = currentColor;
}

现在,我希望在屏幕的左上角有一个叠加层:

Video stream with overlay in the upper-left corner

我不希望此叠加层仅显示粉红色纹理,而是显示粉红色纹理和背景纹理的 multiply blend 请注意,的纹理具有相同的坐标。

但是现在,让我们忘记混合,让我们在粉红色纹理的着色器程序中渲染背景纹理 。所以最后,是的,应该看到仅背景版本和带有叠加版本的bacground之间没有区别。

Overlay with offset

正如你所看到的(看看画面和椅子的顶部),有一个小偏移 ......

用于渲染叠加层的着色器是:

// Vertex Shader
attribute vec4 a_position;
attribute vec2 a_currentTextureCoords;
varying vec2 v_currentTextureCoords;

void main()
{
    gl_Position = a_position;
    v_currentTextureCoords = a_currentTextureCoords;
}


// Fragment Shader
varying highp vec2 v_currentTextureCoords;
uniform sampler2D u_currentTexture;
uniform sampler2D u_backgroundTexture;

void main()
{
    vec2 screenSize = vec2(1080.0, 1920.0);
    vec2 cameraResolution = vec2(720.0, 1280.0);
    vec2 texelSize = vec2(1.0 / screenSize.x, 1.0 / screenSize.y);
    vec2 scaleFactor = vec2(cameraResolution.x / screenSize.x, cameraResolution.y / screenSize.y);
    vec2 uv = gl_FragCoord.xy * texelSize * scaleFactor;
    uv = vec2(scaleFactor.y - uv.y, scaleFactor.x - uv.x);
    vec4 backgroundColor = texture2D(u_backgroundTexture, uv);

    gl_FragColor = backgroundColor;
}

我的计算错了吗?

1 个答案:

答案 0 :(得分:0)

为什么需要这条线?

uv = vec2(scaleFactor.y - uv.y, scaleFactor.x - uv.x);

不确定绝对纹理坐标与需要加法或减法的比例因子有什么算术关系......

P.S。它与您的问题无关,但如果您只使用该语言中的向量操作,则着色器将更短且更易于阅读。例如,替换:

vec2 scaleFactor = vec2(cameraResolution.x / screenSize.x, cameraResolution.y / screenSize.y);

...与......

vec2 scaleFactor = cameraResolution / screenSize;

只要矢量类型的长度相同,它就可以完全按照您的预期进行操作,但输入次数要少得多......