优化项目架构

This commit is contained in:
2025-09-15 19:10:37 +08:00
parent 4119ed3445
commit 26b856d74e
1361 changed files with 4 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
shader_type canvas_item;
uniform bool allow_out_of_bounds = true;
uniform float outline_thickness: hint_range(0.0, 16.0, 1.0) = 1.0;
uniform vec4 outline_color: source_color = vec4(1.0);
uniform int quality: hint_range(1, 3, 1) = 2; // 1=低质量但快速, 2=平衡, 3=高质量但慢
uniform bool use_fast_mode = true; // 快速模式,牺牲一点质量换取性能
bool is_inside_usquare(vec2 x) {
return x == clamp(x, vec2(0.0), vec2(1.0));
}
vec4 blend(vec4 bottom, vec4 top) {
float alpha = top.a + bottom.a * (1.0 - top.a);
if (alpha < 0.0001) return vec4(0.0);
vec3 color = mix(bottom.rgb * bottom.a, top.rgb, top.a) / alpha;
return vec4(color, alpha);
}
void vertex() {
if (allow_out_of_bounds) VERTEX += (UV * 2.0 - 1.0) * outline_thickness;
}
void fragment() {
if (outline_thickness <= 0.0 || outline_color.a <= 0.0) {
COLOR = texture(TEXTURE, UV);
} else {
vec2 uv = UV;
vec4 texture_color = texture(TEXTURE, UV);
if (allow_out_of_bounds) {
vec2 texture_pixel_size = vec2(1.0) / (vec2(1.0) / TEXTURE_PIXEL_SIZE + vec2(outline_thickness * 2.0));
uv = (uv - texture_pixel_size * outline_thickness) * TEXTURE_PIXEL_SIZE / texture_pixel_size;
if (is_inside_usquare(uv)) {
texture_color = texture(TEXTURE, uv);
} else {
texture_color = vec4(0.0);
}
}
// 如果当前像素已经有alpha且不是在边缘可以跳过复杂计算
if (texture_color.a > 0.9) {
COLOR = texture_color;
} else {
float alpha = 0.0;
if (use_fast_mode) {
// 快速模式:使用较少的采样点
float step_size = max(1.0, outline_thickness / 4.0);
int max_samples = 32; // 限制最大采样数
int sample_count = 0;
for (float radius = step_size; radius <= outline_thickness && sample_count < max_samples; radius += step_size) {
// 使用8个方向的采样点
vec2 directions[8] = {
vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0),
vec2(0.707, 0.707), vec2(-0.707, 0.707), vec2(0.707, -0.707), vec2(-0.707, -0.707)
};
for (int i = 0; i < 8; i++) {
vec2 sample_uv = uv + directions[i] * radius * TEXTURE_PIXEL_SIZE;
if (is_inside_usquare(sample_uv)) {
float sample_alpha = texture(TEXTURE, sample_uv).a;
alpha = max(alpha, sample_alpha);
sample_count++;
if (alpha > 0.99) break; // 早期退出
}
}
if (alpha > 0.99) break; // 早期退出
}
} else {
// 原始高质量模式,但有优化
int max_thickness = int(min(outline_thickness, float(8 + quality * 4))); // 限制最大厚度
for (int y = 1; y <= max_thickness; y++) {
for (int x = 0; x <= y; x++) {
float dist = length(vec2(float(x), float(y) - 0.5));
if (dist > outline_thickness) break;
vec2 offsets[8] = {
vec2(float(x), float(y)), vec2(float(-x), float(y)),
vec2(float(x), float(-y)), vec2(float(-x), float(-y)),
vec2(float(y), float(x)), vec2(float(-y), float(x)),
vec2(float(y), float(-x)), vec2(float(-y), float(-x))
};
for (int i = 0; i < 8; i++) {
vec2 sample_uv = uv + offsets[i] * TEXTURE_PIXEL_SIZE;
if (is_inside_usquare(sample_uv)) {
float sample_alpha = texture(TEXTURE, sample_uv).a;
alpha = max(alpha, sample_alpha);
if (alpha > 0.99) break; // 早期退出
}
}
if (alpha > 0.99) break; // 早期退出
}
if (alpha > 0.99) break; // 早期退出
}
}
COLOR = blend(vec4(outline_color.rgb, alpha * outline_color.a), texture_color);
}
}
}

View File

@@ -0,0 +1 @@
uid://xrlqe0cdb3ty

View File

