Основи програмування шейдерів мовою GLSL. Частина 1 — Налаштування інструментів.

Captain GPU
8 min readOct 29, 2023

Привіт, це перша частина статей про основи програмування шейдерів за допомогою мови GLSL. У цій серії буде розказано про все, що стосується мови програмування GLSL. Про базові інструменти для вивчення, про синтаксис та семантику, про підходи та оптимізацію, а також про різні методи та алгоритми, що використовуються при програмуванні шейдерів.

Мова GLSL (OpenGL Shading Language) є однією з основних мов для програмування шейдерів, і ця серія статей допоможе вам навчитися програмувати цією мовою. Якщо ви не програміст — не переживайте, я постараюся зробити цю серію дуже простою для розуміння, яка не вимагатиме будь-яких початкових знань програмування.

У першій частині я розповім, як налаштувати основні інструменти за допомогою яких можна почати вивчати програмування шейдерів за допомогою мови GLSL, не обтяжуючи себе вивченням графічних API, таких як OpenGL або Vulkan. Так, знання графічних API дуже важливе для програмістів графіки (Graphics Programmer) або розробників систем рендерингу (Render Developer), але в той же час, розробляти шейдера можна в рамках технічного арту (Technical Art), а також для різних систем візуалізації та програм моделювання . Наприклад, розробка матеріалів у редакторі 3D-моделювання Blender та йому подібних, або для ігрових двигунів Unreal Engine та Unity.

У такому разі знання графічних API не потрібні, хоча можуть бути корисними. У цій серії буде поверхово і узагальнено пояснено як саме працюють сучасні графічні API та їх конвеєри малювання (graphics pipeline). Основний упор буде ставитися саме на мову GLSL, а речі, які пов’язують GLSL з певним графічним API, подаватимуться узагальнено, щоб було розуміння навіщо та чи інша річ присутня в GLSL, яка виходить за рамки мови.

Першим головним інструментом, який знадобиться для вивчення GLSL та написання шейдерів, є текстовий редактор або інтегрована система розробки (IDE). У цій серії з ряду причин використовуватиметься редактор коду Visual Studio Code.

Visual Studio Code є легким редактором, підтримує велику кількість платформ, має велику кількість інструментів для розробки шейдерів, а найголовніше — безкоштовний.

У цій серії статей, як операційна система системи я буду використовувати MacOS, але Visual Studio Code підтримує основні операційні системи, і її налаштування під інші системи практично ідентичні, та не повинні викликати у вас проблем.

Сторінка завантаження Visual Studio Code

На момент написання цієї частини, Visual Studio Code доступна за цим посиланням на офіційному сайті. Вам потрібно зайти на офіційний сайт та завантажити останню актуальну версію редактора, а також встановити її на свій комп’ютер.

Интерфейс Visual Studio Code

Ми не будемо оглядати редактор Visual Studio Code та всі його можливості, оскільки це серія про програмування шейдерів мовою GLSL, тому вивчення інтерфейсу та всіх можливостей редактора залишається за вами. Я лише можу порадити наступний матеріал, який допоможе вам розібратися у всіх тонкощах редактора.

Visual Studio Code є редактором коду, і не була спеціально розроблена для певної мови програмування. Підтримка тієї чи іншої мови програмування реалізована у Visual Studio Code за допомогою розширень (Extentions) і щоб Visual Studio Code підтримувала мову GLSL, потрібно встановити розширення для підтримки шейдерних мов.

Розділ розширень Visual Studio Code

Для цього потрібно перейти до розділу розширень (Extentions) і в полі пошуку ввести Shader languages support for VS Code і відкрити знайдене розширення кліком на нього.

Сторінка розширення Shader languages support for VS Code у Visual Studio Code

Вам потрібно встановити його, натиснувши кнопку Install. Це розширення додає Visual Studio Code можливість підсвічування синтаксису трьох шейдерних мов — GLSL, HLSL та Cg. Після перезавантаження редактора, він зможе без проблем ідентифікувати код мовою GLSL і відображати кольорові сигнатури різних конструкцій мови GLSL.

