Files
PRD_TU_MP550/Shaders/loadead.gdshader

118 lines
8.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

shader_type canvas_item;
// Конфигурационные униформы для кольца.
uniform float dot_scale : hint_range(0.1, 9.1) = 0.5; // Масштаб точек кольца.
uniform float ring_radius : hint_range(0.1, 1.0) = 0.2; // Радиус кольца.
uniform int num_points : hint_range(3, 10) = 8; // Количество точек на кольце.
uniform float gap_ratio : hint_range(0.0, 0.9) = 0.22; // Отношение пробелов между точками.
uniform bool all_dots_same_size = false; // Флаг, указывающий, должны ли все точки быть одинакового размера.
// Визуальные свойства точек кольца.
uniform vec4 dot_color_start : source_color = vec4(0.5, 0.0, 0.5, 1.0); // Начальный цвет точек.
uniform vec4 dot_color_end : source_color = vec4(0.8, 0.5, 1.0, 1.0); // Конечный цвет точек.
uniform bool enable_shadow = true; // Флаг для включения/выключения теней.
uniform vec4 shadow_color : source_color = vec4(0.0, 0.0, 0.0, 0.35); // Цвет теней.
uniform vec2 shadow_offset = vec2(0.03, 0.01); // Смещение теней от точек.
// Контроль анимации кольца.
uniform float rotation_speed : hint_range(0.0, 10.0) = 1.5; // Скорость вращения кольца.
// Новые униформы для текстуры иконки и её внешнего вида.
uniform sampler2D icon_texture; // Текстура иконки.
uniform float icon_size : hint_range(0.0, 1.0) = 0.15; // Контроль радиуса иконки.
// Новые униформы для контроля вращения иконки.
uniform bool enable_icon_rotation = false; // Флаг для включения вращения иконки.
uniform bool reverse_icon_rotation = false; // Флаг для инверсии вращения иконки.
uniform float icon_rotation_speed : hint_range(-10.0, 10.0) = 1.0; // Скорость вращения иконки.
// Униформ для контроля отрисовки иконки.
uniform bool show_icon = false; // Если false, текстура иконки игнорируется.
void fragment() {
// Преобразование UV-координат для центрирования начала координат и корректировки в зависимости от аспекта экрана.
float aspect_ratio = SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y;
vec2 uv = (UV * 2.0 - 1.0) * vec2(0.3, aspect_ratio); // Нормализация UV координат.
// Подсчет кольца (точек и опциональной тени).
vec4 ring_color = vec4(0.0); // Начальный цвет кольца.
float dot_accum = 0.0; // Накапливаемый вклад от точек.
float shadow_accum = 0.0; // Накапливаемый вклад от теней.
float total_angle = 6.283185307; // Полный круг в радианах (2π).
float gap = total_angle * gap_ratio; // Вычисление ширины пробела между точками.
float spacing = (total_angle - gap) / float(num_points); // Вычисление интервала между точками.
// Определение направления вращения кольца.
float direction = 1.0; // Вращение по часовой стрелке или против.
float rotation = TIME * rotation_speed * direction; // Вычисление текущего угла поворота.
for (int i = 0; i < num_points; i++) { // Проход по каждой точке кольца.
float angle = rotation + spacing * float(i); // Вычисление угла для данной точки.
vec2 pos = vec2(cos(angle), sin(angle)) * ring_radius; // Вычисление позиции точки по окружности.
// Вычисление размера точки:
float size_factor = 0.5 + (float(i) / float(num_points)); // Фактор уменьшения размера.
float radius = all_dots_same_size ? 0.1 * dot_scale : 0.1 * size_factor * dot_scale; // Радиус точки.
// Интерполяция цвета точки вдоль кольца от начала к концу.
float gradient_factor = float(i) / float(num_points - 1); // Фактор градиента для цветовой интерполяции.
vec4 dot_color = mix(dot_color_start, dot_color_end, gradient_factor); // Цвет точки.
// Вычисление вклада точки на основе расстояния.
float distance = length(uv - pos); // Расстояние до текущей точки.
float contribution = smoothstep(radius + 0.01, radius, distance); // Плавный вклад на основе расстояния.
if (contribution > 0.0) { // Если вклад точки больше нуля,
ring_color = mix(ring_color, dot_color, contribution); // Смешивание с цветом кольца.
dot_accum += contribution; // Накопление вклада от точки.
}
// Опциональная тень за каждой точкой.
if (enable_shadow) {
vec2 shadow_pos = pos + shadow_offset; // Позиция для тени.
float shadow_dist = length(uv - shadow_pos); // Расстояние до тени.
float shadow_contrib = smoothstep(radius * 1.2 + 0.005, radius * 1.2, shadow_dist); // Вклад от тени.
shadow_accum += shadow_contrib; // Накопление вклада от теней.
}
}
// Определение базового цвета для кольца или тени.
vec4 base_color = vec4(0.0); // Начальный цвет.
if (dot_accum > 0.0) { // Если есть вклад от точек,
base_color = ring_color; // Установка базового цвета на цвет кольца.
} else if (enable_shadow && shadow_accum > 0.0) { // Если тени включены и есть вклад от теней,
base_color = shadow_color; // Установка базового цвета на цвет тени.
}
// Отрисовка иконки - приступаем только если show_icon истинно.
if (show_icon) {
// Создание радиальной маски, чтобы иконка была видимой внутри радиуса icon_size.
float icon_mask = smoothstep(icon_size, icon_size - 0.005, length(uv)); // Маска для иконки.
// Нормализация UV-координат для иконки.
vec2 icon_uv = (uv / icon_size + vec2(1.0)) / 2.0; // Превращение из диапазона (-icon_size ... +icon_size) в (0 ... 1).
// Применение вращения иконки, если оно включено.
if (enable_icon_rotation) {
float icon_angle = TIME * icon_rotation_speed; // Угол вращения на основе времени и скорости вращения.
if (reverse_icon_rotation) {
icon_angle = -icon_angle; // Инверсия угла, если требуется.
}
// Вращение вокруг центра (0.5, 0.5) текстуры иконки.
vec2 centered_uv = icon_uv - vec2(0.5); // Смещение UV координат.
float s = sin(icon_angle); // Синус угла.
float c = cos(icon_angle); // Косинус угла.
centered_uv = vec2(centered_uv.x * c - centered_uv.y * s,
centered_uv.x * s + centered_uv.y * c); // Применение матрицы вращения.
icon_uv = centered_uv + vec2(0.5); // Смещение обратно к нормализованным координатам.
}
vec4 icon_sample = texture(icon_texture, icon_uv); // Получение цвета из текстуры иконки.
// Смешивание текстуры иконки с базовым цветом кольца с учетом маски и альфа-канала текстуры.
base_color = mix(base_color, icon_sample, icon_mask * icon_sample.a);
}
COLOR = base_color; // Установка финального цвета для текущего пикселя.
}