【问题标题】:Rendering six video textures on a cube using three.js使用 three.js 在立方体上渲染六个视频纹理
【发布时间】:2016-09-26 07:59:40
【问题描述】:

我的视频如下所示:

Screenshot of the input video

您可能从视频的屏幕截图中可以看出,我将视频流分成了 6 个部分。

目标:我想将这 6 个视频投影到立方体的六个面上。为此,我编写了以下 JavaScript:

<!DOCTYPE html>
<html>
  <head>
    <title>WebGL/Three.js Step Tutorial</title>
        <style>
            body {
            margin: 0px;
            background-color: #fff;
            overflow: hidden;
        }
        </style>
  </head>
  <body>
    <script src="js/three.js"></script>
    <script src="js/three-tut.js"></script>
  </body>
</html>


    <script>


     var camera;
     var scene;
     var renderer;
     var mesh;


     init();
     animate();

     function init() {

         scene = new THREE.Scene();
         camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);

         var light = new THREE.DirectionalLight( 0xffffff );
         light.position.set( 0, 1, 1 ).normalize();
         scene.add(light);

         var geometry = new THREE.CubeGeometry( 10, 10, 10);


        var texture = new THREE.VideoTexture( 'videos/Input.mp4' );
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;
        texture.format = THREE.RGBFormat;

         var material = new THREE.MeshPhongMaterial( { map: texture } );

         var face1 = [new THREE.Vector2(0, .5), new THREE.Vector2(.3333, .5), new THREE.Vector2(.3333, 1), new THREE.Vector2(0, 1)];
         var face2 = [new THREE.Vector2(.3333, .5), new THREE.Vector2(.6666, .5), new THREE.Vector2(.6666, 1), new THREE.Vector2(.3333, 1)];
         var face3 = [new THREE.Vector2(.6666, .5), new THREE.Vector2(1, .5), new THREE.Vector2(1, 1), new THREE.Vector2(.6666, 1)];
         var face4 = [new THREE.Vector2(0, 0), new THREE.Vector2(.3333, 0), new THREE.Vector2(.3333, .5), new THREE.Vector2(0, .5)];
         var face5 = [new THREE.Vector2(.3333, 0), new THREE.Vector2(.6666, 0), new THREE.Vector2(.6666, .5), new THREE.Vector2(.3333, .5)];
         var face6 = [new THREE.Vector2(.6666, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, .5), new THREE.Vector2(.6666, .5)];

         geometry.faceVertexUvs[0] = [];

             geometry.faceVertexUvs[0][0] = [ face1[0], face1[1], face1[3] ];
             geometry.faceVertexUvs[0][1] = [ face1[1], face1[2], face1[3] ];

             geometry.faceVertexUvs[0][2] = [ face2[0], face2[1], face2[3] ];
             geometry.faceVertexUvs[0][3] = [ face2[1], face2[2], face2[3] ];

             geometry.faceVertexUvs[0][4] = [ face3[0], face3[1], face3[3] ];
             geometry.faceVertexUvs[0][5] = [ face3[1], face3[2], face3[3] ];

             geometry.faceVertexUvs[0][6] = [ face4[0], face4[1], face4[3] ];
             geometry.faceVertexUvs[0][7] = [ face4[1], face4[2], face4[3] ];

            geometry.faceVertexUvs[0][8] = [ face5[0], face5[1], face5[3] ];
             geometry.faceVertexUvs[0][9] = [ face5[1], face5[2], face5[3] ];

             geometry.faceVertexUvs[0][10] = [ face6[0], face6[1], face6[3] ];
             geometry.faceVertexUvs[0][11] = [ face6[1], face6[2], face6[3] ];

         mesh = new THREE.Mesh(geometry,  material);
         mesh.position.z = -50;
         scene.add( mesh );

         renderer = new THREE.WebGLRenderer();
         renderer.setSize( window.innerWidth, window.innerHeight );
         document.body.appendChild( renderer.domElement );

         window.addEventListener( 'resize', onWindowResize, false );

         render();
     }

     function animate() {
         mesh.rotation.x += .04;
         mesh.rotation.y += .02;

         render();
         requestAnimationFrame( animate );
     }

     function render() {
         renderer.render( scene, camera );
     }


     function onWindowResize() {
         camera.aspect = window.innerWidth / window.innerHeight;
         camera.updateProjectionMatrix();
         renderer.setSize( window.innerWidth, window.innerHeight );
         render();
     }