Додавання підтримки синтаксису до Visual Studio Code завершено, тепер нам потрібно додати підтримку стандартів мови GLSL відповідно до певного набору правил. Як згадувалося вище, Visual Studio Code не розроблена для певної мови програмування, і щоб вона могла визначати помилки в коді для цього потрібен лінтер, який перевіряв би код на помилки і відповідність правил програмування на GLSL. Для цього нам знадобиться лінтер та валідатор мови програмування GLSL.

Сторінка завантаження валідатора мови GLSL на GitHub

Насамперед нам знадобиться валідатор мови GLSL. Завантажити його можна з офіційного репозиторію, який на момент написання цієї частини знаходиться за цим посиланням. Завантажте версію для вашої операційної системи та збережіть її на своєму комп’ютері.

Сторінка розширення GLSL Linter у Visual Studio Code

Тепер нам знадобиться лінтер, який зв’яже валідатор GLSL та Visual Studio Code, щоб остання могла визначати невалідний код з помилкою. Лінтер мови GLSL для Visual Studio Code також реалізований як розширення. Тому вам потрібно знову увійти до розділу розширень і за допомогою рядка пошуку знайти GLSL Linter. Вам потрібно встановити це розширення, також на сторінці розширення ви можете ознайомитися з ним, його можливостями та налаштуваннями.

Налаштування розширення GLSL Linter у Visual Studio Code

Тепер потрібно налаштувати лінтер та вказати йому шлях до валідатора GLSL. Для цього перейдіть до розділу Settings редактора, виберіть підрозділ Extensions, і у списку розширень знайдіть GLSL linter configuration. Заповніть поле Validator Path, вказавши туди розміщення раніше завантаженого вами валідатора. Вказувати потрібно повний шлях до валідатора, а не тільки папку в якій він знаходиться. У випадку з Windows потрібно також вказати розширення .exe.

Тепер нам знадобиться останній інструмент, за допомогою якого ми бачитимемо результат роботи шейдера. Інструмент називає glsl-canvas, і він є готовою системою візуалізації, для якої можна розробляти шейдера як в режимі реального часу, стежачи за змінами в результаті, так і для кількох готових стандартних тривимірних моделей, доступ до яких надає glsl-canvas. Іншими словами, glsl-canvas дає нам можливість відразу бачити результат роботи шейдера у Visual Studio Code.

Сторінка розширення glsl-canvas у Visual Studio Code

glsl-canvas для Visual Studio Code реалізований як розширення, тому потрібно знову зайти до розділу розширень (Extensions) і за допомогою рядка пошуку знайти glsl-canvas та встановити його.

Всі основні інструменти в рамках цієї серії статей про основи програмування мовою GLSL — налаштовані та готові. Також ви можете налаштувати для себе так звані сніпети-коду підготовлені Lewis Lepton, які допоможуть вам швидше писати повторюваний код, а також отримувати певну документацію про типи даних та функції мови GLSL. Lewis Lepton спробував описати основними типи і код мови GLSL, що часто повторюється.

Налаштування сниппетів коду

Це робити не обов’язково, але на початковому етапі це допоможе вам у вивченні мови GLSL. Для цього вам потрібно буде перейти за наступним посиланням і скопіювати весь текст сніпету. Далі, перейти до пункту меню налаштування (Settings), та вибрати налаштування сніппетів (Configure User Snippets), і у з’явившийся у верхній частині редактора строці вводу, введіть GLSL та натисніть Enter на клавіатурі, цим ви відкриєте файл налаштування сніппет-коду для мови GLSL. Далі, вставте туди раніше скопійований код сніпетів та перезавантажте редактор коду.

Тепер ми можемо перейти до перевірки інструментів, які ми налаштували. Але, спочатку створіть на своєму комп’ютері папку, в якій під час проходження цієї серії статей і вивченні мови GLSL ви будете зберігати створені шейдери. Відкрийте цю папку, перетягнувши її у відкритий редактор Visual Studio Code, або на іконку в Dock-панелі MacOS, або якщо ви використовуєте Windows, то за допомогою контекстного меню папки виберіть Open in Visual Studio Code.

Створення нового файлу шейдера

Тепер створіть новий файл та назвіть його helloworld.frag. Скопіюйте в нього наступний код, не переживайте, цей код використовується для перевірки налаштування інструментів, і вам на даний момент не потрібно розуміти що саме в ньому відбувається, в наступних частинах цієї серії ви зрозумієте, що цей код означає.

