我尝试过搜索,这是一件微不足道的事情,但无法弄清楚,我看了很多答案,但从未用完整的工作示例回答我需要的内容。
我正在尝试在片段着色器中缩放视频纹理,并在背景中使用图像纹理。所以不能变换顶点。视频纹理需要调整为 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.);
}
答案 0 :(得分:0)
您需要缩放视频的纹理坐标:
vec2 frameuv = texCoord * vec2(texWidth, texHeight) / vec2(200.0, 200.0);
vec4 texel1 = texture2D(frame, frameuv);
如果 texel1
或 frameuv.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";