2016-05-27 3 views
0

У меня есть видео, которое выглядит следующим образом:Rendering шесть видео текстур на кубе с помощью Three.js

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> 

Как вы можете видеть, я использовал УФ отображение на карте шесть различных частей видео на шести граней куба.

Три-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(); 
} 

Все, что не работает. Вот как выглядит моя веб-страница (в хромированном виде):

The output on the webpage На вкладке «Консоль» нет ошибок.

Пожалуйста, дайте мне знать, где я буду не так. Я только начинаю с three.js, и любая помощь будет оценена. Спасибо!

ответ

1

Here's my demo.

По существу, я проверил mrdoob's пример на github и украл, пока все не сработало.

Главное изменение имело элемент видеоизображения 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-координатами, чтобы сделать ваш код более гибким.

Проводка кода была хорошей, но я знаю, что публикация рабочей демонстрации, либо bl.ock, либо jsfiddle, либо вашего собственного сервера, будет весьма полезна в будущем.

Я более запятнан цели из трех-tut.js. Насколько я могу судить, это делает zlich. Вернее, он определяет сцену с кубом, выталкивает визуализатор three.js на тело, а затем продолжает ничего не делать, кроме беспорядка с вашей сеткой куба видео (этот вызов renderAnimationFrame() заканчивается ссылкой на тот же mesh и так двойной молот - код вращения.) Все это не поможет вам с кубом видео.

+0

Вы обрезали видео sintel.mp4? Или это случилось? –

+0

Я ничего не сделал для mp4, просто использовал демонстрационный файл как есть, так что это может стать источником растяжения UV (т. Е. Не соответствует вашему соотношению сторон). Вы можете проверить его на [gist] (https://gist.github.com/user01/65cbe8f15fe6f338f709dbc1b311575f), если вы хотите проверить его на кодек, разрешения и т. П. – user01

+0

Спасибо! Как мне с этим справиться? WebGL: INVALID_VALUE: texImage2D: нет видео [.CommandBufferContext] RENDER WARNING: текстура, привязанная к текстурной единице 0, не является рендерируемой. Это может быть не-power-of-2 и иметь несовместимую фильтрацию текстур. –

Смежные вопросы