Засади WebGL: розбираємося в магічному коді й заливаємо на хостинг


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

WebGL – технологія, яка “створює магію” у 2D, – canvas ‘е HTML5. Розповідаємо, як за допомогою градієнта добитися такого цікавого 3D-ефекту, як опуклість, не використовуючи додаткових бібліотек і детально пояснивши всю “магію”. Після завершення роботи з кодом ми заллємо наш проект на хостинг GPDHOST, щоб Ви могли поділитися результатом зі знайомими.

Код

Розпочнемо з прикладу: намалюємо прямокутник на екрані. Цей код повинен срендерити прямокутник з градієнтом:

%MINIFYHTMLe1289e2d54c8885a1254604fc35512342%%MINIFYHTMLe1289e2d54c8885a1254604fc35512343%%MINIFYHTMLe1289e2d54c8885a1254604fc35512344%

Насправді, код малює два трикутники, X і Y координати кожного пікселя використовуються як R і G значення кольору, а кольори всередині трикутників екстраполюються і в результаті виходить прямокутник із градієнтом.

Що відбувається?

Ми створюємо canvas об’єкт, який використовується для рендерингу, а також два “дивні” теги script.  Як тип у цих тегів Ви можете вказати все, що завгодно – головне, щоб Ви могли потім якось витягнути ці елементи з DOM через JS. Важливо вказати такий тип, який не розпізнаватиметься браузерами як “javascript”. Це дозволить нам додати невидимий багаторядковий вміст у документ, з яким ми зможемо працювати пізніше. Загалом, ці теги не мають якогось спеціального значення, це просто такий трюк, щоб додати потрібну нам інформацію в JS.

У коді ми бачимо два такі теги script. Їх вміст належить двом різним шейдерам, за допомогою яких ми “робитимемо магію”.

Про шейдери

Саме шейдери дозволяють зіставляти вхідні пікселі з вихідними пікселями і пікселі з вихідними кольорами. У нашому випадку є два шейдери: вершинний (vertex) шейдер, який зіставляє вхідні пікселі їх координатам, і фрагментний (fragment) шейдер, який зіставляє пікселі з їх кольорами.

У шейдерах є 4 основні типи “змінних”. Перший – це uniform. Ви можете визначити таку змінну за допомогою JS, але в шейдері вона буде read-only. Другий тип це attribute, який, умовно кажучи, використовується для отримання певних атрибутів точки. Третій – varying тип, він дозволяє нам пересилати дані з одного шейдера в інший. Четвертий і останній це const, він дозволяє створювати константи.

Крім них є ще float для чисел з плаваючою комою, типи vec1, vec2, vec3 і vec4 для векторів, які являють собою список чисел із плаваючою комою. Є також типи xyz, rgba і т. д. Очевидно, вони не мають особливих відмінностей, тому не розглядатимемо їх детально.

Як працює написаний вище код?

JS-код розпочинається з простої ініціалізації і початкового завантаження: отримання canvas, отримання gl- контексту і т. д.

Спочатку ми компілюємо обидва шейдери в одну “програму”:

var vertShaderObj = gl.createShader (gl.VERTEX_SHADER);var vertexShaderSrc = document.querySelector ('[type=" vertex"]').textContent;gl.shaderSource (vertShaderObj, vertexShaderSrc);gl.compileShader (vertShaderObj);
gl.attachShader (program, vertShaderObj);

Після компіляції перевіряємо, скомпілювалися шейдери або ні. Ви можете використати щось подібне до:

if (!gl.getShaderParameter (vertShaderObj, gl.COMPILE_STATUS)) console.error ("Could not compile shader: " + gl.getShaderInfoLog (vertShaderObj));

Так Ви зможете отримати більше інформації про те, чому компіляція завершилася невдало. Для відладки бажано використати Firefox, оскільки він видає більше подробиць про помилку, ніж Chrome.

Функції main шейдерів не повертають якихось значень. Замість цього вони повинні встановлювати змінну, яку перехопить WebGL. Проте для зручності називатимемо цю змінну повертаним значенням функції. Наприклад, вершинний шейдер повинен встановити змінну gl_Position, щоб повідомити WebGL, який саме піксель canvas ‘а ми зараз малюємо. Фрагментний шейдер повинен установити змінну fl_FragColor, яка призначає колір пікселя у форматі RGBA. Встановлюване значення цих змінних може бути будь-яким у діапазоні від − 1.0 до 1.0.

