Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Ваш перший 2D-шейдер

Вступ

Шейдери — це спеціальні програми, які виконуються на графічному процесорі та використовуються для відтворення графіки. Увесь сучасний рендеринг виконується за допомогою шейдерів. Для більш детального опису того, що таке шейдери, перегляньте What are shaders.

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

Примітка

Якщо у вас є досвід написання шейдерів і ви просто шукаєте огляд того, як шейдери працюють у Godot, перегляньте Shading Reference.

Налаштування

CanvasItem shaders використовуються для малювання всіх 2D-об'єктів у Godot, тоді як шейдери Spatial використовуються для малювання всіх 3D-об'єктів.

Щоб використовувати шейдер, він має бути прикріплений до Material, який має бути прикріплений до об’єкта. Матеріали є типом Resource. Щоб намалювати кілька об’єктів одним і тим самим матеріалом, матеріал має бути прикріплений до кожного об’єкта.

Усі об’єкти, похідні від CanvasItem, мають властивість material. Сюди входять усі елементи GUI elements, Sprite2Ds, TileMapLayers, MeshInstance2Ds тощо. Вони також мають можливість успадковувати матеріал свого батька. Це може бути корисно, якщо у вас є велика кількість вузлів, для яких ви хочете використовувати той самий матеріал.

Для початку створіть вузол Sprite2D. You can use any CanvasItem, якщо він малює на полотні, тому для цього уроку ми будемо використовувати Sprite2D, оскільки це найпростіший CanvasItem для початку малювання.

В інспекторі клацніть поруч із «Текстурою», де написано «[пусто]», виберіть «Завантажити», а потім виберіть «icon.svg». Для нових проектів це значок Godot. Тепер ви повинні побачити значок у вікні перегляду.

Далі подивіться вниз в інспекторі, у розділі CanvasItem, клацніть біля «Material» і виберіть «New ShaderMaterial». Це створює новий матеріальний ресурс. Натисніть на сферу, що з'явиться. Наразі Godot не знає, чи пишете ви шейдер CanvasItem чи просторовий шейдер, і попередньо переглядає результат просторових шейдерів. Отже, ви бачите результат просторового шейдера за замовчуванням.

Примітка

Матеріали, успадковані від ресурсу Material, такі як class_StandardMaterial3D і class_ParticleProcessMaterial, можна перетворити на class_ShaderMaterial, а їхні існуючі властивості буде перетворено на супровідний текстовий шейдер. Для цього клацніть правою кнопкою миші на матеріалі в док-станції FileSystem і виберіть Перетворити на ShaderMaterial. Ви також можете зробити це, клацнувши правою кнопкою миші будь-яку властивість, що містить посилання на матеріал в інспекторі.

Клацніть поруч із «Шейдером» і виберіть «Новий шейдер». Нарешті клацніть шейдер, який ви щойно створили, і відкриється редактор шейдерів. Тепер ви готові почати писати свій перший шейдер.

Ваш перший шейдер CanvasItem

У Godot усі шейдери починаються з рядка, який визначає тип шейдера. Він використовує такий формат:

shader_type canvas_item;

Оскільки ми пишемо шейдер CanvasItem, ми вказуємо canvas_item у першому рядку. Весь наш код буде розміщено під цією декларацією.

Цей рядок повідомляє механізму, які вбудовані змінні та функціональні можливості надати вам.

У Godot ви можете змінити три функції, щоб керувати роботою шейдера; вершина, фрагмент і світло. Цей підручник допоможе вам створити шейдер із функціями вершин і фрагментів. Функції світла значно складніші, ніж функції вершин і фрагментів, тому тут не розглядатимуться.

Ваша перша функція фрагмента

Функція фрагмента виконується для кожного пікселя в Sprite2D і визначає колір цього пікселя.

Вони обмежені пікселями, охопленими Sprite2D, це означає, що ви не можете використовувати один, щоб, наприклад, створити контур навколо Sprite2D.

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

Ми робимо це, записуючи vec4 у вбудовану змінну COLOR. vec4 — скорочення для побудови вектора з 4 чисел. Для отримання додаткової інформації про вектори перегляньте Vector math tutorial. COLOR є як вхідною змінною функції фрагмента, так і кінцевим її виходом.

