Главная Новости

Обзор движка Verge3D - "убийцы" Blend4Web и Three.js


Опубликовано: 01.09.2018

Описание основных возможностей Verge3D for Blender, нового трёхмерного движка для создания web-приложений.

Verge3D это WebGL -движок, который мы, создатели аддона Blend4Web, делаем на замену этому "монстру". Основная идея Verge3D - предложить простое и легковесное решение, пригодное для массового применения в интернете: для онлайн магазинов, конфигураторов товаров, всяческих интерактивных презентаций и обучающих программ, ну и про игры забывать тоже не стоит.

Итак, чтобы не изобретать велосипед, в основу движка мы положили Three.js , наверное, самый популярный движок для WebGL (второй не менее популярный Babylon.js, но это Microsoft, сами понимаете...). Но радости от этого не так много, как может показаться на первый взгляд - библиотека имеет кучу недостатков. По сути основные проблемы Three.js вытекают из его же преимуществ: он затачивается как минималистичное решение, с помощью которого можно отрендерить какую-нибудь модель в 3D. Нужно хорошо почитать документацию и потратить довольно много времени, чтобы разобраться даже в самых простых вещах: форматах, загрузке сцен или перемещении объектов по трёхмерной сцене.

Вот так выглядит простой пример, загружающий модель из OBJ файла в Three.js:

+ Показать

− Скрыть

<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - loaders - OBJ loader</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { font-family: Monospace; background-color: #000; color: #fff; margin: 0px; overflow: hidden; } #info { color: #fff; position: absolute; top: 10px; width: 100%; text-align: center; z-index: 100; display:block; } #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer } </style> </head> <body> <div id="info"> <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader test </div> <script src="../build/three.js"></script> <script src="js/loaders/OBJLoader.js"></script> <script> var container; var camera, scene, renderer; var mouseX = 0, mouseY = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; init(); animate(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 ); camera.position.z = 250; // scene scene = new THREE.Scene(); var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 ); scene.add( ambientLight ); var pointLight = new THREE.PointLight( 0xffffff, 0.8 ); camera.add( pointLight ); scene.add( camera ); // texture var manager = new THREE.LoadingManager(); manager.onProgress = function ( item, loaded, total ) { console.log( item, loaded, total ); }; var textureLoader = new THREE.TextureLoader( manager ); var texture = textureLoader.load( 'textures/UV_Grid_Sm.jpg' ); // model var onProgress = function ( xhr ) { if ( xhr.lengthComputable ) { var percentComplete = xhr.loaded / xhr.total * 100; console.log( Math.round(percentComplete, 2) + '% downloaded' ); } }; var onError = function ( xhr ) { }; var loader = new THREE.OBJLoader( manager ); loader.load( 'obj/male02/male02.obj', function ( object ) { object.traverse( function ( child ) { if ( child instanceof THREE.Mesh ) { child.material.map = texture; } } ); object.position.y = - 95; scene.add( object ); }, onProgress, onError ); // Verge3D, Three.js-подобного renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); // window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { windowHalfX = window.innerWidth / 2; windowHalfY = window.innerHeight / 2; camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function onDocumentMouseMove( event ) { mouseX = ( event.clientX - windowHalfX ) / 2; mouseY = ( event.clientY - windowHalfY ) / 2; } // function animate() { requestAnimationFrame( animate ); render(); } function render() { camera.position.x += ( mouseX - camera.position.x ) * .05; camera.position.y += ( - mouseY - camera.position.y ) * .05; camera.lookAt( scene.position ); renderer.render( scene, camera ); } </script> </body> </html>

То есть когда речь идёт о том, чтобы взять простенький кубик, разместить его на сцене и навесить на него красивый материал, который выглядит как пластик или металл, проблем нет, можно взять готовый пример и слегка доработать. Но когда нужно создать полноценное приложение, с реалистичными материалами и логикой, вам потребуется помощь программистов графики, чтобы сделать его в приемлемом виде. Как известно, такие встречаются редко и стоят недёшево, что, как мне кажется, и препятствует повсеместному распространению технологии WebGL в массы.

Кроме того, в Three.js довольно часто встречаются баги и недоработки, но это дело привычное :)

Итак, мы уже поняли, что одной WebGL-библиотеки маловато, нужна нормальная программа для создания 3D контента, нужен нормальный формат, удобный способ создания реалистичных материалов, анимации и логики, ну и наконец, некое подобие системы для создания приложений.

Обо всём по порядку.

Чтобы подключить дизайнеров и моделлеров, нужна интеграция с инструментом для моделирования и создания контента под движок. На первых порах мы взяли Blender, он бесплатный, открытый и повсеместно распространённый. В дальнейшем будем поддерживать и другие инструменты, но нужно с чего-то начинать!

Основным форматом стал glTF 2.0, это последняя версия стандарта для обмена трёхмерной графикой в интернете. Конечно, его нам быстро стало не хватать, посему мы накрутили на него десяток новых расширений, благо спецификация позволяет это делать.

По материалам всё стандартно: Блендер поддерживает три модели материалов: первая модель, условно, называемая стандартной - по сути куча настроек на панели редактора материала, вторая, более навороченная - основана на встроенном редакторе нод, и третья, самая сложная - встроена в "рейтрейсинговый" рендерер Cycles. Понятно, что Cycles несколько проблематично реализовать в рендере реального времени, поэтому мы ограничились только первыми двумя. В дополнение к блендеровским материалам, стандартом glTF 2.0 определён фотореалистичный PBR-материал, основанный на модели освещения Metallic Roughness. Его использование сводится к добавлению на сцену соответствующей группы нод (хак?), которая в при экспорте заменяется на настройки материала, описанные в стандарте.

Помимо материалов, в освещении большую роль играют источники света: некоторые из них действуют совершенно не так как, как предполагает художник, настраивающий их в Blender - это следствие различий в математических моделях, используемых для расчёта интенсивности света. В результате серии экспериментов, а также копании в Блендеровских исходниках, нам удалость привести освещение к какому-то общему знаменателю.

Анимация также поддерживается и экспортируется из Блендера, кстати, она довольно неплохо сделана в glTF 2.0, не буду на ней подробно останавливаться, про это можно написать ещё не одну статью.

Теперь мы переходим к самому главному, как научить художников и других людей, не знакомых с программированием, создавать логику работы приложения, и при этом не писать код? Правильно, нужно использовать визуальный редактор логики. Существует огромное множество решений самого разного уровня, но мы взяли, на наш взгляд, наиболее уместное. В недрах компании Google и университета MIT создали очень интересную библиотеку для обучения детей программированию. Называется Blockly:

С помощью простеньких блоков можно делать весьма и весьма сложные приложения. Отличительной особенностью данного решения, собственно, что и привлекло нас в нём, это подобие такой графической интерпретации реальному коду. Но поскольку это не выглядит как код, и намного более высокоуровневое, порог вхождения существенно снижается, позволяя создавать логику людям, не желающим осваивать веб-программирование. Сделав множество своих собственных блоков поверх API Verge3D, мы, не долго думая, придумали для нового редактора незамысловатое название Puzzles. Вещь получилась отменная, программировать на ней доставляет немалое удовольствие, всем кто не видел, явно стоит попробовать )

Ну и в завершение статьи скажу пару слов о нашем менеджере приложений:

Тут всё предельно просто: создаём приложения на основе шаблонов, запускаем сцены в браузере и Blender, управляем лицензированием и ищем по документации из одного места. Когда мы работали в Blend4Web, у нас был сильно более навороченный, а соответственно, сложный в использовании инструмент, который мы пытались сделать похожим на полноценную IDE. Практика показывает, что навязывать веб-разработчикам инструментарий не самая лучшая идея! В большинстве случаев, веб-разработчики имеют свои собственные проекты, сделанные на WordPress, Rails или Django, и им совсем не нравится идея иметь ещё какой-то проект в непонятном 3D пакете и перетаскивать оттуда файлы с ресурсами.

В менеджере приложений проект не имеет метаданных, всё определяется тем, какие файлы находятся с созданном приложении, отсюда и вытекает логика его работы. Это можно сравнить с утиной типизацией в языках программирования, мы не задаём тип проекта явно, а определяем его по внешнему виду.

На этом всё, пишите в комментариях или на нашем форуме , что нравится или не нравится в нашем новом проекте, а если чего не хватает, но очень нужно, мы сделаем ). Кстати, сам движок можно скачать тут , а чтобы его установить и начать использовать, может потребоваться всего несколько минут, так что пробуйте!

P.S.: 14 декабря мы запустили облачный сервис Verge3D Network, состоящий из online хранилища и CDN для распространения трёхмерных приложений. Подробнее о нём читайте в следующей статье.

rss