WebGL着色器中如何调整带遮罩缩放视频纹理在背景图上的显示位置
解决方案
核心逻辑说明
当前代码默认将200x200尺寸的视频纹理渲染在画布左下角,是因为WebGL坐标系y轴从下往上递增,原frameuv的计算逻辑直接将画布像素坐标除以200,仅当像素坐标在左下角200x200区间内时,frameuv落在[0,1]的有效采样范围内,其他区域会被step函数过滤不显示。
调整视频位置只需要修改frameuv的计算逻辑,先对像素坐标做偏移,再除以视频尺寸即可。
硬编码实现方案
右上角显示200x200视频
仅需要修改frameuv计算行即可,修改后的完整片段着色器如下:
precision mediump float; uniform sampler2D background; uniform sampler2D frame; uniform sampler2D mask; uniform float texWidth; uniform float texHeight; void main(void) { vec2 texCoord = gl_FragCoord.xy / vec2(texWidth,texHeight); // 右上角定位:x偏移为画布宽度减视频宽度,y偏移为画布高度减视频高度 vec2 frameuv = (gl_FragCoord.xy - vec2(texWidth - 200.0, texHeight - 200.0)) / vec2(200.0, 200.0); vec4 texel0 = texture2D(background, texCoord); vec4 frameTex = texture2D(frame, frameuv.xy); vec4 maskTex = texture2D(mask, frameuv.xy); // 增加负坐标过滤,避免采样异常 float show = step(0.0, frameuv.x) * step(frameuv.x, 1.0) * step(0.0, frameuv.y) * step(frameuv.y, 1.0) * maskTex.a * 255.; gl_FragColor = mix(texel0, frameTex, show); }
右下角显示200x200视频
仅修改frameuv计算行即可,替换为以下代码:
// 右下角定位:x偏移为画布宽度减视频宽度,y偏移为0 vec2 frameuv = (gl_FragCoord.xy - vec2(texWidth - 200.0, 0.0)) / vec2(200.0, 200.0);
后续优化建议
如果后续要改成可动态调整的uniform变量,只需要新增以下三个uniform变量,JS层动态传值即可:
frameWidth:视频渲染宽度offsetX:视频X轴偏移量offsetY:视频Y轴偏移量frameuv的通用计算逻辑为:
vec2 frameuv = (gl_FragCoord.xy - vec2(offsetX, offsetY)) / vec2(frameWidth, frameHeight);
内容的提问来源于stack exchange,提问作者Dan Rossi
相关产品推荐
相关产品推荐

