WebGL тур по сонячній системі: Марс, частина 1

19

Від автора: у попередній статті я познайомив вас з WebGL. Також я пояснив, чому для створення нативного 3D контенту на сторінках буду використовувати фреймворк threeJS для демонстрації можливостей WebGL. У цій статті я покажу вам, як зробити 3D камеру і кнопки для взаємодії між WebGL контентом і HTML-сторінкою.

Я все пояснюю ретельно і покроково в міру нашого просування, в цій статті ви не навчитеся рендери сцени. Про це я розповім у супровідних статтях по створенню сцен. Хочете побачити кінцевий результат – можете подивитися демо на CodePen.

Музика сфер

WebGL може бути єдиним контентом на сторінці, однак у даної технології є одна перевага. WebGL є веб-технологією, заснованої на стандартах, що означає, що її можна легко інтегрувати з HTML контентом. У canvas бракує доступності та SEO, тому було б розумно створювати WebGL сцену прогресивно: текст буде представлений у вигляді HTML-тексту з додаванням WebGL контенту там, де це можливо. Для нашої сторінки про Марсі нам знадобиться наступна розмітка:

Mars

Home to both the Solar System’s highest mountain…

Елемент marsloc буде зберігати наш WebGL контент для рендеринга, поверх якого буде лежати HTML контент. Робиться це за допомогою CSS на Sass:

body {
background: black;
margin: 0;
min-height: 100vh;
color: #fff;
}
#marsloc {
cursor: grab;
}
#marsinfo {
position: absolute;
top: 0;
width: 100%;
padding: 2rem;
}
#marsinfo h1 {
font-size: 8vw;
margin-top: 0;
font-weight: 100;
line-height: 1;
position: absolute;
}
#marsinfo div {
width: 40%;
position: absolute;
background-color: rgba(0,0,0,0.3);
right: 0;
padding: 1.3 rem;
line-height: 1.6;
font-size: 1.2 rem;
pointer-events: none;
@all media and (max-width: 540px) {
width: 100%;
left: 0;
top: 40vw;
}
}

Курсор у вигляді руки на елементі #marsloc – це UI підказка для WebGL контенту. Блоку div всередині #marsinfo встановлено властивість pointer-events: none, щоб його вміст не заважав при взаємодії з планетою.

Створення планети

HTML і CSS є, залишилося підключити останню версію threeJS з CDN у нижній частині сторінки:

Бібліотека threeJS повинна бути підключена раніше, ніж ми почнемо використовувати її код.

Наш наступний файл-скрипт починається з встановлення ряду змінних і констант, які будуть використовуватися в нашому коді:

var container, controls, camera, renderer, scene, light, marsMesh,
clock = new THREE.Clock();
const imgLoc = «https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/»;

Змінна clock допоможе нам анімувати руху Марса за замовчуванням. imgLoc – положення всіх зображень. Змінна оголошена тут, щоб потім не повторюватися.

Область огляду

Перший елемент, який ми створимо, буде камера. Камера потрібна, щоб «бачити» створену нами сцену. У threeJS є кілька типів камер:

perspectiveCamera: паралельні лінії у сцені будуть сходитися, якщо вони досить довгі (уявіть, що ви стоїте посеред залізничних шляхів і дивіться вдалину). Далекі об’єкти будуть мати менший розмір. Задіяний принцип нашого зору, то, як ми бачимо світ.

OrthographicCamera: паралельні лінії у сцені не перетинаються незалежно від їх довжини. Об’єкти не стають менше по мірі віддалення. Така камера добре підходить для візуалізації UI елементів і деяких архітектурних видів.

Для камери з перспективою нам також знадобиться поставити «область огляду (часто скорочується як FOV). FOV – кут огляду камери. Вузька область огляду фокусує камеру на окремій частині сцени (уявіть кінь, на яку одягли захисні окуляри, звужують область огляду, щоб та не лякалася і не відволікалася). Візуальні елементи, що не входять в цю область, відсікаються. Широка область огляду бачить більше, але об’єкти стають менше і відсуваються далі.

Також нам знадобиться задати співвідношення сторін камери: коефіцієнт відношення ширини до висоти отрендеренного виду. Ви, швидше за все, знаєте про співвідношення сторін з кіно. Широкоформатні фільми, як правило, більш «кинематографичные» і захоплюючі. Низьке співвідношення сторін (ближче до квадрату) надає фільму інтимності і старить фільм.

Майже у всіх випадках співвідношення сторін має відображати вікно користувача: тобто ширина вікна браузера, розділена на його висоту.

Останні два значення камери – ближня і дальня площини відсікання — near та far. За замовчуванням 3D камера «дивиться» нескінченно вдалечінь: на відміну від реального світу, тут об’єктив 3D камери не закривається частками, зваженими в атмосфері, а також не обмежується можливостями лінз. В іграх цей ефект часто називають «дальність промальовування». Одна з причин, чому в ранніх 3D іграх було багато туману і вузьких коридорів – чим менше елементів треба малювати, тим швидше гра.

Нам потрібно, щоб ближня січну площину камери була майже впритул до уявної лінзі, а дальня – на розумній відстані. Між двома площинами відсікання будуть знаходитися наші елементи сцени. Код:

camera = new THREE.PerspectiveCamera(45,
window.innerWidth / window.innerHeight, 0.1, 10000);

Зараз наша камера літає в нескінченному чорному просторі і ні на що не дивиться. У наступній статті я розповім про суть 3D простору, як її висвітлити, а також як додавати об’єкти на сцену.