#ifdef GL_ES
precision mediump float;
#endif

void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Вікно запуску glslCanvas

Тепер натисніть F1 на клавіатурі, та у вікні що з’явилося, введіть Show glslCanvas.

Результат роботи шейдера у glslCanvas

Праворуч від коду вашого шейдера з’явиться вікно glslCanvas, яке відображатиме результати роботи вашого шейдера. Ви побачите червоний прямокутник, результат роботи вашого шейдера буквально видає червоний колір, тому усі пікселі glslCanvas будуть пофарбовані в цей колір.

Спробуйте тепер змінити рядок gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); на gl FragColor = vec4(1.0, 0.0, 0.0, 1.0); замінивши символ підкреслення _ на пробіл. Ваш код має виглядати так:

#ifdef GL_ES
precision mediump float;
#endif

void main() {
gl FragColor = vec4(1.0, 0.0, 0.0, 1.0); // помилка у коді
}
Відображення помилок у коді Visual Studio та в glslCanvas

Ви побачите, що glslCanvas напише повідомлення про помилку, з описом рядка коду в якому є помилка, а також повний текст помилки. Також у редакторі Visual Studio Code рядок з помилкою буде підсвічений і лінтер показуватиме повідомлення про помилку, до тих пір, доки помилка не буде виправлена. Виправте помилку, збережіть файл, після чого ви побачите як результат роботи шейдера моментально зміниться.

У наступних частинах серії ми детально розберемо поточний код шейдера, але, щоб дати вам можливість поексперементувати, дуже швидко пройдемось по коду вашого першого шейдера.

#ifdef GL_ES
precision mediump float;
#endif

На початку коду шейдера йде декілька директив, які дозволяють цьому шейдеру більш оптимально працювати на мобільних та вбудованих системах. Ці директиви будуть розглянуті у наступних частинах.

void main() {
gl FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Далі слідує код, в якому описується основна функція шейдера — void main(), яка завжди буде викликана коли шейдер почне свою роботу. Фактично це точка входу до шейдера, з неї починається виконання коду.

gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
// Red = 1.0
// Green = 0.0
// Blue = 0.0
// Aplha = 1.0

Усередині цієї функції є лише одна інструкція. Ця інструкція надає системній змінній gl_FragColor (яка відповідає за виведення кольору в шейдері) колір, описаний за допомогою чотиризначного вектора. vec4 дозволяє описувати кольори у форматі RGBA, де кожному каналу або компоненту вектора відповідає певне значення червоного (red), зеленого (green), синього (blue) кольорів та значення прозорості (aplha), в діапазоні від 0 до 1. Про систему RGBA та інші системи опису кольору ви дізнаєтеся у наступних частинах.

#ifdef GL_ES
precision mediump float;
#endif

void main() {
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}

Пограйтеся з різними значеннями компонентів кольору, змінюючи їх значення як у коді вище, або вказавши це значення за допомогою інструмента Color picker (кольоровий квадрат біля опису значення кольору).

Результат роботи вашого першого GLSL-шейдера

Також, навівши курсор миші на вікно glslCanvas, ви відобразите панель налаштувань, в якому можна відобразити лічильник кадрів, щоб стежити за продуктивністю шейдера, а також вибрати одну з доступних тривимірних моделей та побачити результат роботи шейдера на цих моделях. А ще експортувати відео із візуалізацією вашого шейдера.

Панель налаштувань glslCanvas

Ваш перший шейдер готовий, інструменти налаштовані, і тепер ви можете поринути у вивчення основ програмування шейдерів за допомогою мови GLSL. У наступних частинах ми детальніше розглянемо що таке шейдери, які типи шейдерів бувають, де вони використовуються і для яких завдань застосовуються. Розглянемо історію та еволюцію мови GLSL та перейдемо до синтаксису та можливостей мови, а також писатимемо більш складні та комплексні шейдери.

На цьому все. Бажаю вам вдачі у вивченні мови GLSL і зустрінемося в наступній частині.

--

--

Captain GPU

Render developer and UE5 ukrainian game developer... Interests: gamedev, OpenGL, Vulkan, DirectX, shaders, Unreal Engine and art