Интерактивные
3D-карты своими
руками
Амосов Александр, AVITO
email: s9k0@ya.ru
twitter: @gc_s9k
История
2
3
4
5
6
2D vs 3D
7
Почему 3D?
• Это красиво
8
Почему 3D?
• Это красиво
9
Почему 3D?
• Это красиво
• Это наглядно
10
Почему 3D?
• Это красиво
• Это наглядно
• Потому что я могу
11
Создание модели
12
Создание модели
• Найти моделлера (опционально)
• Найти готовые модели (опционально)
• Освоить 3D-редактор самому
13
14
Blender
• бесплатность
• открытый код
• постоянное развитие
• кроссплатформенность
• пользовательские скрипты на python
15
16
SVG Blender
17
18
19
20
import bpy
geometry = bpy.data.meshes['place']
for obj in bpy.context.selected_objects:
obj.rotation_euler.x = 0
obj.rotation_euler.y = 0
obj.data = geometry
obj.location.z = 0
21
22
Тени
23
24
25
26
OpenGL 1.5 OpenGL 2.0 OpenGL 3.3 OpenGL 4.5
OpenGL ES 1.1 OpenGL ES 2.0 OpenGL ES 3.0
Vulkan
WebGL 1.0 WebGL 2.0
27
WebGL Next?
28
29
2D vs 3D [2]
30
2D
31
<canvas id="canvas" width="100" height="100"></canvas>
<script>
(function() {
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
context.fillStyle = 'rgba(255, 0, 0, 1)';
context.fillRect(25, 25, 50, 50);
}());
</script>
3D
32
<canvas id="canvas" width="100" height="100"></canvas>
<script>
(function() {
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
// Инициализировать шейдеры
// Создать программу
// Создать вершинный буфер
// Сохранить ссылку на буферный объект в атрибут
// Вызвать отрисовку
}());
</script>
Вершинный шейдер
33
const vertexShaderSource = `
attribute vec4 position;
void main() {
gl_Position = position;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
Фрагментный шейдер
34
const fragmentShaderSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, vertexShaderSource);
gl.compileShader(fragmentShader);
Программа
35
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
Вершинный буфер
36
const vertices = new Float32Array([
-0.5, 0.5, -0.5, -0.5,
0.5, 0.5, 0.5, -0.5
]);
const vertexSize = 2;
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const attrPosition = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(attrPosition, vertexSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(attrPosition);
Отрисовка
37
const vertices = new Float32Array([
-0.5, 0.5, -0.5, -0.5,
0.5, 0.5, 0.5, -0.5
]);
const vertexSize = 2;
// …
gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / vertexSize);
38
WebGL Programming Guide:
Interactive 3D Graphics:
Programming with WebGL
Авторы: Коичи Мацуда, Роджер Ли
39
WebGL Framework
(three.js)
40
WebGL Framework
• Удобные абстракции
• Краткий код
• Никаких шейдеров (поначалу)
41
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
42
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
43
44
45
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
46
47
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
48
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
49
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
50
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
var loader = new THREE.ObjectLoader();
loader.load('model.json', function(mesh) {
scene.add(mesh);
});
ry =
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
51
SVG Blender
{
"metadata": {
"version": 4.4,
"sourceFile": "model.blend",
"generator": "io_three",
"type": "Object"
},
"geometries": [
...
],
"materials": [
...
],
"object": {
...
}
}
JSON
io_three
52
Больше контроля
53
Больше контроля
54
Больше контроля
55
<script src="three/build/three.js"></script>
<script src="three/examples/js/controls/OrbitControls.js"></script>
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
var loader = new THREE.ObjectLoader();
loader.load('model.json', function(mesh) {
scene.add(mesh);
});
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
56
var scene, camera, renderer, geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
new THREE.OrbitControls(camera);
var loader = new THREE.ObjectLoader();
loader.load('model.json', function(mesh) {
scene.add(mesh);
});
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
57
58
https://goo.gl/ell2e7
Interactive 3D Graphics Course With Three.js & WebGL
https://www.udacity.com/course/interactive-3d-graphics--cs291
59
Как работает
приложение
60
Viewer 61
• Модель с запеченными тенями
• Рейкастинг объектов
• Спрайты для иконок
UI 62
• React
Viewer UI
Redux store
63
Viewer UI
Redux store
64
{
type: 'SELECT_FLOOR',
floor: 10
}
Все тормозит?
65
66
Сглаживание
67
// WebGL:
const gl = canvas.getContext("webgl", { antialias: true });
// three.js:
const renderer = new THREE.WebGLRenderer({ antialias: true });
На взлет
68
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
Не рендерить все время
69
Начало движения камеры
Конец движения камеры
Запуск рендеринга
Остановка рендеринга
Изменение состояния приложения Отрендерить один кадр
Raycasting
70
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(normalizedMouseCoordinates, camera);
const intersects = raycaster.intersectObjects(objects);
Colliders
71
72
73
Instancing
До:
365 draw calls
После:
51 draw calls
74
ANGLE_instanced_arrays extension
75
76
uniform
uniform
uniform
uniform
77
uniform
uniform
uniform
uniform
uniform
78
uniform
uniform
uniform
uniform
uniform
79
uniform
uniform
uniform
uniform
attribute
attribute
attribute
attribute
Instancing
80
• Сильно повышает производительность
Instancing
81
• Сильно повышает производительность
• Сложно
https://goo.gl/zdaWZU
82
Упрощение модели
83
Оптимизация текстур
84
Сжатые текстуры
Плюсы:
• В 4 раза меньше видеопамяти занимают
Ограничения:
• Разные форматы: DXT, PVRTC, ETC
• Ухудшение картинки
• Проблемы с прозрачностью
• Больший объем файлов (но можно применить gzip)
85
https://goo.gl/swsgxR
Сжатые текстуры
86
Сжатые текстуры
87
88
Сжатые текстуры
Не гонитесь за
реализмом
89
You are not alone
90
Ссылки
Курс по трехмерной графике на Udacity
Книга "Программирование трехмерной графики"
Примеры threejs
Видео про рендеринг текста в WebGL (слайды)
Видео про производительность WebGL (статья)
91
Спасибо! Вопросы?
92
Ссылки
https://goo.gl/wt4wzp

Интерактивные 3D-карты своими руками / Александр Амосов (Avito)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
    Почему 3D? • Этокрасиво • Это наглядно 10
  • 11.
    Почему 3D? • Этокрасиво • Это наглядно • Потому что я могу 11
  • 12.
  • 13.
    Создание модели • Найтимоделлера (опционально) • Найти готовые модели (опционально) • Освоить 3D-редактор самому 13
  • 14.
  • 15.
    Blender • бесплатность • открытыйкод • постоянное развитие • кроссплатформенность • пользовательские скрипты на python 15
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
    import bpy geometry =bpy.data.meshes['place'] for obj in bpy.context.selected_objects: obj.rotation_euler.x = 0 obj.rotation_euler.y = 0 obj.data = geometry obj.location.z = 0 21
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    OpenGL 1.5 OpenGL2.0 OpenGL 3.3 OpenGL 4.5 OpenGL ES 1.1 OpenGL ES 2.0 OpenGL ES 3.0 Vulkan WebGL 1.0 WebGL 2.0 27 WebGL Next?
  • 28.
  • 29.
  • 30.
    2D vs 3D[2] 30
  • 31.
    2D 31 <canvas id="canvas" width="100"height="100"></canvas> <script> (function() { const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); context.fillStyle = 'rgba(255, 0, 0, 1)'; context.fillRect(25, 25, 50, 50); }()); </script>
  • 32.
    3D 32 <canvas id="canvas" width="100"height="100"></canvas> <script> (function() { const canvas = document.getElementById('canvas'); const gl = canvas.getContext('webgl'); // Инициализировать шейдеры // Создать программу // Создать вершинный буфер // Сохранить ссылку на буферный объект в атрибут // Вызвать отрисовку }()); </script>
  • 33.
    Вершинный шейдер 33 const vertexShaderSource= ` attribute vec4 position; void main() { gl_Position = position; } `; const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexShaderSource); gl.compileShader(vertexShader);
  • 34.
    Фрагментный шейдер 34 const fragmentShaderSource= ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `; const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, vertexShaderSource); gl.compileShader(fragmentShader);
  • 35.
    Программа 35 const program =gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); gl.useProgram(program);
  • 36.
    Вершинный буфер 36 const vertices= new Float32Array([ -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5 ]); const vertexSize = 2; const vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); const attrPosition = gl.getAttribLocation(program, 'position'); gl.vertexAttribPointer(attrPosition, vertexSize, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(attrPosition);
  • 37.
    Отрисовка 37 const vertices =new Float32Array([ -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5 ]); const vertexSize = 2; // … gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / vertexSize);
  • 38.
  • 39.
    WebGL Programming Guide: Interactive3D Graphics: Programming with WebGL Авторы: Коичи Мацуда, Роджер Ли 39
  • 40.
  • 41.
    WebGL Framework • Удобныеабстракции • Краткий код • Никаких шейдеров (поначалу) 41
  • 42.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 42
  • 43.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 43
  • 44.
  • 45.
  • 46.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 46
  • 47.
  • 48.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 48
  • 49.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 49
  • 50.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; geometry = new THREE.BoxGeometry( 200, 200, 200 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 50
  • 51.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; var loader = new THREE.ObjectLoader(); loader.load('model.json', function(mesh) { scene.add(mesh); }); ry = renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 51
  • 52.
    SVG Blender { "metadata": { "version":4.4, "sourceFile": "model.blend", "generator": "io_three", "type": "Object" }, "geometries": [ ... ], "materials": [ ... ], "object": { ... } } JSON io_three 52
  • 53.
  • 54.
  • 55.
    Больше контроля 55 <script src="three/build/three.js"></script> <scriptsrc="three/examples/js/controls/OrbitControls.js"></script>
  • 56.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; var loader = new THREE.ObjectLoader(); loader.load('model.json', function(mesh) { scene.add(mesh); }); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 56
  • 57.
    var scene, camera,renderer, geometry, material, mesh; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); camera.position.z = 1000; new THREE.OrbitControls(camera); var loader = new THREE.ObjectLoader(); loader.load('model.json', function(mesh) { scene.add(mesh); }); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); } function animate() { requestAnimationFrame( animate ); mesh.rotation.y += 0.02; renderer.render( scene, camera ); } 57
  • 58.
  • 59.
    Interactive 3D GraphicsCourse With Three.js & WebGL https://www.udacity.com/course/interactive-3d-graphics--cs291 59
  • 60.
  • 61.
    Viewer 61 • Модельс запеченными тенями • Рейкастинг объектов • Спрайты для иконок
  • 62.
  • 63.
  • 64.
    Viewer UI Redux store 64 { type:'SELECT_FLOOR', floor: 10 }
  • 65.
  • 66.
  • 67.
    Сглаживание 67 // WebGL: const gl= canvas.getContext("webgl", { antialias: true }); // three.js: const renderer = new THREE.WebGLRenderer({ antialias: true });
  • 68.
    На взлет 68 function animate(){ requestAnimationFrame(animate); renderer.render(scene, camera); }
  • 69.
    Не рендерить всевремя 69 Начало движения камеры Конец движения камеры Запуск рендеринга Остановка рендеринга Изменение состояния приложения Отрендерить один кадр
  • 70.
    Raycasting 70 const raycaster =new THREE.Raycaster(); raycaster.setFromCamera(normalizedMouseCoordinates, camera); const intersects = raycaster.intersectObjects(objects);
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
    Instancing 80 • Сильно повышаетпроизводительность
  • 81.
    Instancing 81 • Сильно повышаетпроизводительность • Сложно https://goo.gl/zdaWZU
  • 82.
  • 83.
  • 84.
  • 85.
    Сжатые текстуры Плюсы: • В4 раза меньше видеопамяти занимают Ограничения: • Разные форматы: DXT, PVRTC, ETC • Ухудшение картинки • Проблемы с прозрачностью • Больший объем файлов (но можно применить gzip) 85 https://goo.gl/swsgxR
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
    You are notalone 90
  • 91.
    Ссылки Курс по трехмернойграфике на Udacity Книга "Программирование трехмерной графики" Примеры threejs Видео про рендеринг текста в WebGL (слайды) Видео про производительность WebGL (статья) 91
  • 92.

Editor's Notes

  • #41 no shaders
  • #47 Разобрать пример Добавить про controls
  • #71 Хотелось бы картинку как это происходит
  • #90 Меньше полигонов, текстуры проще, эффектов меньше