</script>

如您所见,我使用 UV 映射将视频的六个不同部分映射到立方体的六个面上。

三个tut.js文件(上面代码中提到的)是这样的:

 var camera;
 var scene;
 var renderer;
 var mesh;

 init();
 animate();

 function init() {

     scene = new THREE.Scene();
     camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);

     var light = new THREE.DirectionalLight( 0xffffff );
     light.position.set( 0, 1, 1 ).normalize();
     scene.add(light);

     var geometry = new THREE.CubeGeometry( 10, 10, 10);
     var material = new THREE.MeshPhongMaterial( { color: 0x0033ff, specular: 0x555555, shininess: 30 } );

     mesh = new THREE.Mesh(geometry, material );
     mesh.position.z = -50;
     scene.add( mesh );

     renderer = new THREE.WebGLRenderer();
     renderer.setSize( window.innerWidth, window.innerHeight );
     document.body.appendChild( renderer.domElement );

     window.addEventListener( 'resize', onWindowResize, false );

     render();
 }

 function animate() {
     mesh.rotation.x += .03;
     mesh.rotation.y += .03;

     render();
     requestAnimationFrame( animate );
 }

 function render() {
     renderer.render( scene, camera );
 }


 function onWindowResize() {
     camera.aspect = window.innerWidth / window.innerHeight;
     camera.updateProjectionMatrix();
     renderer.setSize( window.innerWidth, window.innerHeight );
     render();
 }

整个事情都不起作用。这是我的网页(在 chrome 中)的样子:

The output on the webpage “控制台”选项卡中没有错误。

请让我知道我哪里出错了。 我只是三个.js 的开始,任何形式的帮助都将不胜感激。 谢谢!

【问题讨论】:

    标签: javascript 3d three.js textures


    【解决方案1】:

    Here's my demo.

    基本上,我在github 上查看了mrdoob's 的示例并偷偷摸摸,直到一切正常为止。

    主要的变化是有一个display:none html 视频元素来播放实际的视频(没有深入研究three.js 代码,我假设传递一个url 应该可以即时执行此操作,或者类似的效果。 You could do that too,如果您需要js代码中的所有内容。)

    <video id="video" autoplay loop style="display:none">
      <source src="sintel.mp4" type='video/mp4'>
    </video>
    

    然后在js代码中引用:

    video = document.getElementById( 'video' );
    videoTexture = new THREE.VideoTexture(video);
    

    你如何在立方体上手动编码 UV,但它确实有效。您可能需要考虑导入具有 UV 坐标的网格,以使您的代码更加灵活。

    发布代码很好,但我知道发布一个工作演示,无论是 bl.ock 还是 jsfiddle 或您自己的服务器,将来都会很有帮助。

    three-tut.js 的用途让我更加困惑。据我所知,zlich 确实如此。或者更确切地说,它定义了一个带有立方体的场景,将 three.js 渲染器推到主体上,然后什么都不做,除了弄乱您的视频立方体网格(该 renderAnimationFrame() 调用最终引用相同的 mesh所以双锤旋转代码。)整件事对视频立方体没有帮助。

    【讨论】:

    • 您是否裁剪了 sintel.mp4 视频?还是以某种方式发生的?
    • 我没有对 mp4 做任何事情,只是按原样使用演示文件,因此这可能是 UV 拉伸的来源(即,与您的纵横比不匹配)。如果您想检查它的编解码器、分辨率等,您可以在gist 上查看它。
    • 谢谢!我该如何处理? WebGL:INVALID_VALUE:texImage2D:无视频 [.CommandBufferContext]RENDER WARNING:绑定到纹理单元 0 的纹理不可渲染。它可能不是 2 的幂并且具有不兼容的纹理过滤。
    • 很难说没有更多信息。您确定视频正在加载到元素中吗?你能发布一个你当前状态的演示吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 2017-01-18
    • 2012-11-19
    • 1970-01-01
    • 2014-05-06
    相关资源
    最近更新 更多