Типы шейдеров: выбор и назначение
Куда назначать шесть типов шейдеров, чем Shader отличается от ShaderMaterial и как работают общие текстуры.
Сначала выберите объект, который должен использовать результат. shader_type определяет доступные этапы и встроенные значения; одинаковое имя COLOR в разных типах не означает одинаковый контракт.
Выберите тип по задаче
| Задача | shader_type | Куда назначить ShaderMaterial | Этапы и справочник |
|---|---|---|---|
| Поверхность 3D-меша | spatial | Материал поверхности Mesh или MeshInstance3D.MaterialOverride | vertex / fragment / light |
| Спрайт или интерфейс 2D | canvas_item | CanvasItem.Material, например у Sprite2D или ColorRect | vertex / fragment / light |
| Моделирование GPU-частиц | particles | GpuParticles2D/GpuParticles3D.ProcessMaterial | start / process |
| Небо и карта освещения окружения | sky | Sky.SkyMaterial; сам Sky назначается в Environment | sky |
| Вклад FogVolume в объёмный туман | fog | FogVolume.Material; нужны Forward+ и VolumetricFogEnabled | fog |
| Явная запись в DrawableTexture2D | texture_blit | Аргумент material операции BlitRect/BlitRectMulti | blit |
Этапы в таблице не обязательно писать все: используйте нужные для эффекта. Particle-материал моделирует данные, а отдельный материал меша/спрайта рисует частицу. Texture blit выполняется по вызову операции и не становится постоянным эффектом отображения. Привязка материала не включает автоматически свет, окружение, объёмный туман или эмиссию частиц.
Тип Shader, параметры ShaderMaterial
Shader хранит код/граф и общие настройки. ShaderMaterial ссылается на Shader и хранит значения параметров материала. Два отдельных материала могут разделять один Shader; назначение одного ShaderMaterial двум объектам даёт общие значения его параметров.
У текстового Shader тип задаётся директивой shader_type. GetMode читает тип из подготовленного после препроцессора текста. Это не проверка успешной компиляции или правильного места назначения: даже пустой ресурс по умолчанию сообщает Spatial. После подключения проверяйте результат в нужном проходе и ошибки компилятора.
Сохраните полный ShaderRoute.cs для проверки типа перед созданием материала:
using System;
using Reckfell;
public static class ShaderRoute
{
public static ShaderMaterial Material(Shader shader, Shader.Mode expected)
{
ArgumentNullException.ThrowIfNull(shader);
if (shader.GetMode() != expected)
throw new ArgumentException("Shader type does not match the intended consumer.", nameof(shader));
return new ShaderMaterial { Shader = shader };
}
public static void DefaultSource(Shader shader, Texture? texture)
{
shader.SetDefaultTextureParameter("source_texture", texture!, 0);
}
}Загрузите нужный Shader, например ResourceLoader.Load<Shader>("asset://DefaultSource.reckfellshader"). Для примера ниже создайте ShaderRoute.Material(shader, Shader.Mode.CanvasItem) и назначьте результат в Material видимого ColorRect. Guard проверяет соответствие типа; он не доказывает работоспособность GPU-кода.
Значения по умолчанию и переопределения
Полный шейдер примера читает текстуру и параметр gain:
shader_type canvas_item;
uniform sampler2D source_texture : source_color, hint_default_white;
uniform float gain = 1.0;
void fragment() {
COLOR = texture(source_texture, UV) * gain;
}ShaderRoute.DefaultSource(shader, texture) задаёт общую текстуру source_texture на Shader. Материалы без собственного значения используют её; material.SetShaderParameter("source_texture", otherTexture) переопределяет её только для этого материала. Для обычных параметров используйте точное имя uniform без префикса shader_parameter/.
Передача null в DefaultSource снимает общую текстуру. У примера после этого действует hint_default_white; переопределение материала сохраняется. Передача default(Variant) в SetShaderParameter снимает уже переопределение материала. Это два разных уровня настройки.
GetDefaultTextureParameter(name, index) читает назначенную общую текстуру или возвращает null. У sampler-массива index выбирает элемент; снятие одного элемента не снимает остальные. Если у uniform есть хотя бы одна назначенная текстура по умолчанию, текущий GetShaderUniformList скрывает этот uniform целиком. Код и возможность задать материалу параметр при этом остаются. После снятия последнего назначения uniform снова появляется в списке.
GetCode возвращает исходный текст, включая директивы, а не развёрнутый код драйвера. InspectNativeShaderCode запрашивает отдельный просмотр в редакторе, если соответствующий просмотрщик доступен; метод не возвращает строку скомпилированного шейдера.
Куда идти дальше
| Нужен ответ | Раздел |
|---|---|
| Типы, uniform, varying, функции и области параметров | Язык шейдеров |
| #include, #define и условная компиляция | Препроцессор |
| Математические и текстурные встроенные функции | Встроенные функции |
| Граф вместо текстового алгоритма | VisualShader |
| Экранная текстура, глубина или последовательность эффектов | Экранные шейдеры |
В Windows Forward+/Vulkan проверены типы шести деклараций, C#-guard и фактические CanvasItem-пиксели общих/индивидуальных текстур, их снятия и индексов массива. Это не подтверждение отрисовки всех типов одним тестом: у подробных руководств есть собственные проверки соответствующих проходов. Окно native-кода редактора, остальные платформы/рендереры и производительность здесь отдельно не проверялись.