Uploaded by Denis Sigida

Индивидуально задание WebGL

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
«ЛУГАНСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ
ИМЕНИ ВЛАДИМИРА ДАЛЯ»
Факультет компьютерных систем и информационных технологий
Кафедра информатики и программной инженерии
Индивидуальная работа
_____________Моделирование и анимация 3D объекта “Шкаф”____________
______________________________________________________________
______________________________________________________________
(название темы индивидуальной работы)
Студент-исполнитель
Приняли:
Оценка:
Матвиенко В.В.____________________
(Ф.И.О., подпись)
2-й курс, ИТ-692___________________
(курс, группа)
Ромашова О. Н.__________________
(Ф.И.О., подпись)
ЧигринаА. Н.______________________
(Ф.И.О., подпись)
__________________________________
Луганск 2020
2
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
«ЛУГАНСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ
ИМЕНИ ВЛАДИМИРА ДАЛЯ»
Факультет компьютерных систем и информационных технологий
Кафедра информатики и программной инженерии
Направление подготовки: 09.03.04 – Программная инженерия
(шифр и название)
ЗАДАНИЕ
НА ИНДИВИДУАЛЬНУЮ РАБОТУ
студенту Матвиенко Виталию Валерьевичу
1. Тема работы: «Моделирование и анимация 3D объекта в WebGL»;
2. Руководитель работы: Ромашова Ольга Николаевна, старший
преподаватель;
3. Срок представления студентом работы: 25.12.2020;
4. Содержание индивидуальной работы:
а) Реферат
б) Основной текст
в) Список источников
г) Приложения
5. Дата выдачи задания: 02.12.2020.
3
ЗАДАНИЕ ДЛЯ ИНДИВИДУАЛЬНОЙ РАБОТЫ
Прорисовка, текстурирование и анимация 3D модели «Шкаф» на
WebGL. Программа должна иметь интерфейс со следующими возможностями:
1)
Предоставлять пользователю возможность менять положение
источника света (по осям);
2)
изменять интенсивность освещенности по нажатию на кнопку
(использовать выпадающий список с возможностью изменения мощности
освещения в процентах);
3)
вращать объект вокруг осей (с возможностью выбора вида оси OX,
OY, OZ);
4)
масштабировать объект (выбор масштаба с помощью кнопки из
выпадающего списка);
5)
шагом.
перемещать объект на заданное расстояние по осям с выбранным
4
РЕФЕРАТ
Работа содержит: 6 страниц основного текста, 11 страниц приложений,
6 рисунков, 3 использованный источник.
Работа состоит из трех разделов, введения, выводов и приложений.
Объект исследования: язык WebGL и прилежащих к ней библиотек.
Методы исследования: изучение лекции и методических указаний.
Целью работы: является прорисовка, текстурирование и анимация 3D
модели «Шкаф» на языке WebGL.
Результаты исследования: в процессе работы был смоделирован
объект “Шкаф” и добавлены возможности такие как, менять положение
источника света (по осям); изменять интенсивность освещенности по нажатию
на кнопку; вращать объект вокруг осей; масштабировать объект; перемещать
объект на заданное расстояние по осям с выбранным шагом.
Ключевые слова: WEBGL, ТЕКСТУРИРОВАНИЕ, ПРОРИСОВКА.
5
СОДЕРЖАНИЕ
ВВЕДЕНИЕ............................................................................................................. 6
РАЗДЕЛ 1. СОЗДАНИЕ ТРЕХМЕРНОЙ МОДЕЛИ ШКАФ ....................... 7
1.1 ДЕТАЛИ ДЛЯ ОБЪЕКТА ШКАФ .............................................................. 7
РАЗДЕЛ 2. СОЗДАНИЕ ОСВЕЩЕНИЯ И АНИМАЦИИ ОБЪЕКТА ....... 8
1.1 ОСВЕЩЕНИЕ ............................................................................................... 8
1.2 АНИМАЦИЯ ................................................................................................. 9
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ ..................................... 12
ПРИЛОЖЕНИЯ .................................................................................................. 13
6
ВВЕДЕНИЕ
WebGL является 3D графической библиотекой, которая позволяет
современным интернет-браузерам отрисовывать 3D-сцены стандартным и
эффективным способом. WebGL имеет клиенто-ориентированный подход;
элементы, которые составляют части 3D-сцены, обычно загружаются с
сервера. Однако, вся дальнейшая обработка, необходимая для получения
изображения выполняется локально, с помощью графического оборудования
клиента.
В проекте будет рассмотрена задача моделирования различных
объектов, добавление анимации и освещения.
7
РАЗДЕЛ 1
СОЗДАНИЕ ТРЕХМЕРНОЙ МОДЕЛИ ШКАФ
1.1 ДЕТАЛИ ДЛЯ ОБЪЕКТА ШКАФ
Данная модель будет создаваться с помощью функций библиотеки
Three.js, которая уменьшает количество строк при написании кода.
Для того, чтобы получить модель шкафа нужно создать отдельные
детали. Т.е. создать полки, боковые стороны, а также верхнюю, нижнюю и
заднюю сторону шкафа. (Рис. 1.1).
Рис.1.1 - Модель шкафа с его сторонами и
полками (без текстуры и дверей)
Рис. 1.2 - Каркасная модель
шкафа
8
Рис. 1.3 – Модель с текстурой
Создать
геометрию
куба
можно
с
помощью
функции
THREE.BoxGeometry(). В скобках задаем значения (x,y,z).
var cubeGeometry = new THREE.BoxGeometry (43,49,0);
После чего используем функцию THREE.MeshPhongMaterial(), в
которой устанавливаем материал и цвет (или текстуру) объекта.
var cubeMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
Объединяем объект и материал с текстурой, функцией THREE.Mesh().
Проделываем данные шаги для каждой детали. После чего детали соединяем
в один объект. И добавляем в сцену (Полный код JavaScript документа в
Приложении А.1).
9
РАЗДЕЛ 2
СОЗДАНИЕ ОСВЕЩЕНИЯ И АНИМАЦИИ ОБЪЕКТА
1.1 ОСВЕЩЕНИЕ
Освещение в библиотеке Three.js создается с помощью функции
THREE.PointLight():
light = new THREE.PointLight( 0xFFFF00,1);
Первым значением устанавливаем цвет в (hex формате), а вторым
интенсивность света.
1.2 АНИМАЦИЯ
Для того, чтобы анимировать наш объект, требуется создать функции,
которые будут управлять моделью.
В HTML коде напишем тег <input> и зададим такие параметры (Полный
код HTML в Приложении Б.1):
<input type="range" min="-150" max="150" id="line"
oninput="testMy()" value="0">
Атрибут oninput это название нашей функции, которая будет
использоваться в документе JavaScript.
function testMy() { //Ползунок вращения по оси X
line = document.getElementById("line").value;
shkaf.rotation.x = line*0.02;}
10
Используя переменную line (в которой будет храниться значение
ползунка) и функцию rotation.x, пользователь будет иметь возможность
вращать объект по оси X (Рис. 2.1).
Рис. 2.1 - Вращение по всем осям (OX,OY.OZ)
Таким образом создаются функции для передвижения освещения
(Рис.2.2),
Рис. 2.2 - Предоставить пользователю возможность менять положение
источника света (по осям);
11
Функция передвижения объекта “Шкаф” (Рис. 2.3),
Рис. 2.3 - Перемещение объекта на заданное расстояние, по осям с
выбранным шагом.
Функция приближения (Рис. 2.4)
Рис. 2.4 - Приближение объекта с помощью выпадающего списка
12
Функция интенсивности света (Рис. 2.5).
Рис. 2.5 - Изменение интенсивности освещения по нажатию на кнопку
13
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1.
WebGL: программирование трехмерной графики. / Пер. с англ.
Киселев А. Н. – М.: ДМК Пресс, 2015. – 494 с.: ил.
2.
"3D-МОДЕЛИРОВАНИЕ
НА
WEBGL
С
ПОМОЩЬЮ
БИБ­ЛИОТЕКИ THREE.JS: Учебное пособие", Вильданов А.Н. 2014 г., 114 с.
3.
Основы Three.js < threejsfundamentals.org/threejs/lessons/ru/>
14
ПРИЛОЖЕНИЯ
15
Приложение А (код из документа JavaScript)
var scene, renderer, camera;
var cubeback;
var cameraCenter = new THREE.Vector3();
var cameraHorzLimit = 50;
var cameraVertLimit = 10;
var mouse = new THREE.Vector2();
// ==-=-=-=-=-=-=-=-=-=-=-=-=-SHKAF-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
var shkaf = new THREE.Object3D();
//=============================Функции
передвижения=============================
function testMy() { //Ползунок изменения положения по X
line = document.getElementById("line").value;
shkaf.rotation.x = line*0.02;
}
function test1My(){//Ползунок изменения положения по Y
line1 = document.getElementById("line1").value;
shkaf.rotation.y = line1*0.02;
}
function test2My(){//Ползунок изменения положения по Y
line1 = document.getElementById("line2").value;
shkaf.position.z = line1;
}
//=========================Перемещение с шагом==========================
function posMy() { //Ползунок изменения положения по X
pos = document.getElementById("pos").value;
shkaf.position.x = pos;
}
function pos1My(){//Ползунок изменения положения по Y
pos1 = document.getElementById("pos1").value;
shkaf.position.y = pos1;
}
function pos2My(){//Ползунок изменения положения по Y
pos1 = document.getElementById("pos2").value;
shkaf.position.z = pos1;
}
//=========================ZOOM==========================
function zoom(){
zoom1 = document.getElementById("zoom_p").value;
camera.position.z = zoom1;
}
function lightMy(){
inst = document.getElementById("light").value;
light.position.x = inst;
}
function light1My(){
inst1 = document.getElementById("light1").value;
light.position.y = inst1;
}
function light2My(){
inst2 = document.getElementById("light2").value;
light.position.z = inst2;
}
function inten(){
intens = document.getElementById("intens").value;
16
return intens;
}
init();
animate();
function init()
{
renderer = new THREE.WebGLRenderer( {antialias:true} );
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize (width, height);
document.body.appendChild (renderer.domElement);
//TEXTURE
scene = new THREE.Scene();
//задняя сторона-----------------------------------------------------var cubeGeometry = new THREE.BoxGeometry (43,49,0);
var cubeMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubeback = new THREE.Mesh (cubeGeometry, cubeMaterial);
cubeback.rotation.y = 3.14;
cubeback.position.set (-7, 25, 0);
//-------------------------------------------------------------------//left
var cubeleft;
var cubeleftGeom = new THREE.BoxGeometry (1,38.88,9);
var cubeleftMaterial = new
THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubeleft = new THREE.Mesh (cubeleftGeom, cubeleftMaterial);
cubeleft.position.set (-15, 20, 5);
//-------------------------------------------------------------------//right
var cuberight;
var cuberightGeom = new THREE.BoxGeometry (-1,50,10);
var cuberightMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cuberight = new THREE.Mesh (cuberightGeom, cuberightMaterial);
cuberight.position.set (15, 25, 5);
//left 2)
var cubeleft2;
var cubeleft2Geom = new THREE.BoxGeometry (-1,50,10);
var cubeleft2Material = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubeleft2 = new THREE.Mesh (cubeleft2Geom, cubeleft2Material);
cubeleft2.position.set (-28.98, 25, 5);
//top
var cubeTop;
var cubeTopGeom = new THREE.BoxGeometry (-45,1,10);
var cubeTopMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubeTop = new THREE.Mesh (cubeTopGeom, cubeTopMaterial);
17
cubeTop.position.set (-7, 50, 5);
//-------------------------------------------------------------------//middlepalka
var cubemiddle;
var cubemiddleGeom = new THREE.BoxGeometry (1,50,9);
var cubemiddleMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubemiddle = new THREE.Mesh (cubemiddleGeom, cubeleftMaterial);
cubemiddle.position.set (0, 25, 5);
//-------------------------------------------------------------------//pol
var cubePol;
var cubePolGeom = new THREE.BoxGeometry (-45,1,10);
var cubePolMaterial = new THREE.MeshPhongMaterial ({map: new
THREE.TextureLoader().load('img/derevo.png')});
cubepol = new THREE.Mesh (cubePolGeom, cubePolMaterial);
cubepol.position.set (-7, 0.1, 5);
//------------------------------------------------------------//veshalka
const Cyllgeometry = new
THREE.CylinderBufferGeometry(0.5, 0.5, 14, 25);
var CyllMaterial = new THREE.MeshPhongMaterial
({color: 0x808080});
cylinder = new THREE.Mesh (Cyllgeometry, CyllMaterial);
cylinder.position.set (7, 45, 7);
cylinder.rotation.z = 1.57;
//polka1--------------------------------------------------------------var polka1;
var polka1Geom = new THREE.BoxGeometry (-13.98,1,9);
var polka1Material = new THREE.MeshPhongMaterial ({color: 0xA0522D});
polka1 = new THREE.Mesh (polka1Geom, polka1Material);
polka1.position.set (-7.5, 10, 5);
//polka2--------------------------------------------------------------var polka2;
var polka2Geom = new THREE.BoxGeometry (-13.98,1,9);
var polka2Material = new THREE.MeshPhongMaterial ({color: 0xA0522D});
polka2 = new THREE.Mesh (polka2Geom, polka2Material);
polka2.position.set (-7.5, 20, 5);
//polka3--------------------------------------------------------------var polka3;
var polka3Geom = new THREE.BoxGeometry (-13.98,1,9);
var polka3Material = new THREE.MeshPhongMaterial ({color: 0xA0522D});
polka3 = new THREE.Mesh (polka3Geom, polka3Material);
polka3.position.set (-7.5, 30, 5);
//bigpolka--------------------------------------------------------------var bigpolka;
var bigpolkaGeom = new THREE.BoxGeometry (-27.98,1,9);
var bigpolkaMaterial = new THREE.MeshPhongMaterial ({color: 0xA0522D});
bigpolka = new THREE.Mesh (bigpolkaGeom, bigpolkaMaterial);
bigpolka.position.set (-14.5,40, 5);
//light------------------------------------------------------------------var intena = inten();
light = new THREE.PointLight( 0xFFFF00,intena);
scene.add( light );
// Geometry
===============================================================Doska black
and White
var cbgeometry = new THREE.PlaneGeometry( 500, 500, 8, 8 );
18
// Materials
var cbmaterials = [];
cbmaterials.push(
side: THREE.DoubleSide })
cbmaterials.push(
side: THREE.DoubleSide })
new THREE.MeshPhongMaterial( { color: 0xffffff,
);
new THREE.MeshPhongMaterial( { color: 0x000000,
);
var l = cbgeometry.faces.length / 2; // <-- Right here. This should
still be 8x8 (64)
console.log("This should be 64: " + l);// Just for debugging
puporses, make sure this is 64
for( var i = 0; i < l; i ++ ) {
j = i * 2; // <-- Added this back so we can do every other 'face'
cbgeometry.faces[ j ].materialIndex = ((i + Math.floor(i/8)) %
2); // The code here is changed, replacing all 'i's with 'j's. KEEP THE 8
cbgeometry.faces[ j + 1 ].materialIndex = ((i + Math.floor(i/8))
% 2); // Add this line in, the material index should stay the same, we're
just doing the other half of the same face
}
// Mesh
cb = new THREE.Mesh( cbgeometry, new THREE.MeshPhongMaterial(
cbmaterials ) );
cb.position.x = -Math.PI/2;
cb.position.y = -Math.PI/2;
cb.rotation.set(300,0,0);
scene.add( cb )
// Geometry
===============================================================Doska black
and White
//add to Object3D:
shkaf.add(polka1,polka2,polka3,bigpolka);
shkaf.add(cubepol);
shkaf.add(cylinder);
shkaf.add(cubemiddle);
shkaf.add(cubeTop);
shkaf.add(cubeback);
shkaf.add(cubeleft,cuberight,cubeleft2);
// add shkaf to scene
scene.add(shkaf);
shkaf.position.x = 0;
camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000);
camera.position.x = 0;
camera.position.y = 60;
camera.position.z = 250;
camera.rotation.x = -0.2;
//camera.lookAt (new THREE.Vector3(0,0,0));
renderer.setClearColor (0x87CEEB, 1); //87CEEB
}
function animate()
{
//updateCamera();
requestAnimationFrame ( animate );
renderer.render (scene, camera);
}
19
Приложение Б (код из документа HTML)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lab</title>
<style type="text/css">
body {
margin-top: 0;
margin-left: 0;
}
.box {
width: 100%;
height: 90px;
background-image:
url("https://wallpaper-mania.com/wpcontent/uploads/2018/09/High_resolution_wallpaper_background_ID_77701893136.j
pg");
color: #FFFFFF;
}
#my {
margin-top: 0%;
padding-top: 0px;
margin-left: 5%;
position: absolute;
}
#my1 {
margin-top: 2%;
padding-top: 0px;
margin-left: 5%;
position: absolute;
}
#my2 {
margin-top: 4%;
padding-top: 0px;
margin-left: 5%;
position: absolute;
}
#my3 {
margin-left: 27%;
margin-top: 0%;
padding-top: 0px;
position: absolute;
}
#my4 {
margin-left: 45%;
margin-top: 0%;
padding-top: 0px;
position: absolute;
}
#my5 {
margin-left: 45%;
margin-top: 2%;
padding-top: 0px;
position: absolute;
}
#my6 {
margin-left: 45%;
margin-top: 4%;
padding-top: 0px;
20
position: absolute;
}
#my7 {
margin-left: 27%;
margin-top: 2%;
padding-top: 0px;
position: absolute;
}
#my8 {
margin-left: 70%;
margin-top: 0%;
padding-top: 0px;
position: absolute;
}
#my9 {
margin-left: 70%;
margin-top: 2%;
padding-top: 0px;
position: absolute;
}
#my10 {
margin-left: 70%;
margin-top:4%;
padding-top: 0px;
position: absolute;
}
</style>
</head>
<body>
<div class="box">
<!-- Ползунки изменения !-->
<div id="my"> <input type="range" min="-150" max="150" id="line"
oninput="testMy()" value="0">
Повернуть шкаф по оси X</div>
<div id="my1"> <input type="range" min="-150" max="150" id="line1"
oninput="test1My()" value="0">
Повернуть шкаф по оси Y</div>
<div id="my2"> <input type="range" min="-100" max="100" id="line2"
oninput="test2My()" value="0">
Повернуть шкаф по оси Z</div>
<!-- ---------------------------Выпадающий список-----------------------!-->
<div id="my3">Приблизить объект на: <select name = "blacklist" oninput="zoom()"
id="zoom_p">
<option value = "150" selected>0%</option>
<option value = "100">50%</option>
<option value = "50" >100%</option>
</select></div>
<!---------------------Ползунки изменения-----------------!-->
<div id="my4"> <input type="range" min="-100" max="100" step="50" id="pos"
oninput="posMy()" value="0">
Переместить шкаф по оси X</div>
<div id="my5"> <input type="range" min="-20" max="20" step="10" id="pos1"
oninput="pos1My()" value="0">
Переместить шкаф по оси Y</div>
<div id="my6"> <input type="range" min="-100" max="100" step="50" id="pos2"
oninput="pos2My()" value="0">
Переместить шкаф по оси Z</div>
<!-- ---------------------------Освещение-----------------------!-->
<div id="my8"> <input type="range" min="-500" max="500" id="light"
21
oninput="lightMy()" value="0">
Переместить свет по оси X</div>
<div id="my9"> <input type="range" min="-500" max="500"
oninput="light1My()" value="0">
Переместить свет по оси Y</div>
<div id="my10"> <input type="range" min="-500" max="500"
oninput="light2My()" value="0">
Переместить свет по оси Z</div>
<div id="my7">Освещение на: <select name
id="intens">
<option value = "0.8" selected>0%</option>
<option value = "0.5">50%</option>
<option value = "1" >100%</option>
</select></div>
</div>
=
id="light1"
id="light2"
"blacklist"
<script type="text/javascript" src="three.js"></script>
<script type="text/javascript" src="webgl.js"></script>
</body>
</html>
oninput="inten()"
Download