WebGL

Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Вт, 16 июля 2013, 10:49:36

Включить в опере на компе - opera:config#UserPrefs|EnableWebGL значение 1 а потом не забыть нажать кнопку сохранить и перезапустить оперу.
Правда всё это бесполезно, т.к. WebGL реализована в опере криво ((

Добавлено спустя 4 минуты 27 секунд:
Уроки:

http://ruwebgl.blogspot.ru/
http://learningwebgl.com/blog/?page_id=1217 - тут примитивы и рендеринг в текстуру
http://learningwebgl.com/lessons/lesson04/index.html

спецификация и т.д.
https://www.khronos.org/webgl/
https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf
Вложения
webgl-reference-card-1_0.pdf
(494.99 КБ) 134 скачивания
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Пн, 23 декабря 2013, 09:09:51

карты на джава ккрипт с локальным хранилищем
http://habrahabr.ru/post/191850/
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#3 dyvniy » Ср, 25 декабря 2013, 16:11:40

Разные JS движки,
http://www.webgl-game-engines.com/
"сквозь вселенную "
http://www.greensock.com/js/speed.html
Вложения
сквозь вселенную.png
сквозь вселенную.png (23.35 КБ) 1307 просмотров
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#4 dyvniy » Ср, 7 января 2015, 10:04:42

Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#5 dyvniy » Ср, 16 сентября 2015, 16:22:25

Игровой мир WebGL
Three.js (http://threejs.org/) vs Babylon.js (http://www.babylonjs.com/)
http://habrahabr.ru/post/246259/
Спойлер
Когда я начинал писать свою первую игрушку на three.js я и не думал, что на самом деле three.js это верхушка айсберга в мире WebGL и что есть десятки разнообразных фреймворков и у каждого из них свой специфический уклон, а three.js просто один из них.

Введение
1. Базовые элементы
2. Группировка
3. Движение
4. Частицы
5. Анимация — 1
6. Анимация — 2
7. Простой ландшафт
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:
<canvas id="renderCanvas"></canvas>

Как и у three.js также опцией включается antialiasing.
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);

Далее создаем саму сцену:
BABYLON.JS
scene получает параметром 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: <b>" + BABYLON.Tools.GetFps().toFixed() + "</b>
});

Примитивы

После инициализации сцены первое, что можно сделать — это создать примитивы.
Тут все схоже у 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: 0x00ff00 }) );
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.js
BABYLON.JS
FreeCamera — По сути показывает перспективную проекцию, но с возможностью назначать клавиши для управления, что удобно использовать в играх от первого лица, подробнее в главе про Передвижение персонажа
ArcRotateCamera — Камера предполагает вращение вокруг заданной оси, с помощью курсора мыши или сенсора, если предварительно подключить hand.js

THREE.JS
PerspectiveCamera — камера перспективной проекции, немного упрощенный аналог 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.JS
Point 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.JS
AmbientLight — представляет общее освещение, применяемое ко всем объектам сцены.
AreaLight представляет пространственный источник света, имеющий размеры — ширину и высоту и ориентированный в пространстве
DirectionalLight — представляет источник прямого (направленного) освещения — поток параллельных лучей в направлении объекта.
HemisphereLight — представляет полусферическое освещение
SpotLight — представляет прожектор.

//ambientLight
var ambientLight = new THREE.AmbientLight( 0x404040 );
//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.JS
MeshBasicMaterial — просто назначает любой цвет примитиву
MeshNormalMaterial — материал со свойствами shading, совмещает в себе смешение цветов.
MeshDepthMaterial — материал со свойствами wireframe, выглядит черно-белым
MeshLambertMaterial — материал для не блестящих поверхностей
MeshPhongMaterial — материал для блестящих поверхностей
MeshFaceMaterial — может комбинировать другие виды материалов назначать на каждый полигон свой материал.


Для примера базовая сцена для обоих библиотек:
three.js
babylon.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<code> серверу для управления. А вот с <font color="green">THREE.JS</font> все гораздо сложнее. Камера сама по себе тут просто камера и чтобы заставить её двигаться нужно прописывать на каждое нажатие клавиши смену позиции. Естественно, о плавности движения также предстоит побеспокоится. Для управления мышью тоже все непросто - менять, подставлять координаты в <code>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:
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.html

7. Простой ландшафт

