优化项目架构
This commit is contained in:
108
SproutFarm-Frontend/Shader/2DCircularOutline.gdshader
Normal file
108
SproutFarm-Frontend/Shader/2DCircularOutline.gdshader
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://xrlqe0cdb3ty
|
||||
97
SproutFarm-Frontend/Shader/Animatedprogressbar.gdshader
Normal file
97
SproutFarm-Frontend/Shader/Animatedprogressbar.gdshader
Normal 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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://c62wifgla7rux
|
||||
71
SproutFarm-Frontend/Shader/FarmLotOutline.gdshader
Normal file
71
SproutFarm-Frontend/Shader/FarmLotOutline.gdshader
Normal 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));
|
||||
}
|
||||
}
|
||||
1
SproutFarm-Frontend/Shader/FarmLotOutline.gdshader.uid
Normal file
1
SproutFarm-Frontend/Shader/FarmLotOutline.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://1ls557unpikt
|
||||
44
SproutFarm-Frontend/Shader/OutlineforAtlasTexture.gdshader
Normal file
44
SproutFarm-Frontend/Shader/OutlineforAtlasTexture.gdshader
Normal 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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://d0uvu33hbgixy
|
||||
54
SproutFarm-Frontend/Shader/PlantSwayShader.gdshader
Normal file
54
SproutFarm-Frontend/Shader/PlantSwayShader.gdshader
Normal 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);
|
||||
}
|
||||
}
|
||||
1
SproutFarm-Frontend/Shader/PlantSwayShader.gdshader.uid
Normal file
1
SproutFarm-Frontend/Shader/PlantSwayShader.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ccqhg1n3d7sw8
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dbob5p3pkf7a0
|
||||
Reference in New Issue
Block a user