@@ -0,0 +1,97 @@
shader_type canvas_item;
uniform float u_aspect; // aspect of the control.
uniform vec4 progress_color : source_color = vec4(0.5, 0.5, 0.5, 1.0);
uniform vec4 background_color : source_color = vec4(0.4, 0.4, 0.4, 1.0);
uniform vec4 outline_color : source_color = vec4(0.4, 0.4, 0.4, 1.0);
uniform float progress = 0.9;
const float corner_radius = 0.2;
const float grain_darkness = 0.01;
const vec4 white_color = vec4(1.0);
const float gradient_length = 0.05;
const float star_size = 20.0; // In pixels.
const float border_width = 0.01;
const float edge_softness = 0.005;
const float border_size = 0.1;
// A Signed Distance Field (SDF) formulas: https://iquilezles.org/articles/distfunctions2d/
float sdBox(in vec2 pos, in vec2 half_size)
{
vec2 d = abs(pos) - half_size;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}
float sdRoundedBox(in vec2 pos, in vec2 half_size, in float r)
{
return sdBox(pos , half_size) - r;
}
float sdStar(in vec2 p, in float r)
{
const float k1x = 0.809016994; // cos(π/ 5) = ¼(√5+1)
const float k2x = 0.309016994; // sin(π/10) = ¼(√5-1)
const float k1y = 0.587785252; // sin(π/ 5) = ¼√(10-2√5)
const float k2y = 0.951056516; // cos(π/10) = ¼√(10+2√5)
const float k1z = 0.726542528; // tan(π/ 5) = √(5-2√5)
const vec2 v1 = vec2( k1x,-k1y);
const vec2 v2 = vec2(-k1x,-k1y);
const vec2 v3 = vec2( k2x,-k2y);
p.x = abs(p.x);
p -= 2.0*max(dot(v1,p),0.0)*v1;
p -= 2.0*max(dot(v2,p),0.0)*v2;
p.x = abs(p.x);
p.y -= r;
return length(p-v3*clamp(dot(p,v3),0.0,k1z*r))
* sign(p.y*v3.x-p.x*v3.y);
}
float sdRoundedStar(in vec2 p, in float r, in float corner_r) {
return sdStar(p, r) - corner_r;
}
void fragment() {
vec2 aspect = vec2(u_aspect, 1.0);
vec2 half_size = vec2(0.5, 0.5) * aspect;
vec2 pos = UV * aspect - half_size;
float distance = sdRoundedBox(pos, half_size - corner_radius, corner_radius);
if (UV.x < progress) {
COLOR = progress_color;
float position_gradient = UV.x - (progress - gradient_length); // 0.0 -> length
float normalized_position = clamp(position_gradient / gradient_length, 0.0, 1.0);
COLOR += white_color * normalized_position * 0.2;
float shift = TIME * star_size;
vec2 grid_coord = (FRAGCOORD.xy + vec2(-shift, shift)) / star_size;
// 36° rotation matrix.
const mat2 rot36 = mat2(vec2(0.8090, -0.5878), vec2(0.5878, 0.8090));
grid_coord *= rot36;
float index_y = floor(grid_coord.y);
vec2 fraction = fract(grid_coord);
// Shift X.
if (mod(index_y, 2.0) == 1.0) {
fraction.x = fract(grid_coord.x + 0.5);
}
vec2 pos = fraction - vec2(0.5, 0.5);
float distance = sdRoundedStar(pos, 0.4, 0.02);
if (distance < 0.0) {
COLOR *= 0.93;
}
} else {
// Grainy checker pattern.
float grain = mod(floor(FRAGCOORD.x * 0.3) + floor(FRAGCOORD.y * 0.3), 3.0);
COLOR = background_color - grain * grain_darkness;
}
// Border.
float border_alpha = 1.0 - smoothstep(border_size - edge_softness, border_size, abs(distance));
COLOR = mix(COLOR, outline_color, border_alpha);
// Rounded corners.
float smoothed_alpha = 1.0 - smoothstep(0.0, edge_softness, distance);
COLOR.a = smoothed_alpha;
}

View File

@@ -0,0 +1 @@
uid://c62wifgla7rux

View File

