Отрисовать блок с видео-контентом в three.js
Запись от 04.09.2015
Понадобилось разработать минимальный пример для отображения видео на плоскости в 3D.
За основу взял этот пример: http://threejs.org/examples/#webgl_ma...ials_video
Для поставленной задачи, он оказался достаточно сложным (слева пример, справа, то что требовалось):
Сразу, вот исходный код: https://github.com/Dok11/three.js-video-simple
Разберемся по порядку, что к чему:
Теперь разберем функцию инициализации:
Стоит обратить внимание, что угол обзора камеры 40 градусов, а её удаление от "центра 3D мира" 500 единиц по оси Z.
Стоит обратить внимание на свойство antialias, которое должно сглаживать края объектов.
Также к материалу необходимо задать свойства hue и saturation. На сколько я понял, ноль - это нейтральное положение для них. Что по умолчанию - не знаю, но если не установить эти свойства, объект мы не увидим.
Еще одна важная вещь - тип установки материала MeshBasicMaterial - он не учитывает внешнее освещение, то есть, если задать источник света, то на этом материале мы не увидим эффектов типа specular и т.п. Но и если не задавать источников света объект не будет черным.
И добавление объекта на сцену.
Как я мог догадаться, этот код забирает видео-поток из <video> и транслирует его в материал.
Содержимое самих функций рассматривать не буду, они не столь важны для примера, да и в целом достаточно просты.
P.S. Категорически приветствую ваши комментарии и критику.
За основу взял этот пример: http://threejs.org/examples/#webgl_ma...ials_video
Для поставленной задачи, он оказался достаточно сложным (слева пример, справа, то что требовалось):
Сразу, вот исходный код: https://github.com/Dok11/three.js-video-simple
Разберемся по порядку, что к чему:
<script src="js/three.min.js"></sc ript>
<script src="js/shaders/ConvolutionShader.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/Detector.js"></script>
Здесь подключаем стандартные библиотеки на 400+ Кб, в gzip около 100 Кб.<video id="video" autoplay loop style="display:none">
<source src="textures/sintel.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<source src="textures/sintel.ogv" type='video/ogg; codecs="theora, vorbis"'>
</video>
Это HTML5 тег с видео, которое будет проигрываться в нашем объекте. if(!Detector.webgl) Detector.addGetWebGLMessage();
var container;
var camera, scene, renderer;
var video, texture, material, mesh;
var composer;
var mouseX = 0;
var mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
Здесь определили необходимые переменные для работы сцены.init();
animate();
Запуск инициализации сцены и анимаций.Теперь разберем функцию инициализации:
container = document.createElement( 'div' );
document.body.appendChild( container );
Этот код создает div для сцены (canvas). camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 500;
Здесь создается камера из которой мы будем наблюдать за 3D миром. Стоит обратить внимание, что угол обзора камеры 40 градусов, а её удаление от "центра 3D мира" 500 единиц по оси Z.
scene = new THREE.Scene();
В переменной scene сохраняем объект сцены - в нем будет происходить отрисовка мира.renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
Создание объекта для рендера и установка его свойств и размеров. Стоит обратить внимание на свойство antialias, которое должно сглаживать края объектов.
video = document.getElementById('video');
texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
На основе HTML5 тега <video> создается материал (текстура) для будущего объекта с необходимыми свойствами (их минимальный набор).var geometry;
var parameters = {color: 0xffffff, map: texture};
geometry = new THREE.BoxGeometry(480, 204, 0.01);
material = new THREE.MeshBasicMaterial(parameters);
material.hue = 0;
material.saturation = 0;
Здесь создается объект геометрии с материалом видео-записью. Также к материалу необходимо задать свойства hue и saturation. На сколько я понял, ноль - это нейтральное положение для них. Что по умолчанию - не знаю, но если не установить эти свойства, объект мы не увидим.
Еще одна важная вещь - тип установки материала MeshBasicMaterial - он не учитывает внешнее освещение, то есть, если задать источник света, то на этом материале мы не увидим эффектов типа specular и т.п. Но и если не задавать источников света объект не будет черным.
mesh = new THREE.Mesh(geometry, material);
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 0.6;
scene.add( mesh );
На основе созданных ранее объектов создается форма объекта, указывается размещение в пространстве xyz, а также масштаб 0.6. И добавление объекта на сцену.
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
Этой строкой задается функция, вращающая сцену, при перемещении курсора мыши.// postprocessing
var renderModel = new THREE.RenderPass( scene, camera );
var effectCopy = new THREE.ShaderPass( THREE.CopyShader );
effectCopy.renderToScreen = true;
composer = new THREE.EffectComposer( renderer );
composer.addPass( renderModel );
composer.addPass( effectCopy );
На мой взгляд, самая сложная часть кода в плане понимания. Как я мог догадаться, этот код забирает видео-поток из <video> и транслирует его в материал.
window.addEventListener( 'resize', onWindowResize, false );
Эта функция меняет размер сцены, при ресайзе окна. Содержимое самих функций рассматривать не буду, они не столь важны для примера, да и в целом достаточно просты.
P.S. Категорически приветствую ваши комментарии и критику.