Часто нужно создать какой-то незатейливый окружающий ландшафт, небольшие холмы или горы. И чтобы это было быстро.
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
Придется все-таки вручную проверять. Или с помощью RayCasting
9. Динамические коллизии

Используются когда вы никак точно не можете знать, произойдет ли столкновение какого-то одного объекта с другим. А если произойдет, то нужно как-то на это реагировать.
Все идентично, практически. Примеры попадания шариков имитирующих попадание пули в объекты.
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. Встраивание физических движков.

Как отдельный класс существуют движки, имитирующие столкновения физического мира. Например, машина натыкается на ящик, который отлетает и пару раз перекатывается. Или шарик попадает в ящик, который сдвигается. Естественно, такие возможности гораздо удобнее, чем все это вручную прописывать.
oimo.js — один из самых перспективных и удобных.
Песочница oimo.js поиграться
cannon.js тоже довольно популярный
Самый распространенный пример имитирующий простенький шутер со стрельбой шариками по кубикам, интегрированный с three.js.
ammo.js один из первых движков
Physijs построен на ammo.js
JigLibJS C/C++ библиотека вызывающая JigLib
bullet.js мало распространенная

Существует два направление работы с движками. Первое — с помощью разных плагинов, упрощающих интеграцию и, собственно, напрямую.
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.aspx
pixelcodr.com/tutos/oimo/oimo.html
pixelcodr.com/tutos/physics/physics.html
THREE.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( 0x59472b, 1000, 500 );
//туман - 2
scene.fog = new THREE.FogExp2(0xD6F1FF, 0.0005);



P.S. За кадром осталось много всего, да и этот материал получился довольно растянутым, на мой взгляд. Надеюсь, он поможет тем, кто только начинает изучать возможности WebGL, а также тем, кто выбирает на чем лучше написать игрушку. Спасибо всем кто дочитал до конца.

Используемые материалы.
THREE.JS
API
Схема вызовов при отрисовке сцены в three.js
Русскоязычная справка
Примеры от stemkoski
Сайт с примерами
Больше примеров
Список дополнений



BABYLON.JS
API
Примеры основной функциональности
Форум babylon.js отвечают очень неплохо
Сайт babylon.js с примерами
Документация
Обзорная статья на Хабре
javascript, three.js, babylon.js, webgl, blender, 3d
+52

29770

368


Александр @Alex10 карма52,0 рейтинг0,0
Похожие публикации

Что выбрать для 3D сайта – Three.js или Blend4Web? (41)
Анимация персонажей в Blender 3D — это просто (11)
Обзор дополнений для Blender 3D (13)
Трёхмерный фон для сайта в реальном времени на JavaScript при помощи three.js (10)
Звездное небо на webGL с использованием three.js (4)
Комментарии (18) отслеживать новые: в почте в трекере

+2 maxmert26 января 2015 в 13:41#
Спасибо за обзор. Сам использовал только three.js (в основном мелочь, вроде vimeo.com/83977515), было интересно увидеть babylon.js. Попробую на досуге. В карму плюс ;)
0 xGromMx26 января 2015 в 13:47#
Есть еще такой редактор clara.io
+1 xGromMx26 января 2015 в 13:59#
Еще есть такой ресурс www.webgl-game-engines.com
0 Keyten26 января 2015 в 15:15#
Спасибо за обзор.

К минусам обоих библиотек: когда-то сам так писал, но теперь удивляет такой подход — перерисовывать сцену даже если она не изменилась.
+3 CJay26 января 2015 в 17:43#↵↑
а как вы будете определять, что стоит перерисовать?! Если камера повернулась или сместилась совсем немного, перерисовывать придётся всё.
0 Galiaf4726 января 2015 в 20:35#↵↑
Речь не об отдельных объектах, а о наличии render loop.
+2 Keyten27 января 2015 в 02:08#↵↑
Например, как в graphics2d: для изменения параметров используются методы (а не свойства) объекта, которые вызывают перерисовку.
// обычный подход: loop перерисует всё с другим значением параметра
object.x = 10;

// функция object.x изменяет параметр и вызывает одну перерисовку
object.x(10);