void fragment(){
  COLOR = vec4(0.4, 0.6, 0.9, 1.0);
}
../../../_images/blue-box.png

Щиро вітаю! Ви готові. Ви успішно написали свій перший шейдер у Godot.

Тепер давайте ускладнимо речі.

Існує багато вхідних даних для функції фрагменту, які можна використовувати для обчислення COLOR. UV - один з них. Ультрафіолетові координати вказуються у вашому Sprite2D (без вашого відома!), і вони вказують шейдеру, де зчитувати текстури для кожної частини сітки.

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

UV змінюється в межах 0-1 зліва направо та зверху вниз.

../../../_images/iconuv.png
void fragment() {
  COLOR = vec4(UV, 0.5, 1.0);
}
../../../_images/UV.png

Використання вбудованої ТЕКСТУРИ

Функція фрагмента за замовчуванням читає зі встановленої текстури Sprite2D і відображає її.

Якщо ви хочете налаштувати колір у Sprite2D, ви можете налаштувати колір текстури вручну, як показано в коді нижче.

void fragment(){
  // This shader will result in a blue-tinted icon
  COLOR.b = 1.0;
}

Певні вузли, наприклад Sprite2D, мають спеціальну змінну текстури, до якої можна отримати доступ у шейдері за допомогою TEXTURE. Якщо ви хочете використовувати текстуру Sprite2D для поєднання з іншими кольорами, ви можете використовувати UV з функцією texture для доступу до цієї змінної. Використовуйте їх, щоб перемалювати Sprite2D з текстурою.

void fragment(){
  COLOR = texture(TEXTURE, UV); // Read from texture again.
  COLOR.b = 1.0; //set blue channel to 1.0
}
../../../_images/blue-tex.png

Рівномірне введення

Уніфікований вхід використовується для передачі даних у шейдер, який буде однаковим для всього шейдера.

Ви можете використовувати форму, визначивши її у верхній частині шейдера так:

uniform float size;

Додаткову інформацію про використання див. у Shading Language doc.

Додайте форму, щоб змінити кількість синього кольору в Sprite2D.

uniform float blue = 1.0; // you can assign a default value to uniforms

void fragment(){
  COLOR = texture(TEXTURE, UV); // Read from texture
  COLOR.b = blue;
}

Тепер ви можете змінити кількість синього кольору в Sprite2D з редактора. Поверніться до інспектора під тим місцем, де ви створили свій шейдер. Ви повинні побачити розділ під назвою «Параметр шейдера». Розгорніть цей розділ, і ви побачите уніформу, яку щойно задекларували. Якщо ви зміните значення в редакторі, воно перезапише значення за замовчуванням, яке ви надали в шейдері.

Взаємодія з шейдерами з коду

Ви можете змінити форму з коду за допомогою функції set_shader_parameter(), яка викликається на матеріальному ресурсі вузла. За допомогою вузла Sprite2D наступний код можна використовувати для встановлення блакитної форми.

var blue_value = 1.0
material.set_shader_parameter("blue", blue_value)

Зверніть увагу, що назва уніформи – рядок. Рядок має точно відповідати тому, як він написаний у шейдері, включаючи орфографію та регістр.

Ваша перша вершинна функція

Тепер, коли у нас є функція фрагмента, давайте напишемо функцію вершини.

Використовуйте функцію вершини, щоб обчислити, де на екрані має опинитися кожна вершина.

Найважливішою змінною у функції вершини є VERTEX. Спочатку він визначає координати вершин у вашій моделі, але ви також пишете в нього, щоб визначити, де насправді малювати ці вершини. VERTEX - це vec2, який спочатку представлено в локальному просторі (тобто не відносно камери, вікна перегляду або батьківських вузлів).

Ви можете зміщувати вершини, безпосередньо додаючи до VERTEX.

void vertex() {
  VERTEX += vec2(10.0, 0.0);
}

У поєднанні з вбудованою змінною TIME це можна використовувати для базової анімації.

void vertex() {
  // Animate Sprite2D moving in big circle around its location
  VERTEX += vec2(cos(TIME)*100.0, sin(TIME)*100.0);
}

Висновки

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

Щоб отримати натхнення, подивіться на деякі з більш просунутих навчальних посібників із шейдерів і подивіться на інші сайти, як Shadertoy і Книга шейдерів.