Files
uarep-ctl/shaders/antenas.gdshader
2025-12-24 09:45:45 +03:00

102 lines
4.4 KiB
Plaintext
Raw 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;
#include "tools.gdshaderinc"
#define ANT_BAND_READY 1U /* Антенна (модуль ФС) готова или исправна */
#define ANT_BAND_FAILED 0U /* Антенна (модуль ФС) не исправно */
// Конфигурация сетки
uniform int grid_cells_angle = 4; /* Количество секторов (90° каждый) */
uniform int grid_layers_radius = 7; /* Количество слоёв по радиусу */
uniform float alpha: hint_range(0.0, 1.0) = 0.5;
uniform float inner_radius = 0.36; /* Внутренняя незакрашенная окружность. Относительное значение */
uniform float outer_radius = 1.0; /* Внешний радиус. Относительное значение */
uniform float grid_line_width = 0.0025; /* Сетка, ширина линий. Относительное значение */
uniform float rotation: hint_range(0, 360) = 0.0;
uniform float ffr: hint_range(0.0, 1.0) = 0.2; /* Индикация неисправности модулей ФС. Заметность штриховки. Индикация неисправности модулей ФС */
uniform float sfr: hint_range(0.0, 10.0) = 0.0; /* Индикация неисправности модулей ФС. Скорость движения штрховки */
uniform float pfr: hint_range(0.01, 1.0) = 0.025; /* Индикация неисправности модулей ФС. Частота штриховки */
// Вариант 1: Массив цветов для каждой ячейки (4×7 = 28)
uniform vec4 ant_band_c[28]: source_color;
uniform uint ant_band_m[28];
varying vec2 centered_uv;
void vertex()
{
// 1. Переводим UV в координаты относительно центра (-1..1)
centered_uv = (UV - 0.5) * 2.0;
rotate_vec2(centered_uv, radians(rotation + 315.0), vec2(0, 0));
}
void fragment()
{
float dist = length(centered_uv);
// 2. Отсекаем за пределами внешнего радиуса
if (dist > outer_radius) {
COLOR = vec4(0.0);
discard;
}
// 3. Отсекаем внутри внутреннего радиуса
if (dist < inner_radius) {
COLOR = vec4(0.0);
discard;
}
// 4. Вычисляем полярные координаты
float angle = 6.28318530718 - atan(centered_uv.y, centered_uv.x);
// Приводим к диапазону 0..2π
angle = mod(angle + 6.28318530718, 6.28318530718);
// 5. Определяем индексы ячейки
// Сектор (0..3)
float sector_width = 6.28318530718 / float(grid_cells_angle);
int sector_idx = int(angle / sector_width);
// Слой (0..6)
float available_radius = outer_radius - inner_radius;
float normalized_radius = (dist - inner_radius) / available_radius;
float layer_height = 1.0 / float(grid_layers_radius);
int layer_idx = int(normalized_radius / layer_height);
// 6. Проверяем границы (чтобы не выйти за пределы)
if (layer_idx >= grid_layers_radius) {
COLOR = vec4(0.0);
discard;
}
// 7. Рассчитываем глобальный индекс ячейки (0..27)
int cell_index = layer_idx * grid_cells_angle + sector_idx;
// 8. Получаем цвет ячейки (два варианта) из массива цветов
vec4 cell_color = ant_band_c[cell_index];
// Границы по углу
float angle_in_sector = mod(angle, sector_width);
if (angle_in_sector < grid_line_width ||
sector_width - angle_in_sector < grid_line_width) {
cell_color.rgb *= 0.7; // Затемняем границы
}
// Границы по радиусу
float radius_in_layer = mod(normalized_radius, layer_height);
if (radius_in_layer < grid_line_width ||
layer_height - radius_in_layer < grid_line_width) {
cell_color.rgb *= 0.7; // Затемняем границы
}
// Подмешивание шума для включённых
cell_color.a = alpha + random_timed(centered_uv) * cell_color.a;
// Индикация не исправности
if (ant_band_m[cell_index] == ANT_BAND_FAILED)
{
cell_color.a *= (1.0 - ffr) + tanh(10.0 * sin(TIME * sfr + 2.0 * PI * centered_uv.x / pfr)) * ffr;
}
COLOR = cell_color;
}