@@ -0,0 +1,71 @@
shader_type canvas_item;
uniform float outline_thickness: hint_range(0.0, 8.0, 0.5) = 1.0;
uniform vec4 outline_color: source_color = vec4(1.0);
uniform bool high_performance_mode = true; // 高性能模式,减少采样
void vertex() {
VERTEX += (UV * 2.0 - 1.0) * outline_thickness;
}
void fragment() {
vec2 uv = UV;
vec2 texture_pixel_size = vec2(1.0) / (vec2(1.0) / TEXTURE_PIXEL_SIZE + vec2(outline_thickness * 2.0));
uv = (uv - texture_pixel_size * outline_thickness) * TEXTURE_PIXEL_SIZE / texture_pixel_size;
vec4 texture_color = vec4(0.0);
if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) {
texture_color = texture(TEXTURE, uv);
}
// 如果当前像素不透明,直接设置颜色
if (texture_color.a > 0.5) {
COLOR = texture_color;
} else {
// 需要计算描边
float outline_alpha = 0.0;
if (high_performance_mode) {
// 高性能模式只检查4个主要方向
vec2 directions[4] = {
vec2(outline_thickness, 0.0),
vec2(-outline_thickness, 0.0),
vec2(0.0, outline_thickness),
vec2(0.0, -outline_thickness)
};
for (int i = 0; i < 4; i++) {
vec2 check_uv = uv + directions[i] * TEXTURE_PIXEL_SIZE;
if (check_uv.x >= 0.0 && check_uv.x <= 1.0 && check_uv.y >= 0.0 && check_uv.y <= 1.0) {
float check_alpha = texture(TEXTURE, check_uv).a;
outline_alpha = max(outline_alpha, check_alpha);
if (outline_alpha > 0.9) break; // 早期退出
}
}
} else {
// 标准模式8方向检查
vec2 directions[8] = {
vec2(outline_thickness, 0.0), vec2(-outline_thickness, 0.0),
vec2(0.0, outline_thickness), vec2(0.0, -outline_thickness),
vec2(outline_thickness * 0.707, outline_thickness * 0.707),
vec2(-outline_thickness * 0.707, outline_thickness * 0.707),
vec2(outline_thickness * 0.707, -outline_thickness * 0.707),
vec2(-outline_thickness * 0.707, -outline_thickness * 0.707)
};
for (int i = 0; i < 8; i++) {
vec2 check_uv = uv + directions[i] * TEXTURE_PIXEL_SIZE;
if (check_uv.x >= 0.0 && check_uv.x <= 1.0 && check_uv.y >= 0.0 && check_uv.y <= 1.0) {
float check_alpha = texture(TEXTURE, check_uv).a;
outline_alpha = max(outline_alpha, check_alpha);
if (outline_alpha > 0.9) break; // 早期退出
}
}
}
// 混合颜色
float final_alpha = outline_alpha * outline_color.a;
COLOR = vec4(outline_color.rgb * final_alpha + texture_color.rgb * texture_color.a,
max(final_alpha, texture_color.a));
}
}

View File

@@ -0,0 +1 @@
uid://1ls557unpikt

View File

@@ -0,0 +1,44 @@
shader_type canvas_item;
uniform float outline_width = 1.0;
uniform vec4 outline_color : source_color;
uniform vec4 texture_region = vec4(0.0);
void fragment() {
vec4 color = texture(TEXTURE, UV);
vec2 outline_offset = vec2(outline_width) * TEXTURE_PIXEL_SIZE;
vec4 uv_region = vec4(texture_region.xy * TEXTURE_PIXEL_SIZE, texture_region.zw * TEXTURE_PIXEL_SIZE);
if (uv_region.zw == vec2(0.0)) {
uv_region.zw = vec2(1.0);
}
float uv_offset;
float a;
float max_a = 0.0;
uv_offset = UV.y - outline_offset.y;
if (uv_offset > uv_region.y) {
a = texture(TEXTURE, vec2(UV.x, uv_offset)).a;
max_a = max(a, max_a);
}
uv_offset = UV.y + outline_offset.y;
if (uv_offset < uv_region.y + uv_region.w) {
a = texture(TEXTURE, vec2(UV.x, uv_offset)).a;
max_a = max(a, max_a);
}
uv_offset = UV.x - outline_offset.x;
if (uv_offset > uv_region.x) {
a = texture(TEXTURE, vec2(uv_offset, UV.y)).a;
max_a = max(a, max_a);
}
uv_offset = UV.x + outline_offset.x;
if (uv_offset < uv_region.x + uv_region.z) {
a = texture(TEXTURE, vec2(uv_offset, UV.y)).a;
max_a = max(a, max_a);
}
COLOR = mix(color, outline_color, max_a - color.a);
}