Вопрос не в том, чтобы перерисовывать часть объектов (это другой вопрос), а чтобы не перерисовывать, когда это не нужно. И вообще исключить любую обработку. Например, если ваша сцена меняется только при движении мыши, очевидно, перерисовка, когда мышь неподвижна, абсолютно бессмысленна. Но здесь она есть.
+1 Galiaf4726 января 2015 в 20:46#↵↑
Если я не ошибаюсь, никто не навязывает перерисовку в цикле, вы вольны вызывать ее на свое усмотрение. Но для динамических сцен, где изменения могут происходить самостоятельно (дождь например), такой цикл необходим. Кроме того — это общепринятая практика для игр, и не забывайте что у рекомендуемого THREE.js цикла есть свои достоинства, например: ограничение частоты кадров и отключение когда вы переключаете вкладку в браузере.
0 yadobr26 января 2015 в 16:09#
Спасибо за статью. Давно хотел что-нибудь на JS написать в плане игрушек.
Скажите, а как обстоит дело с обфускацией кода? Это единственный способ защиты?
0 Alex1026 января 2015 в 16:54#↵↑
Ну как вариант разве что можно предложить на игровом движке blender сделать. И дальше просто экспортировать в браузер. Правда не уверен что там гладко все пройдет с многопользовательским вариантом. Но мне кажется что там тоже многое возможно.
+1 Keyten26 января 2015 в 17:04#↵↑
Обфускация, увы, зачастую замедляет код, что в WebGL (по крайней мере, сейчас) вряд ли приемлемо.
Если у вас какие-то секретные алгоритмы, не связанные с отрисовкой, проще всего их перенести на сервер.
0 Galiaf4726 января 2015 в 21:05#
Чтобы вращать мышью камеру с объектом нужно вначале создать один new THREE.Object3D(), внутрь него поместить другой и внутри вращать. Тогда получится видимость поворота вокруг своей оси. Выглядит это все в сокращенном варианте примерно так:


Проблемы с вращением камеры происходят из-за того, что для поворота объекта используются Углы Эйлера
Такие повороты некоммутативны и конечное положение системы зависит от порядка, в котором совершаются повороты.
wikipedia.org

Для решения проблемы можно использовать один объект (или саму камеру) с измененным порядком осей вращения:
obj.rotation.order = 'YXZ';
0 engine927 января 2015 в 03:49#
Самое время вспомнить blend4web.
0 Alex1027 января 2015 в 16:21#↵↑
В тексте и в комментариях выше вспоминали blender, blend4web это по сути тот же blender только может с десятком уже готовых сцен в платной версии. Ну и встроенном в него экспортере в веб.
0 engine927 января 2015 в 16:41#↵↑
У них есть еще многофункциональный редактор-просмотрщик и сложность проектов не ограничивается отдельными сценами. Вот пример полноценного уровня с физикой, NPC, даже трактором.
0 Magistr_AVSH27 января 2015 в 08:23 (комментарий был изменён)#
Самая первая картинка — это из вашей игрушки или…? :)
Давно пользуюсь three.js, на мой взгляд он все таки лидер среди всех остальных библиотек. Если где-то встречается WebGL, то можно почти быть увереным — это three.js.
Ее, на мой взгляд, надо рассматривать как графический движок, а не игровой. Тогда все встает на свои места.
0 Alex1027 января 2015 в 11:21 (комментарий был изменён)#↵↑
Самая первая картинка из стандартного примера ландшафта babylon.js с наложением карты. Мне в написании игрушки показалось самым сложным это все таки не окружающий мир а взаимодействие друг с другом игроков синхронизация и все такое.
+1 rejjin28 января 2015 в 12:16#
Замечательный обзор. Правда не дает понять о преимуществах и недостатках, не рассказывает в каких проектах лучше использовать babylon.js, а в каких three.js. Формально, одно можно назвать движком, а другое фреймворком.
Все написано понятно, я бы с особым вниманием читал это, если бы только начинал в этой сфере.
Стоило бы отметить, что babylon.js написан (переписан?) на TypeScript, будет приятно писать игры более-менее внятных объемов. К three.js тоже есть define types, но, если мне не изменяет память, то актуальность версий не сходится. Хотя можно дописывать самостоятельно.
Есть еще очень и очень хорошая штука под названием away3d. Это уже не только flash/as3, можно писать для webgl на js/ts. На сайте есть внушающая демка.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#6 dyvniy » Чт, 17 сентября 2015, 10:39:58

Test))
http://www.babylonjs.com/scenes/simd.html
i7 4770 + GTX 770 = 150 densers
Изображение


Название раздела: Web на стороне клиента, Java Script
Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Web на стороне клиента, Java Script»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 9 гостей