Перейти до основного вмісту

Основи GLSL

Що таке GLSL?

GLSL (OpenGL Shading Language) – мова програмування шейдерів для OpenGL. Використовується для написання vertex, fragment, geometry та інших шейдерів, що працюють на GPU.

Оголошення версії


#version 330 core

Вказує версію GLSL. Наприклад, 330 core відповідає OpenGL 3.3.

Вхідні та вихідні змінні


layout(location=0) in vec3 aPos;
layout(location=1) in vec3 aNormal;

out vec3 FragPos;

in – вхідні атрибути (vertex shader).
out – вихідні змінні (vertex shader) або фінальний колір (fragment shader).

Основні типи даних


float, int, bool
vec2, vec3, vec4
mat2, mat3, mat4
sampler2D (текстури)
Тип Опис Приклади використання
vec2 Двокомпонентний вектор з типом float. - Текстурні координати (UV)
- 2D позиції
- Швидкість у 2D
vec3 Трикомпонентний вектор з типом float. - Координати позицій у 3D
- Нормалі
- Колір у форматі RGB
vec4 Чотирикомпонентний вектор з типом float. - RGBA кольори
- Позиції у гомогенних координатах (x, y, z, w)
- Передача даних з додатковою інформацією (наприклад, альфа-канал)
mat2 2x2 матриця з типом float. - Трансформації у 2D (масштабування, обертання)
mat3 3x3 матриця з типом float. - Трансформації у 3D без врахування перспективи
- Робота з нормалями (normal matrix)
mat4 4x4 матриця з типом float. - Трансформації у 3D з перспективою
- Матриці моделі, огляду та проєкції
sampler2D Тип, що використовується для доступу до 2D текстури. - Зчитування кольорів з текстури у fragment shader
- Використання для матеріалів, normal maps, height maps

Головна функція


void main()
{
    // код шейдера
}

Присвоєння позиції в vertex shader


gl_Position = projection * view * model * vec4(aPos, 1.0);

Приклад vertex shader


#version 330 core
layout (location=0) in vec3 aPos;
layout (location=1) in vec3 aColor;

out vec3 fColor;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    fColor = aColor;
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

Приклад fragment shader


#version 330 core

in vec3 fColor;
out vec4 FragColor;

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

Передача uniform змінних


uniform mat4 model;
uniform sampler2D texture1;

Uniform – однакові значення для всіх вершин/фрагментів у кадрі.

Текстурні координати


layout (location=2) in vec2 aTexCoord;

out vec2 TexCoord;

void main()
{
    TexCoord = aTexCoord;
}

Читання текстури у fragment shader


uniform sampler2D texture1;
in vec2 TexCoord;
out vec4 FragColor;

void main()
{
    FragColor = texture(texture1, TexCoord);
}

Основні вбудовані функції


length(v) // довжина вектора
normalize(v) // нормалізація вектора
dot(a, b) // скалярний добуток
cross(a, b) // векторний добуток
mix(a, b, t) // лінійна інтерполяція
clamp(x, minVal, maxVal) // обмеження значення

Типи шейдерів у GLSL

  • vertex shader – обробляє кожну вершину моделі, трансформуючи її з локальної системи координат у простір кліпу. Тут зазвичай обчислюються позиції, нормалі, передаються дані у fragment shader.
  • fragment shader – виконується для кожного фрагмента (пікселя) трикутника, визначає фінальний колір пікселя, застосовує текстури, освітлення та ефекти.
  • geometry shader – працює після vertex shader. Може створювати або змінювати примітиви (точки, лінії, трикутники). Наприклад, для генерації додаткової геометрії (силуети, нормалі, траву).
  • tessellation shader – складається з двох частин: tessellation control shader та tessellation evaluation shader. Використовується для динамічного поділу полігонів на дрібніші (тесселяція), що дозволяє створювати деталізовані поверхні без великої кількості вершин у моделі.
  • compute shader – універсальний шейдер для загальних обчислень на GPU, не прив’язаний до графічного конвеєра. Використовується для паралельної обробки даних, наприклад, фізичних симуляцій, пост-обробки зображень, ML.
Тип шейдера Призначення Приклади використання
Vertex Shader Обробка кожної вершини: трансформація координат, передача даних у фрагментний шейдер. - Перетворення моделі у clip space
- Обчислення нормалей та напрямків освітлення
- Передача UV координат та кольору
Fragment Shader Обчислює колір кожного фрагмента (пікселя), застосовує освітлення та текстурування. - Відображення текстур
- Освітлення Phong, Blinn-Phong
- Пост-обробка (якщо використовується для screen quad)
Geometry Shader Може змінювати існуючі примітиви або створювати нові (після vertex shader). - Генерація нормалей для візуалізації
- Створення силуетів
- Генерація трави, волосся, частинок
Tessellation Shader Динамічне поділення (тесселяція) полігонів на дрібніші для збільшення деталізації. - Деталізація поверхонь при близькому огляді
- Displacement mapping (зміщення вершин по карті висот)
- Реалістична поверхня води або ландшафту
Compute Shader Загальні паралельні обчислення на GPU, незалежні від графічного конвеєра. - Фізичні симуляції (fluid dynamics, particles)
- Пост-обробка HDR, blur, bloom
- Обробка даних у ML (CNN, матричні множення)

