Отчет по ЛР 4 МО-
.docxУФИМСКИЙ ГОСУДАРСТВЕННЫЙ АВИАЦИОННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра вычислительной математики и кибернетики
Лабораторная работа № 4
«Программирование WebGL графики»
Выполнил:
студент группы МО-
Проверил:
Котельников В.А
Уфа, 2021
Оглавление
Теоретическая информация: 3
Ход работы: 3
Листинг программы 4
Цель работы: изучить основы программирования WebGL графики.
Задание: Рассмотреть примеры компьютерной графики в html5 (открывать в IE). Визуализировать Солнечную систему.
Теоретическая информация:
WebGL — кроссплатформенный API для 3D-графики в браузере, разрабатываемый некоммерческой организацией Khronos Group. WebGL использует язык программирования шейдеров GLSL. WebGL исполняется как элемент HTML5 и поэтому является полноценной частью объектной модели документа (DOM API) браузера. Может использоваться с любыми языками программирования, которые умеют работать с DOM API, например, JavaScript, Rust, Java, Kotlin и другими.
PerspectiveCamera дает трехмерный вид, где вещи на расстоянии кажутся меньше, чем вещи рядом.
Three.js это 3D-библиотека, которая максимально упрощает создание 3D-контента на веб-странице.
PointLight и HemisphereLight – источники освещения.
MeshMaterial - это более-менее физически корректный материал
Ход работы:
Рисунок 1
Рисунок 2
На рисунках 1 и 2 представлен результат работы программы.
Вывод: в ходе выполнения лабораторной работы, я научилась программировать WEB графику.
Листинг программы
Index.html:
<!DOCTYPE html>
<html>
<head>
<title>Solar System</title>
<meta charset="utf-8" />
<style type="text/css">
body,
html {
margin: 0;
padding: 0;
}
canvas {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<canvas id="scene"></canvas>
<script src="./three.min.js"></script>
<script src="./index.js"></script>
</body>
</html>
index.js:
function main() {
// Находим холст для отрисовки
const canvas = document.getElementById("scene");
// Создаем рендерер
const renderer = new THREE.WebGLRenderer({ canvas });
// Параметры камеры
const fov = 40;
const far = 1000;
const aspect = 2;
const near = 0.1;
// Создаем камеру
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// Устанавливаем положение для камеры
camera.position.set(0, 60, 0);
camera.up.set(0, 0, 1);
// Указываем куда ей смотреть
camera.lookAt(0, 0, 0);
// Создаем сцену
const scene = new THREE.Scene();
// Параметры источника освещения
const color = 0xffffff;
const intensity = 2;
// Создаем источник освещения. PointLight - рассеивающийся свет, как-будто лампочка
const light = new THREE.PointLight(color, intensity);
light.position.set(0, 10, 0);
// Добавляем свет на сцену
scene.add(light);
// Массив для хранения объектов (он нужен для того, чтобы постоянно к нему обращаться и вращать объекты, которые находятся в нем)
const objects = [];
//Для вращения самого обьекта системы
const array = [];
// Параметры геометрии
const radius = 1;
const widthSegments = 355;
const heightSegments = 355;
// Создаем геометрию
const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);
// Создаем материал. MeshMaterial - это более-менее физически корректный материал
const sunMaterial = new THREE.MeshPhongMaterial({ emissive: 0xffff00 });
// Создаем меш. Просто накладывает материал на геометрию и формирует единый объект.
const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);
// Увеличиваем солнце
sunMesh.scale.set(4, 4, 4);
// Добавляем солнце на сцен
scene.add(sunMesh);
array.push(sunMesh);
const mercuryMaterial = new THREE.MeshPhongMaterial({
color: "red",
emissive: "black",
});
const mercuryMesh = new THREE.Mesh(sphereGeometry, mercuryMaterial);
mercuryMesh.position.x = mercuryMesh.originalPosition = 6;
mercuryMesh.scale.set(0.5, 0.5, 0.5);
scene.add(mercuryMesh);
objects.push(mercuryMesh);
array.push(mercuryMesh);
const venusMaterial = new THREE.MeshPhongMaterial({
color: "orange",
emissive: "black",
});
const venusMesh = new THREE.Mesh(sphereGeometry, venusMaterial);
venusMesh.position.x = venusMesh.originalPosition = 9;
scene.add(venusMesh);
objects.push(venusMesh);
array.push(venusMesh);
// Создаем контейнер для хранения орбиты земли
const earthOrbit = new THREE.Object3D();
// Устанавливаем флаг, что это орбита, чтобы мы этот объект поворачивали вокруг его оси.
earthOrbit.isOrbit = true;
// Устанавливаем позицию для этого объекта
earthOrbit.position.x = earthOrbit.originalPosition = 13;
const earthMaterial = new THREE.MeshPhongMaterial({
color: 0x2233ff,
emissive: 0x112244,
});
const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
earthOrbit.add(earthMesh);
scene.add(earthOrbit);
objects.push(earthOrbit);
array.push(earthMesh);
const marsMaterial = new THREE.MeshPhongMaterial({
color: "red",
emissive: "black",
});
const marsMesh = new THREE.Mesh(sphereGeometry, marsMaterial);
marsMesh.position.x = marsMesh.originalPosition = 17;
marsMesh.scale.set(0.5, 0.5, 0.5);
scene.add(marsMesh);
objects.push(marsMesh);
array.push(marsMesh);
const jupiterMaterial = new THREE.MeshPhongMaterial({
color: "#964B00",
emissive: "black",
});
const jupiterMesh = new THREE.Mesh(sphereGeometry, jupiterMaterial);
jupiterMesh.position.x = jupiterMesh.originalPosition = 23;
jupiterMesh.scale.set(2, 2, 2);
scene.add(jupiterMesh);
objects.push(jupiterMesh);
array.push(jupiterMesh);
const saturnMaterial = new THREE.MeshPhongMaterial({
color: "#FF8000",
emissive: "black",
});
const saturnMesh = new THREE.Mesh(sphereGeometry, saturnMaterial);
saturnMesh.position.x = saturnMesh.originalPosition = 29;
saturnMesh.scale.set(1.9, 1.9, 1.9);
scene.add(saturnMesh);
objects.push(saturnMesh);
array.push(saturnMesh);
const uranusMaterial = new THREE.MeshPhongMaterial({
color: "#d4fafd",
emissive: "black",
});
const uranusMesh = new THREE.Mesh(sphereGeometry, uranusMaterial);
uranusMesh.position.x = uranusMesh.originalPosition = 33;
uranusMesh.scale.set(1.5, 1.5, 1.5);
scene.add(uranusMesh);
objects.push(uranusMesh);
array.push(uranusMesh);
const neptuneMaterial = new THREE.MeshPhongMaterial({
color: "#4e78ff",
emissive: "black",
});
const neptuneMesh = new THREE.Mesh(sphereGeometry, neptuneMaterial);
neptuneMesh.scale.set(1.4, 1.4, 1.4);
neptuneMesh.position.x = neptuneMesh.originalPosition = 38;
scene.add(neptuneMesh);
objects.push(neptuneMesh);
array.push(neptuneMesh);
// Функция для проверки того, необходимо ли изменить размер холста, в зависимости от размеров окна.
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function rotate(time) {
time *= 0.0001;
array.forEach((arr) => {
arr.rotation.y = time;
});
// Рекурсивно вызываем встроенную в браузер функцию "requestAnimationFrame" и передаем в неё функцию "rotate"
requestAnimationFrame(rotate);
}
rotate();
function render(time) {
// уменьшаем значение времени, чтобы оно просто не было большим (по факту ни на что не влияет)
time *= 0.1;
// Проверяет, нужно ли изменить размер сцены
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
const angle = Math.PI / 180;
objects.forEach((obj, index) => {
// Крутим объект по оси X
obj.position.x =
obj.originalPosition * Math.cos(angle * time * ((objects.length - index) * 0.2));
// Крутим объект по оси Z
obj.position.z =
obj.originalPosition * Math.sin(angle * time * ((objects.length - index) * 0.2));
// Если объект является орбитой, то ещё и вращаем его по оси Y
if (obj.isOrbit) {
obj.rotation.y = time * 0.01;
}
});
// рендерим сцену
renderer.render(scene, camera);
// Рекурсивно вызываем встроенную в браузер функцию "requestAnimationFrame" и передаем в неё функцию "render"
requestAnimationFrame(render);
}
render();
}
main();