var positionLocation = gl.getAttribLocation (program, "a_pos"); – це отримання побайтового зміщення для змінної a_pos у скомпільованій програмі, яке потрібне для встановлення значення positionLocation.

Далі створюється буфер з точок, які ми використовуватимемо як параметри для малювання. Ми поміщаємо ці точки у буфер і говоримо WebGL, як їх інтерпретувати:

 gl.bufferData (gl.ARRAY_BUFFER, new Float32Array ([ // два прямокутники - 1.0, - 1.0, 1.0, - 1.0, - 1.0, 1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0]), gl.STATIC_DRAW);

Цей ” рядок” коду поміщає координати двох прямокутників у буфер. Екранні координати перераховані від − 1 до 1, з верхнього лівого кута до нижнього правого, тобто 12 значень вище – це, насправді, 6 координат вершин (<- 1, – 1>, <1, – 1>, <- 1,1>, <- 1,1>, <1, – 1>, <1,1>). STATIC_DRAW – це параметр для оптимізації, який для нас поки що не дуже важливий.

Тепер ми повідомимо WebGL, як використати ці точки:

gl.enableVertexAttribArray (positionLocation);gl.vertexAttribPointer (positionLocation, 2, gl.FLOAT, false, 0, 0);

Тут ми зв’язуємо кожну точку з a_post і переводимо кожні два числа в число з плаваючою комою.

Саме малювання трикутників відбувається в останньому рядку: gl.drawArrays (gl.TRIANGLES, 0, 6);. Тут три кожні три вектори об’єднуються в трикутники. Розберемося детальніше безпосередньо в процесі малювання.

Як WebGL “малює”?

Метод drawArrays працює з буфером, який ми підготували: малює трикутник з трьох пар координат.

Під час цього він застосовує main-функцию кожного шейдера для кожної з координат. Вершинний шейдер передає ці координати в gl_Position, встановлюючи z , що дорівнює 0 і w, що дорівнює 1. Він також кладе координати в varying змінні для використання у фрагментному шейдері. Фрагментный шейдер використовує вхідні координати, щоб встановити RGBA-значення змінної gl_FragColor: він бере vec2-координати і створює з них vec4 для додатка як RGBA значення (r=x, g=y, b=0, a=1).

Насправді ми лише повідомляємо WebGL, що треба намалювати ті 6 точок (3 на кожен трикутник) і екстраполювати кольори між кожною, щоб отримати градієнт. Коли ми малюємо три трикутники, вони заповнюють усю область перегляду. Ніхто реально не малює прямокутники, а складає їх з трикутників – це корисно для простоти і оптимізації.

Ось результат виконання нашого коду:

Давайте тепер поділимося своїм успіхом зі світом і заллємо нашу творчість на хостинг!

Розміщення проекту на хостингу

Щоб розмістити наш проект, скористаємося хостингом GPDHOST. Для нашого нескладного експерименту нам підійде план Starter. Для зручності ввійдіть на сайт – наприклад, через акаунт Google, а потім додайте план Starter у кошик. Далі Вам буде запропоновано вибрати доменне ім’я – виберіть вподобане Вами. Будь-який один домен у зоні .site, .party або .pro надається GPDHOST безкоштовно.

Після отримання доступу до контрольної панелі хостингу, можете переходити до розміщення веб-сторінки з JS-кодом на сайті. У розділі “Quick Server Logins” кликніть по імені вибраного Вами домена, і далі в “Quick Shortcuts” виберіть пункт “File Manager”. Вам відкриється таке вікно:

“Видимі” відвідувачам Вашого сайту HTML-сторінки повинні розташовуватися в теці public_html, виберіть її в дереві каталогів ліворуч. Далі кликніть на “Upload” у верхній частині сторінки і завантажте файл index.html. Щоб він коректно відображався при відкритті Вашого сайту, він повинен називатися index.html. Потім поверніться на сторінку, де був розташований розділ “Quick Shortcuts”, і трохи вище за цей розділ кликніть “Visit Website” – тепер Ви побачите на головній сторінці Вашого сайту canvas з ефектом опуклості.

Подивитися результат Ви можете в цьому прикладі.

Вітаємо, тепер Ви можете поділитися своїм проектом! Продовжуйте вивчати тему, щоб дати своєму проекту цікаві шляхи розвитку.

За матеріалами “Barrel distortion in WebGL”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *