Игровой мир WebGL или Three.js vs Babylon.js
Когда я начинал писать свою первую игрушку на three.js я и не думал, что на самом деле three.js это верхушка айсберга в мире WebGL и что есть десятки разнообразных фреймворков и у каждого из них свой специфический уклон, а three.js просто один из них.
Введение1. Базовые элементы2. Группировка3. Движение4. Частицы5. Анимация — 16. Анимация — 27. Простой ландшафт8. Статические коллизии9. Динамические коллизии10. Импорт моделей11. Встраивание физических движков12. Тени, туман
ВведениеСразу замечу, ничего холиварного, кроме названия, в статье нет. Все задумывалось как просто обзор разных дополнений и библиотек к играм для THREE.JS, а BABYLON.JS описать как еще одну хорошую библиотеку. Но потом, в процессе разработки, стало понятно, что во многом часто происходит дублирование. Например система частиц в three.js выражена неплохим дополнением, а в babylon.js она встроена в саму библиотеку и они немного по разному настраиваются и работают. В итоге получился, скорее, обзор одного и того же в двух разных фреймворках для WebGL.По понятным причинам сделать детальный разбор всех имеющихся библиотек просто невозможно. Поэтому в введении ограничусь просто небольшим обзором самых распространённых и со свободной лицензией.
three.js Первопроходец и самая известная библиотека. babylon.js Достойный конкурент для three.js turbulenz.com Часто упоминается в числе трех самых популярных наряду с babylon и three.js, ну и количество звездочек на github говорит само за себя.В основном turbulenz популяризируется как библиотека для создания игрушек, в частности привлек внимание quake Далее следует ряд менее популярных фреймворков: playcanvas.com Симпатичный фреймворк, симпатичные демки. С Gangnam Style у них неплохая демка получилась. scenejs.org/ Симпатичная библиотека, наверно создателям часто приходилось делать модели связанные с медициной. Много препарированных примеров. Синтаксис больше похож на инициализацию jquery плагинов. voxel.js www.senchalabs.org/philogl/ на первый взгляд примеры не произвели ожидаемого впечатления. www.glge.org/ Еще одна библиотека. www.goocreate.com/blog/ Онлайн редактор, импортер. www.kickjs.org/ просто упомяну здесь для статистики. Пожалуй, это и все, что можно перечислить. Отдельно хочу упомянуть, что некоторые движки для реализации реалистичной физики по сути сами являются фреймворками, но о них чуть ниже.1. Базовые элементы Сцена Для начала нам нужно добавить на страницу нашу сцену.В THREE.JS добавление происходит с добавления в document.bodyrenderer.domElement var renderer = new THREE.WebGLRenderer ({antialias: true}); renderer.setSize (window.innerWidth, window.innerHeight); document.body.appendChild (renderer.domElement); В BABYLON.JS не может быть контейнером для сцены любой div к примеру. Все начинается с создания элемента canvas:
Как и у three.js также опцией включается antialiasing. var canvas = document.getElementById («renderCanvas»); var engine = new BABYLON.Engine (canvas, true); Далее создаем саму сцену: BABYLON.JSscene получает параметром engine. scene = new BABYLON.Scene (engine); THREE.JSСцена создается как бы отдельно. И в неё уже добавляются все элементы сцены. var scene = new THREE.Scene (); scene.add (sceneMesh); После этого в THREE.JS renderer вызывается в любой функции с наличием requestAnimationFrame чаще всего называют animate или render, а в BABYLON.JS колбеком в engine.runRenderLoop.В THREE.JS, чаще всего в animate добавляется все логика движений, например, полет пуль, вращение объектов, беготня ботов и тому подобное.
function animate () { requestAnimationFrame (animate); renderer.render (scene, camera); } Как это выглядит в BABYLON.JS, тут как правило иногда добавляют какие то общие конструкции, подсчет частоты кадров, вершин, количества частиц и прочее. Проще говоря, статистику. Для различных анимаций есть красивый хук, подробней об этом в главе про анимацию engine.runRenderLoop (function () { scene.render (); stats.innerHTML = «FPS: » + BABYLON.Tools.GetFps ().toFixed () + » }); Примитивы После инициализации сцены первое, что можно сделать — это создать примитивы.Тут все схоже у babylon.js выглядит компактнее добавление на сцену объекта просто опцией, а у three.js простые манипуляции с назначениями материалов выглядят компактнее.BABYLON.JS var sphere = BABYLON.Mesh.CreateSphere («sphere1», 16, 2, scene); sphere.material = new BABYLON.StandardMaterial («texture1», scene); sphere.material.diffuseColor = new BABYLON.Color3(1, 0, 0); //красный sphere.material.alpha = 0.3; THREE.JS var cube = new THREE.Mesh (new THREE.BoxGeometry (1, 1, 1), new THREE.MeshBasicMaterial ({ color: 0×00ff00 })); scene.add (cube); Позиция для координат по отдельности указывается одинаково: mesh.position.x = 1; mesh.position.y = 1; mesh.position.z = 1; А чтоб сразу задать есть отличия, например в THREE.JS можно написать вот так: mesh.position.set (1, 1, 1); mesh.rotation.set (1, 1, 1); А в BABYLON.JS если не подсматривать в отладчик то в основном так: mesh.position = new BABYLON.Vector3(1, 1, 1); Камеры У обеих библиотек самых используемых камер по две, хотя есть дополнительные у babylon.js к примеру есть с разными фильтрами и специально для планшетов и прочих девайсов. Специально для этого обычно еще нужно подключать hand.jsBABYLON.JSFreeCamera — По сути показывает перспективную проекцию, но с возможностью назначать клавиши для управления, что удобно использовать в играх от первого лица, подробнее в главе про Передвижение персонажа ArcRotateCamera — Камера предполагает вращение вокруг заданной оси, с помощью курсора мыши или сенсора, если предварительно подключить hand.js THREE.JSPerspectiveCamera — камера перспективной проекции, немного упрощенный аналог FreeCamera. Зависит от пропорций и поля зрения и показывает реальный мир. OrthographicCamera — камера ортогональной проекции, показывает все объекты сцены одинаковыми, без пропорций. Вращать мышкой сцену в three.js помогает плагин OrbitControls.js. В babylon.js похожая возможность есть в ArcRotateCamera. new THREE.PerspectiveCamera (45, width / height, 1, 1000); new THREE.OrthographicCamera (width / — 2, width / 2, height / 2, height / — 2, 1, 1000); Из дополнительного тут есть еще CombinedCamera — позволяет устанавливать фокусное расстояние объектива и переключаться между перспективной и ортогональной проекциями. new THREE.CombinedCamera (width, height, fov, near, far, orthoNear, orthoFar) Освещение BABYLON.JSPoint Light — Точечный свет, имитирует световое пятно. Directional Light — Направленный немного рассеянный свет. Spot Light — Больше похож на имитацию фонарика, например может имитировать движение светила. HemisphericLight — подходит для имитации реалистичной окружающей среды, равномерно освещает. //Point Light new BABYLON.PointLight («Omni0», new BABYLON.Vector3(1, 10, 1), scene); //Directional Light new BABYLON.DirectionalLight («Dir0», new BABYLON.Vector3(0, -1, 0), scene); //Spot Light new BABYLON.SpotLight («Spot0», new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), 0.8, 2, scene); //Hemispheric Light new BABYLON.HemisphericLight («Hemi0», new BABYLON.Vector3(0, 1, 0), scene); THREE.JSAmbientLight — представляет общее освещение, применяемое ко всем объектам сцены. AreaLight представляет пространственный источник света, имеющий размеры — ширину и высоту и ориентированный в пространстве DirectionalLight — представляет источник прямого (направленного) освещения — поток параллельных лучей в направлении объекта. HemisphereLight — представляет полусферическое освещение SpotLight — представляет прожектор. //ambientLight var ambientLight = new THREE.AmbientLight (0×404040); //AreaLight areaLight1 = new THREE.AreaLight (0xffffff, 1); areaLight1.position.set (0.0001, 10.0001, -18.5001); areaLight1.width = 10; //DirectionalLight var directionalLight = new THREE.DirectionalLight (0xffffff, 0.5); directionalLight.position.set (0, 1, 0); //PointLight var pointLight = new THREE.PointLight (0xff0000, 1, 100); pointLight.position.set (50, 50, 50); //PointLight var spotLight = new THREE.SpotLight (0xffffff); spotLight.position.set (100, 1000, 100); Материалы Подход к материалам уже довольно сильно разнится, если у three.js есть как бы список возможных материалов, то у babylon.js по сути есть только один материал и к нему применяются разные свойства: прозрачноcть, накладывание текстур с последующим их смещением по осям и тому подобное.Пара примеров: BABYLON.JS // создание материала и назначение текстуры var materialSphere6 = new BABYLON.StandardMaterial («texture1», scene); materialSphere6.diffuseTexture = new BABYLON.Texture (»./tree.png», scene);
// создание материала и назначение ему цвета и прозрачности var materialSphere2 = new BABYLON.StandardMaterial («texture2», scene); materialSphere2.diffuseColor = new BABYLON.Color3(1, 0, 0); //Red materialSphere2.alpha = 0.3; THREE.JSMeshBasicMaterial — просто назначает любой цвет примитиву MeshNormalMaterial — материал со свойствами shading, совмещает в себе смешение цветов. MeshDepthMaterial — материал со свойствами wireframe, выглядит черно-белым MeshLambertMaterial — материал для не блестящих поверхностей MeshPhongMaterial — материал для блестящих поверхностей MeshFaceMaterial — может комбинировать другие виды материалов назначать на каждый полигон свой материал. Для примера базовая сцена для обоих библиотек: three.js
Если говорить о лаконичности, то, смотря на базовую сцену, количество строчек выходит примерно одинаковое, но дальше мы увидим, что все не так однозначно.2. Группировка
Пожалуй, одна из нужнейших вещей для игры, необходимая для привязки оружия или космолета к камере, оружия к игроку и т.д.BABYLON.JSЕсть несколько способов группировки. Самый простой и очевидный — это назначение свойства parent. Например, если надо закрепить какой то объект за камерой, то:
var mesh = new BABYLON.Mesh.CreateBox ('name', 1.0, scene);
mesh.position = new BABYLON.Vector3(1, -1, 5);
mesh.parent = camera;
А дальше уже мы управляем камерой от первого лица.В THREE.JS нам надо создать родительский объект для всех примитивов и в него поместить остальные объекты, а потом уже управлять этим родительским объектом по своему усмотрению:
var parent = new THREE.Object3D ();
parent.add (camera);
parent.add (mesh);
parent.position.y = 10;
3. Движение персонажа
Для игр от первого лица нужно чтобы камера, показывающая перспективу, управлялась мышкой и с клавиатуры.BABYLON.JSТут все довольно просто FreeCamera позволяет сразу управлять движением. Достаточно указать camera.detachControl (canvas). Камере можно задать ряд свойств, например, скорость camera.speed = 1, назначить клавиши «вперед», «назад», «влево», «вправо» и т.д.
camera.keysUp = [38, 87];
camera.keysDown = [40, 83];
camera.keysLeft = [37, 65];
camera.keysRight = [39, 68];
Следует заметить, что полноценное управление мышью включается только после подключения PointerLock. Камере можно присвоить детей, которые будут вместе с ней ездить. Соответственно, если мы пишем многопользовательскую игру, то лучше передавать координаты камеры camera.position, camera.cameraRotation серверу для управления. А вот с THREE.JS все гораздо сложнее. Камера сама по себе тут просто камера и чтобы заставить её двигаться нужно прописывать на каждое нажатие клавиши смену позиции. Естественно, о плавности движения также предстоит побеспокоится. Для управления мышью тоже все непросто — менять, подставлять координаты в
mesh.rotation.set (x, y, z) явно недостаточно. Тут нас немного спасает пример из github.io автора three.js. Поэтому остановлюсь лишь на паре деталей. Чтобы вращать мышью камеру с объектом нужно вначале создать один new THREE.Object3D (), внутрь него поместить другой и внутри вращать. Тогда получится видимость поворота вокруг своей оси. Выглядит это все в сокращенном варианте примерно так:
var pitchObject = new THREE.Object3D ();
pitchObject.add (camera);
var yawObject = new THREE.Object3D ();
yawObject.position.y = 10;
yawObject.add (pitchObject);
var onMouseMove = function (event) {
yawObject.rotation.y -= event.movementX * 0.002;
pitchObject.rotation.x -= event.movementY * 0.002;
pitchObject.rotation.x = Math.max ( — Math.PI / 2, Math.min (Math.PI / 2, pitchObject.rotation.x));
};
document.addEventListener ('mousemove', onMouseMove, false);
Клавишами, естественно, нужно двигать первый объект.4. Частицы
часто необходимы для рисования огня, взрывов, салютов, выстрелов и много еще чего.В BABYLON.JS система части встроена и изобилует большим количеством настроек. Но для воспроизведения любого эффекта необходимо экспериментировать или бегать по форумам искать понравившийся. Плюс надо привязывать к готовому мешу. Его, конечно, можно сделать невидимым, но можно было бы просто сделать чтобы была возможность просто указать координаты местонахождения.Пример небольшого костра на babylon.js:
var particleSystem = new BABYLON.ParticleSystem («particles», 1000, scene);
particleSystem.particleTexture = new BABYLON.Texture (»./img/flare.png», scene);
particleSystem.emitter = obj; // Начальный объект, от которого начинают появляться частицы
// Откуда частицы начинают появляться
particleSystem.minEmitBox = new BABYLON.Vector3(-0.5, 1, -0.5); // Starting all from
particleSystem.maxEmitBox = new BABYLON.Vector3(0.5, 1, 0.5); // To…
// Цвет частиц
particleSystem.color1 = new BABYLON.Color4(1, 0.5, 0, 1.0);
particleSystem.color2 = new BABYLON.Color4(1, 0.5, 0, 1.0);
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0, 0.0);
// Размер от и до каждой частицы
particleSystem.minSize = 0.3;
particleSystem.maxSize = 1;
// Время жизни каждой частицы, берется в рандомном порядке между max и min
particleSystem.minLifeTime = 0.2;
particleSystem.maxLifeTime = 0.4;
// Эмиссия частиц
particleSystem.emitRate = 600;
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
particleSystem.gravity = new BABYLON.Vector3(0, 0, 0);
// Направление каждой частицы после появления
particleSystem.direction1 = new BABYLON.Vector3(0, 4, 0);
particleSystem.direction2 = new BABYLON.Vector3(0, 4, 0);
particleSystem.minAngularSpeed = 0;
particleSystem.maxAngularSpeed = Math.PI;
// Скорость
particleSystem.minEmitPower = 1;
particleSystem.maxEmitPower = 3;
particleSystem.updateSpeed = 0.007;
particleSystem.start ();
THREE.JSПодключается с помощью стороннего плагина, но имеет возможность сразу воспроизводить заготовленные эффекты и выставлять время. Место появления частиц можно задать координатами.Хороший движок частиц для three.jsНаверное, самый хороший движок частицГотовые примеры с готовыми настройками5. Анимация — 1
Как правило, анимация нужна для воспроизведения каких то эффектов, к примеру, движения небесных светил, движения ботов и тому подобного. Есть несколько вариантов как заставить двигаться разные объекты, рассмотрим их по порядку.BABYLON.JSВставить анимацию можно в любое место стандартным для библиотеки способом:
scene.registerBeforeRender (function () {
mesh.position.x = 100 * Math.cos (alpha);
donutmesh.position.y = 5;
mesh.position.z = 100 * Math.sin (alpha);
alpha += 0.01;
});
Порой бывает удобно для каждого объекта вызывать свою анимацию.THREE.JSДля three.js есть возможность заставить что то двигаться только в петле анимации:
var render = function () {
requestAnimationFrame (render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render (scene, camera);
};
render ();
6. Анимация — 2
Кроме заранее неопределенной анимации когда не знаешь что куда побежит, есть анимация определенная, когда, к примеру, персонаж при определенных обстоятельствах делает заранее известные два-три шага или сымитировать, к примеру, стрельбу автомата.BABYLON.JSПростая анимация с изменением размера бокса:
// Создаем анимацию изменяющую размер на 30 кадров в минуту
var animationBox = new BABYLON.Animation («tutoAnimation», «scaling.x», 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
// настраиваем ключевые кадры анимации
var keys = [];
keys.push ({ frame: 0, value: 1 });
keys.push ({ frame: 20, value: 0.2 });
keys.push ({ frame: 100, value: 1 });
//добавляем ключи в объект анимации
animationBox.setKeys (keys);
box1.animations.push (animationBox);
//запускаем анимацию
scene.beginAnimation (box1, 0, 100, true);
THREE.JSВ основном анимация заключается в манипуляции с geometry.animation.hierarchy и в вызове geometry.animation.hierarchyВыглядеть может примерно так
var loader = new THREE.JSONLoader ();
loader.load («models/skinned/scout/scout.js», function (geometry) {
for (var i = 0; i < geometry.animation.hierarchy.length; i ++ ) {
var bone = geometry.animation.hierarchy[ i ];
var first = bone.keys[ 0 ];
var last = bone.keys[ bone.keys.length - 1 ];
last.pos = first.pos;
last.rot = first.rot;
last.scl = first.scl;
}
geometry.computeBoundingBox();
THREE.AnimationHandler.add( geometry.animation );
var mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial() );
mesh.position.set( 400, -250 - geometry.boundingBox.min.y * 7, 0 );
scene.add( mesh );
animation = new THREE.Animation( mesh, geometry.animation.name );
animation.play();
});
Небольшой пример: alteredqualia.com/three/examples/webgl_animation_skinning_tf2.html7. Простой ландшафт
Часто нужно создать какой-то незатейливый окружающий ландшафт, небольшие холмы или горы. И чтобы это было быстро.BABYLON.JSПроисходит путем совмещения одной оригинальной картинки ландшафта, которая будет фоном, и другой черно-белой — получается как бы выдавливание.
var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
groundMaterial.diffuseTexture = new BABYLON.Texture("./img/earth.jpg", scene);
var ground = BABYLON.Mesh.CreateGroundFromHeightMap("ground", "./img/heightMap.jpg", 200, 200, 250, 0, 10, scene, false);
ground.material = groundMaterial;
THREE.JSЕсть дополнения с похожей функциональностью.Есть простенький вариант, представляющий из себя колечко из горок.github.com/jeromeetienne/threex.montainsarena
var mesh = new THREEx.MontainsArena ()
scene.add (mesh)
Есть немного посложнее, процедурно сгенерированые поверхности.
var geometry = THREEx.Terrain.heightMapToPlaneGeometry (heightMap)
THREEx.Terrain.heightMapToVertexColor (heightMap, geometry)
var material = new THREE.MeshPhongMaterial ({ shading: THREE.SmoothShading, vertexColors: THREE.VertexColors});
var mesh = new THREE.Mesh (geometry, material);
scene.add (mesh);
8. Статические коллизии
Столкновения объектов заранее предусмотренные.BABYLON.JSНа каждый объект можно выставить: Но нужно заметить, что, к примеру, выставлять checkCollisions на большое количество объектов или на объемную площадь бесполезно, все будет тормозить.Лучше написать, что-нибудь вроде:
if (mesh.position.y < 10 )
mesh.position.y = 10;
А вокруг каких-то ландшафтных изгибов лучше выстраивать коридоры из невидимых примитивов.THREE.JSПридется все-таки вручную проверять. Или с помощью RayCasting9. Динамические коллизии
Используются когда вы никак точно не можете знать, произойдет ли столкновение какого-то одного объекта с другим. А если произойдет, то нужно как-то на это реагировать.Все идентично, практически. Примеры попадания шариков имитирующих попадание пули в объекты.BABYLON.JS
// meshList - массив со списком объектов
scene.registerBeforeRender(function () {
for (var i=0; i < meshList.length; i++ ){
if(bullet.intersectsMesh(meshList[i], true))
console.log('Есть попадание, координаты:' meshList[i].position);
}
});
THREE.JS
function animate() {
requestAnimationFrame(animate);
for(var res = 0; res < meshList.length; res++) {
var intersections = raycaster.intersectObject(meshList[res]);
if (intersections.length > 0)
console.log ('Есть попадание, координаты:' ballMeshes[i].position);
}
renderer.render (scene, camera);
}
10. Импорт моделей
Тут экспериментировал в основном только в Blender поэтому могу только за него вести речь.Установка и настройка импорта выглядит одинаково.Скачиваем експортер для babylon.js по ссылке github.com/BabylonJS/Babylon.js/tree/master/Exporters/Blender
Копируем его в директорию ./Blender/2.XX/scripts/addons
перезапускам blender, и в Файл→Параметры или Ctrl+Alt+U закладка Дополнения настраиваем нужную галочку. После чего в меню появится возможность экспортировать в желаемый формат.
А вот на стадии импорта начинается уже интересное.BABYLON.JSЕсть пара нюансов. На первый взгляд все просто, при импорте нет никаких дополнительных галочек — нажал кнопку и все. Но потом выясняется, что некоторые модели так и не импортировались, некоторые вроде нормально импортировались, но почему-то не реагируют на команды, смены позиции или маштабирования.Например, если импортировать в Blender в формате .obj, а потом из Blender экспортировать в .babylon, то высока вероятность, что может нормально не заработать. А если тот же самый процесс повторить с, к примеру, моделью .blend, то вероятность, что она нормально заработает вырастает в разы.Пример загрузки объекта в babylon c появившемся в последних версиях AssetsManager
//инициализируем assetsManager
var assetsManager = new BABYLON.AssetsManager (scene);
// добавляем задачу менеджеру
var meshTask = assetsManager.addMeshTask («obj task»,»,»./», «obj.babylon»);
//любая задача может предоставлять onSuccess и onError колбеки:
meshTask.onSuccess = function (task) {
task.loadedMeshes[0].position = new BABYLON.Vector3(0, 0, 0);
}
// assetsManager предоставляет три колбека onFinish, onTaskSuccess, onTaskError
// показываем всю сцену после того как подгрузятся все импортируемые объекты
assetsManager.onFinish = function (tasks) {
engine.runRenderLoop (function () { scene.render (); });
};
Все текстуры импортируются вместе с объектом. Главное, чтоб лежали рядом.THREE.JSУ three.js все не так просто выглядит. Есть пара десятков загрузчиков, делающих примерно одно и тоже.Импорт .die c помощью ColladaLoader
var loader = new THREE.ColladaLoader ();
loader.load («obj.dae», function (result) {
scene.add (result.scene);
});
Импорт .js импортированного с blender
loader = new THREE.JSONLoader ();
loader.load (»./model.js», function (geometry) {
mesh = new THREE.Mesh (geometry, new THREE.MeshNormalMaterial ());
mesh.scale.set (10, 10, 10);
mesh.position.y = 150;
scene.add (mesh);
});
Загрузка .obj
var loader = new THREE.OBJLoader ();
loader.load ('./model.obj', function (object){
scene.add (object);
});
Загрузка сцены
var loader = new THREE.SceneLoader ();
loader.load ('jet.json', function (res) {
scene.add (res.scene);
renderer.render (res.scene, camera);
});
Следует заметить что из three.js можно импортировать сцену из .babylon
var loader = new THREE.BabylonLoader (manager);
loader.load ('models/babylon/skull.babylon', function (babylonScene) {
scene.add (babylonScene);
}, onProgress, onError);
В three.js тоже есть менеджер загрузок:
var manager = new THREE.LoadingManager ();
manager.onProgress = function (item, loaded, total) {
console.log (item, loaded, total);
};
var loader = new THREE.OBJLoader (manager);
loader.load ('./model.obj', function (object) { });
11. Встраивание физических движков.
Как отдельный класс существуют движки, имитирующие столкновения физического мира. Например, машина натыкается на ящик, который отлетает и пару раз перекатывается. Или шарик попадает в ящик, который сдвигается. Естественно, такие возможности гораздо удобнее, чем все это вручную прописывать.Существует два направление работы с движками. Первое — с помощью разных плагинов, упрощающих интеграцию и, собственно, напрямую.BABYLON.JSВ основном используется два oimo.js и cannot.jsИспользование oimo.js в babylon.js:
//активация
scene = new BABYLON.Scene (engine);
scene.enablePhysics (new BABYLON.Vector3(0,-10,0), new BABYLON.OimoJSPlugin ());
//добавляем физические свойства грунту
grount.setPhysicsState ({ impostor: BABYLON.PhysicsEngine.BoxImpostor, move: false});
//добавляем физические свойства боксу и сфере
sphere.setPhysicsState ({impostor: BABYLON.PhysicsEngine.SphereImpostor, move: true, mass:1, friction:0.5, restitution:0.5});
box.setPhysicsState ({impostor: BABYLON.PhysicsEngine.BoxImpostor, move: true, mass:1, friction:0.5, restitution:0.1});
Дополнительно почитать про oimo.js в babylon.js: blogs.msdn.com/b/davrous/archive/2014/11/18/understanding-collisions-amp-physics-by-building-a-cool-webgl-babylon-js-demo-with-oimo-js.aspxpixelcodr.com/tutos/oimo/oimo.htmlpixelcodr.com/tutos/physics/physics.htmlTHREE.JSДля oimo.js есть Расширение
// инициализация мира oimo.js
var onRenderFcts= [];
var world = new OIMO.World ();
//обновление для каждого кадра положения объекта
onRenderFcts.push (function (delta){ world.step () });
// создание IOMO.Body из объекта three.js
var mesh = new THREE.Mesh (new THREE.CubeGeometry (1,1,1), new THREE.MeshNormalMaterial ())
scene.add (mesh)
var body = THREEx.Iomo.createBodyFromMesh (world, mesh)
var updater = new THREEx.Iomo.Body2MeshUpdater (body, mesh)
// тогда в каждом кадре будет обновление позиции объекта
updater.update ()
12. Тень.
BABYLON.JS
//тень
var shadowGenerator = new BABYLON.ShadowGenerator (1024, light);
shadowGenerator.getShadowMap ().renderList.push (torus);
ground.receiveShadows = true;
//туман
THREE.JS
//тень
var mesh = new THREE.Mesh (new THREE.BoxGeometry (1500, 220, 150), new THREE.MeshPhongMaterial ({color:0xffdd99}));
mesh.position.z = 20;
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add (mesh);
//туман
scene.fog = new THREE.Fog (0×59472b, 1000, 500);
//туман — 2
scene.fog = new THREE.FogExp2(0xD6F1FF, 0.0005);
P.S. За кадром осталось много всего, да и этот материал получился довольно растянутым, на мой взгляд. Надеюсь, он поможет тем, кто только начинает изучать возможности WebGL, а также тем, кто выбирает на чем лучше написать игрушку. Спасибо всем кто дочитал до конца.
Используемые материалы.THREE.JSAPIСхема вызовов при отрисовке сцены в three.jsРусскоязычная справкаПримеры от stemkoskiСайт с примерамиБольше примеровСписок дополнений
BABYLON.JSAPIПримеры основной функциональностиФорум babylon.js отвечают очень неплохоСайт babylon.js с примерамиДокументацияОбзорная статья на Хабре