如何将GLSL比例尺和位置与VideoContext一起使用?

时间:2019-04-05 20:05:27

标签: javascript canvas html5-video glsl webgl

VideoContext库有一个有趣的问题。

我正在尝试将glsl Scale应用于媒体,效果很好,但是当我随后使用“位置”效果时,我发现媒体随后被“截断”在顶部,露出黑色背景色,使得媒体顶部的“黑条”。请在此处看到问题区域用红色圆圈圈出:

enter image description here

对我来说,这似乎是一种奇怪的行为,因为我已经扩大了媒体规模。

我制作了一个CodePen来演示这里的问题:

https://codepen.io/kingpalethe/pen/xeVYLr?editors=0010

以下是此代码笔的所有JS:

const exampleMediaFile = {
    url: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/2831288/cars-4T1c8aZiOWDDZ-1N8KxDX49.mp4",
    width: 1280,
    height: 720,

}
const canvasDescription = {
    width: 1280,
    height: 720,
}


// scale effect
const scaleDescription = {
    title: "AAF Video Scale Effect",
    description: "A scale effect based on the AAF spec.",
    vertexShader: `
          attribute vec2 a_position;
          attribute vec2 a_texCoord;
          varying vec2 v_texCoord;
          void main() {
              gl_Position = vec4(vec2(2.0,2.0)*a_position-vec2(1.0, 1.0), 0.0, 1.0);
              v_texCoord = a_texCoord;
          }`,
    fragmentShader: `
          precision mediump float;
          uniform sampler2D u_image;
          uniform float scaleX;
          uniform float scaleY;
          varying vec2 v_texCoord;
          varying float v_progress;
          void main(){
              vec2 pos = vec2(v_texCoord[0]*1.0/scaleX - (1.0/scaleX/2.0 -0.5), v_texCoord[1]*1.0/scaleY - (1.0/scaleY/2.0 -0.5));
              vec4 color = texture2D(u_image, pos);
              if (pos[0] < 0.0 || pos[0] > 1.0 || pos[1] < 0.0 || pos[1] > 1.0){
                  color = vec4(0.0,0.0,0.0,0.0);
              }
            gl_FragColor = color;
          }`,
    properties: {
        scaleX: { type: "uniform", value: 1.0 },
        scaleY: { type: "uniform", value: 1.0 }
    },
    inputs: ["u_image"]
};

/// position effect

const positionDescription = {
    title: "AAF Video Position Effect",
    description: "A position effect based on the AAF spec.",
    vertexShader: `
        attribute vec2 a_position;
        attribute vec2 a_texCoord;
        varying vec2 v_texCoord;
        void main() {
            gl_Position = vec4(vec2(2.0,2.0)*a_position-vec2(1.0, 1.0), 0.0, 1.0);
            v_texCoord = a_texCoord;
        }`,
    fragmentShader: `
        precision mediump float;
        uniform sampler2D u_image;
        uniform float positionOffsetX;
        uniform float positionOffsetY;
        varying vec2 v_texCoord;
        varying float v_progress;
        void main(){
            vec2 pos = vec2(v_texCoord[0] - positionOffsetX/2.0, v_texCoord[1] -  positionOffsetY/2.0);
            vec4 color = texture2D(u_image, pos);
            if (pos[0] < 0.0 || pos[0] > 1.0 || pos[1] < 0.0 || pos[1] > 1.0){
                color = vec4(0.0,0.0,0.0,0.0);
            }
            gl_FragColor = color;
        }`,
    properties: {
      positionOffsetX: { type: "uniform", value: 0.0 },
      positionOffsetY: { type: "uniform", value: 0.0 }
    },
    inputs: ["u_image"]
  }; 


//Setup the video context.
var canvas = document.getElementById("canvas");
var ctx = new VideoContext(canvas);

//Create a video node
var videoNode = ctx.video(exampleMediaFile.url);

videoNode.start(0);
videoNode.stop(10);



/// ------------ SCALE

const scaleEffect = ctx.effect(scaleDescription);

scaleEffect.scaleX = 2  // this is 200% scale
scaleEffect.scaleY = 2  // this is 200% scale

/// ------------  POSITION

const positionEffect = ctx.effect(positionDescription);
positionEffect.positionOffsetX =  0
positionEffect.positionOffsetY =  -0.1 // this nudges the position slightly down


videoNode.connect(scaleEffect)
scaleEffect.connect(positionEffect)
positionEffect.connect(ctx.destination);


// you could play it if you wanted
// ctx.play();

0 个答案:

没有答案