同时显示视频元素的多个帧

时间:2011-10-04 23:09:58

标签: javascript glsl webgl three.js

一些背景:这里的图形新手,刚刚在浏览器中用mrdoob的优秀three.js将我的脚趾浸入3D世界。我打算尽快通过http://learningwebgl.com/的所有内容:)


我想知道如何重新创建类似于以下内容的内容: http://yooouuutuuube.com/v/?width=192&height=120&vm=29755443&flux=0&direction=rand

我对yooouuutuuube如何运作的天真理解如下:

  1. 创建一个大规模的BitmapData(大于任何合理的浏览器窗口大小)。
  2. 根据目标视频帧的宽度/高度确定所需行/列的数量(在整个BitmapData平面上,而不仅仅是可见区域)
  3. 将最近视频帧中的像素复制到BitmapData上的位置(基于移动方向)
  4. 遍历BitmapData中的每个单元格,从其前面的单元格中复制像素
  5. 以相反的方向滚动整个BitmapData以创建运动错觉,具有Zoetrope类型的效果
  6. 我想在WebGL中执行此操作而不是使用Canvas,因此我可以利用着色器进行后处理(噪声和颜色通道分离以模拟色差)。

    以下是我到目前为止的截图:

    enter image description here

    • 三个视频(相同的视频,但分为R,G和B通道)被绘制到画布2D上下文。每个视频稍微偏移,以伪造色差外观。
    • 在Three.JS中创建一个引用此画布的纹理。每个绘制周期都会更新此纹理。
    • 在Three.JS中创建着色器材质,该材质链接到片段着色器(创建噪声/扫描线)
    • 然后将此材质应用于多个3D平面。

    这适用于显示单帧视频,但我想看看是否可以一次显示多个帧而无需添加其他几何体。

    执行此类任务的最佳方式是什么?我是否应该更详细地研究/调查这些概念?

1 个答案:

答案 0 :(得分:4)

<html>
    <body>
        <script>

            var video = document.createElement( 'video' );
            video.autoplay = true;
            video.addEventListener( 'loadedmetadata', function ( event ) {

                var scale = 0.5;
                var width = video.videoWidth * scale;
                var height = video.videoHeight * scale;
                var items_total = ( window.innerWidth * window.innerHeight ) / ( width * height );

                for ( var i = 0; i < items_total - 1; i ++ ) {

                    var canvas = document.createElement( 'canvas' );
                    canvas.width = width;
                    canvas.height = height;

                    canvas.context = canvas.getContext( '2d' );
                    canvas.context.scale( scale, scale );

                    document.body.appendChild( canvas );

                }

                setInterval( function () {

                    var child = document.body.insertBefore( document.body.lastChild, document.body.children[ 1 ] ); // children[ 0 ] == <script>
                    child.context.drawImage( video, 0, 0 );

                }, 1000 / 30 );

            }, false );
            video.src = 'video.ogv';

        </script>
    </body>
</html>