View File

@@ -0,0 +1 @@
uid://d0uvu33hbgixy

View File

@@ -0,0 +1,54 @@
shader_type canvas_item;
// 摆动参数
uniform float sway_strength : hint_range(0.0, 0.05) = 0.02; // 摆动强度
uniform float sway_speed : hint_range(0.1, 5.0) = 1.0; // 摆动速度
uniform float wind_direction : hint_range(-1.0, 1.0) = 0.0; // 风向偏移
uniform float sway_variation : hint_range(0.0, 2.0) = 0.5; // 摆动变化
// 高度影响参数
uniform float sway_start_height : hint_range(0.0, 1.0) = 0.3; // 开始摆动的高度比例
uniform float height_curve : hint_range(1.0, 4.0) = 2.0; // 高度影响曲线
void fragment() {
vec2 uv = UV;
// 计算摆动强度(只有上半部分摆动)
float height_factor = 0.0;
if (uv.y < sway_start_height) {
// 计算从底部到摆动开始位置的渐变
height_factor = pow((sway_start_height - uv.y) / sway_start_height, height_curve);
}
// 创建多层摆动效果
float time_offset = TIME * sway_speed;
// 主摆动波
float main_sway = sin(time_offset + uv.y * 3.14159) * sway_strength;
// 次级摆动波(频率更高,幅度更小)
float secondary_sway = sin(time_offset * 2.3 + uv.y * 6.28318) * sway_strength * 0.3;
// 第三层摆动(更细微的抖动)
float micro_sway = sin(time_offset * 4.7 + uv.y * 12.56636) * sway_strength * 0.1;
// 结合所有摆动
float total_sway = (main_sway + secondary_sway + micro_sway) * height_factor;
// 添加风向偏移
total_sway += wind_direction * sway_strength * height_factor * 0.5;
// 添加摆动变化(随机性)
float variation = sin(time_offset * 0.37 + uv.x * 6.28318) * sway_variation * 0.01;
total_sway += variation * height_factor;
// 应用摆动到UV坐标
uv.x += total_sway;
// 边界检查防止UV超出范围
if (uv.x < 0.0 || uv.x > 1.0) {
COLOR = vec4(0.0, 0.0, 0.0, 0.0); // 透明
} else {
COLOR = texture(TEXTURE, uv);
}
}

View File

@@ -0,0 +1 @@
uid://ccqhg1n3d7sw8

View File

@@ -0,0 +1,43 @@
shader_type canvas_item;
uniform float intensity: hint_range(0.0, 5.0, 0.1) = 1.0;
uniform float threshold: hint_range(0.0, 2.0, 0.1) = 1.0;
uniform sampler2D screen_texture : hint_screen_texture, filter_nearest;
float vector_angle(vec2 v) {
if (abs(v.x) < 0.0001 && abs(v.y) < 0.0001) {
return 0.0; // Default angle for zero vector
}
return atan(v.y, v.x);
}
vec2 rotate_vector(vec2 v, float cos_theta, float sin_theta) {
return vec2(
v.x * cos_theta - v.y * sin_theta,
v.x * sin_theta + v.y * cos_theta
);
}
void fragment() {
vec2 r_displacement = vec2(-1.0, 0.0);
vec2 g_displacement = vec2(0.0, 0.0);
vec2 b_displacement = vec2(1.0, 0.0);
vec2 center = vec2(0.5);
vec2 dir = SCREEN_UV - center;
float angle = vector_angle(dir);
float dist = 2.0 * length(dir);
float effect = exp(intensity * (dist - threshold));
r_displacement = rotate_vector(effect * intensity * r_displacement, cos(angle), sin(angle));
g_displacement = rotate_vector(effect * intensity * g_displacement, cos(angle), sin(angle));
b_displacement = rotate_vector(effect * intensity * b_displacement, cos(angle), sin(angle));
float r = texture(screen_texture, fma(r_displacement, SCREEN_PIXEL_SIZE, SCREEN_UV), 0.0).r;
float g = texture(screen_texture, fma(g_displacement, SCREEN_PIXEL_SIZE, SCREEN_UV), 0.0).g;
float b = texture(screen_texture, fma(b_displacement, SCREEN_PIXEL_SIZE, SCREEN_UV), 0.0).b;
float a = texture(screen_texture, SCREEN_UV).a;
COLOR = vec4(r, g, b, a);
}

View File

@@ -0,0 +1 @@
uid://dbob5p3pkf7a0