Основна структура програми на GLSL


#version ...

// оголошення in/out/uniform

void main()
{
    // основна логіка
}

Коментарі

Популярні публікації

Шпаргалка по базових командах PostgreSQL

1. Підключення до PostgreSQL через командний рядок: psql -h <host> -p <port> -U <username> -d <database> 2. Підключення до бази без параметрів (якщо користувач і база мають однакове ім’я): psql 3. Показати список усіх баз даних: \l 4. Підключитися до іншої бази даних: \c <database_name> 5. Показати список таблиць у поточній базі: \dt 6. Показати всі об'єкти (таблиці, індекси, секвенції): \d 7. Показати таблиці з усіх схем: \dt *.* 8. Переглянути структуру конкретної таблиці: \d <table_name> 9. Виконати SQL-запит (приклад): SELECT * FROM users; 10. Вийти з psql: \q 11. Створити нову базу даних: CREATE DATABASE mydb; 12. Створити нову таблицю: CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE ); 13. Додати новий запис: INSERT INTO users (name, email) VALUES ('Іван', 'ivan@example.com'); 14. Оновити дані в таблиці: UPDATE users SET name = 'Петро' WH...

Атоми в мові програмування Elixir

Атоми в Elixir Атоми є фундаментальною концепцією в Elixir , що відіграє ключову роль у створенні надійних та масштабованих систем. В Elixir це специфічний тип даних, який є константою , незмінною , ідентифікованою за своїм ім'ям . Отже, атом в Elixir — це іменована константа, що представляє себе. Уявіть, що ви даєте унікальне ім'я певній речі, і це ім'я завжди посилається саме на цю річ, і ніколи на щось інше. Наприклад, атом :ok завжди буде означати саме успішне завершення операції, а не якесь інше значення. Технічно, атоми є похідними від чисел . Кожен унікальний атом зберігається у таблиці атомів, і йому присвоюється унікальний цілочисельний ідентифікатор. Це робить їх надзвичайно ефективними для порівняння: замість порівняння рядків (що є повільною операцією), Elixir порівнює цілочисельні ідентифікатори. Переваги та особливості використання атомів Переваги атомів: Ефективність. Завдяки своєму числовому представленню, порівняння атомів є дуже швидким. Це осо...

Встановлення PostgreSQL на Ubuntu-сервер

Встановлення Оновлюємо пакети та встановлюємо PostgreSQL: sudo apt update sudo apt install -y postgresql postgresql-contrib Перевіряємо статус сервісу: sudo systemctl status postgresql Якщо PostgreSQL не запущений, запустимо його: sudo systemctl start postgresql sudo systemctl enable postgresql Налаштування безпеки Зміна пароля: sudo -u postgres psql У консолі PostgreSQL: ALTER USER postgres PASSWORD 'міцний_пароль'; \q \q - вихід з консолі. Список основних команд для роботи з PostgreSQL можна переглянути за посиланням. За замовчуванням PostgreSQL слухає localhost (127.0.0.1). Щоб дозволити доступ із зовнішніх машин, редагуємо конфігурацію: sudo nano /etc/postgresql/17/main/postgresql.conf (замість 17 вкажи версію PostgreSQL, яку встановлено) Шукаємо рядок: #listen_addresses = 'localhost' та замінюємо на listen_addresses = '*' Зберігаємо (Ctrl + X, Y, Enter). Тепер редагуємо pg_hba.conf: sudo nano /etc/postgresql/17/main/pg_hba.conf...

Прості типи даних в Elixir

Мова Elixir має низку простих (примітивних) типів даних, які часто використовуються в повсякденному програмуванні. Числа Elixir підтримує цілі (integer) та дійсні числа (float). # Цілі числа a = 42 b = -7 # Дійсні числа c = 3.14 d = -0.001 Булеві значення Elixir має два булевих значення: true та false . x = true y = false z = x and y # false Атоми Атоми — це константи з іменем, що починається з двокрапки. Вони широко використовуються, наприклад, для імен параметрів або станів. :ok :error :running :elixir_is_fun Рядки Рядки в Elixir — це двійкові дані з кодуванням UTF-8, оголошуються в подвійних лапках. name = "Pavlo" greeting = "Привіт, #{name}!" Nil Nil — це спеціальне значення, що позначає "відсутність значення". value = nil is_nil(value) # true Бінарні дані та байти Бінарні дані оголошуються в подвійних лапках або як бінарні літерали. string = "Привіт" # це рядок, але також бінарні дані binary = ...