Как использовать масштаб и положение GLSL вместе с VideoContext? - PullRequest
1 голос
/ 05 апреля 2019

У меня есть интересная проблема с библиотекой VideoContext .

Я пытаюсь применить glsl Scale к мультимедиа, что работает нормально, но когда я затем впоследствии использую эффект Position, я обнаруживаю, что мультимедиа затем «обрезается» вверху, показывая черный фоновый цвет, делая своего рода «черная полоса» в верхней части СМИ. Пожалуйста, посмотрите на проблемную область, обведенную красным здесь:

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();
...