缩放视频纹理与图像纹理混合

时间:2021-06-24 19:08:44

标签: javascript glsl webgl textures

我尝试过搜索,这是一件微不足道的事情,但无法弄清楚,我看了很多答案,但从未用完整的工作示例回答我需要的内容。

我正在尝试在片段着色器中缩放视频纹理,并在背景中使用图像纹理。所以不能变换顶点。视频纹理需要调整为 200 x 200 并放置在顶角或底角。

它最终将使用 MediaStream 作为网络摄像头,具有透明背景效果。它与图像纹理顶部的 bodypix 一起使用,使用混合着色器,但需要缩放视频,使其不会拉伸到视口。

如果我尝试使用 vec2(200,200) 的 vec2,clamp 将拉伸其余颜色。重复将平铺它。这些都不是预期的结果。

视频渲染的 Jsfiddle 但需要调整它的大小。

https://jsfiddle.net/danrossi303/or3dk2q4/16/

我正在使用的基本片段着色器。

  precision mediump float;

 uniform sampler2D background;
 uniform sampler2D frame;

uniform float texWidth;
uniform float texHeight;


void main(void) {
vec2 texCoord = gl_FragCoord.xy / vec2(texWidth,texHeight);

vec4 texel0 = texture2D(background, texCoord);
vec4 texel1 = texture2D(frame, texCoord);
 gl_FragColor = mix(texel0, texel1, 1.);
}

1 个答案:

答案 0 :(得分:0)

您需要缩放视频的纹理坐标:

vec2 frameuv = texCoord * vec2(texWidth, texHeight) / vec2(200.0, 200.0);
vec4 texel1 = texture2D(frame, frameuv);

如果 texel1frameuv.x 大于 1.0,则丢弃框架 (frameuv.y)(参见 step):

float w = step(frameuv.x, 1.0) * step(frameuv.y, 1.0);
gl_FragColor = mix(texel0, texel1, w);

完整的片段着色器:

precision mediump float;
  
uniform sampler2D background;
uniform sampler2D frame;

uniform float texWidth;
uniform float texHeight;

void main(void) {
    vec2 texCoord = gl_FragCoord.xy / vec2(texWidth,texHeight);
   
    vec4 texel0 = texture2D(background, texCoord);
    vec2 frameuv = texCoord * vec2(texWidth, texHeight) / vec2(200.0, 200.0);
    vec4 texel1 = texture2D(frame, frameuv);
    gl_FragColor = mix(texel0, texel1, step(frameuv.x, 1.0) * step(frameuv.y, 1.0));
}

此外,加载背景纹理时还有一个错误。 gl.bindTexture 将纹理对象绑定到当前纹理单元。在调用 gl.activeTexture 之前,必须使用 gl.bindTexture 设置纹理单元:

img.onload = () => {
    gl.activeTexture(gl.TEXTURE0);            // <---
    gl.bindTexture(gl.TEXTURE_2D, texture);
    initBackgroundTexture();
};
img.src = "https://videos.electroteque.org/textures/virtualbg.jpg";