mirror of
https://github.com/Rundll86/Dog-Lynx-And-HCN.git
synced 2026-05-27 22:41:56 +08:00
109 lines
3.8 KiB
Plaintext
109 lines
3.8 KiB
Plaintext
|
|
shader_type canvas_item;
|
||
|
|
render_mode blend_add;
|
||
|
|
|
||
|
|
// --- Uniforms (可在编辑器中调整的参数) ---
|
||
|
|
|
||
|
|
// 水晶的基础颜色
|
||
|
|
uniform vec4 crystal_color : source_color = vec4(0.4, 0.8, 1.0, 1.0);
|
||
|
|
// 内部辉光的颜色
|
||
|
|
uniform vec4 glow_color : source_color = vec4(0.8, 0.9, 1.0, 1.0);
|
||
|
|
// 高光的颜色
|
||
|
|
uniform vec4 highlight_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
||
|
|
|
||
|
|
// 控制水晶的整体大小
|
||
|
|
uniform float scale = 1.0;
|
||
|
|
// 控制折射/扭曲的强度
|
||
|
|
uniform float distortion_strength = 0.05;
|
||
|
|
// 控制内部细节的复杂度
|
||
|
|
uniform float detail_noise_scale = 8.0;
|
||
|
|
// 控制闪烁的速度
|
||
|
|
uniform float flicker_speed = 2.0;
|
||
|
|
|
||
|
|
|
||
|
|
// --- Helper Functions (辅助函数) ---
|
||
|
|
|
||
|
|
// 一个简单的伪随机数生成器
|
||
|
|
float random (in vec2 st) {
|
||
|
|
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2D 噪声函数,用于创建有机的内部纹理
|
||
|
|
float noise (in vec2 st) {
|
||
|
|
vec2 i = floor(st);
|
||
|
|
vec2 f = fract(st);
|
||
|
|
|
||
|
|
// 四个角的随机值
|
||
|
|
float a = random(i);
|
||
|
|
float b = random(i + vec2(1.0, 0.0));
|
||
|
|
float c = random(i + vec2(0.0, 1.0));
|
||
|
|
float d = random(i + vec2(1.0, 1.0));
|
||
|
|
|
||
|
|
// 平滑插值
|
||
|
|
vec2 u = f * f * (3.0 - 2.0 * f);
|
||
|
|
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// --- Main Shader Logic ---
|
||
|
|
void fragment() {
|
||
|
|
// 1. 将 UV 坐标归一化到 [-1, 1] 范围,并调整宽高比
|
||
|
|
vec2 uv = (UV - 0.5) * 2.0;
|
||
|
|
uv.x *= SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y;
|
||
|
|
uv /= scale;
|
||
|
|
|
||
|
|
// 2. 定义水晶的形状 (这里使用心形线作为基础,你也可以换成其他形状)
|
||
|
|
// 心形线公式: (x^2 + y^2 - 1)^3 - x^2 * y^3 = 0
|
||
|
|
float heart_shape = (pow(uv.x * uv.x + uv.y * uv.y - 1.0, 3.0) - uv.x * uv.x * pow(uv.y, 3.0));
|
||
|
|
|
||
|
|
// 使用 smoothstep 创建一个柔和的边缘
|
||
|
|
float crystal_mask = 1.0 - smoothstep(-0.1, 0.1, heart_shape);
|
||
|
|
|
||
|
|
// 3. 创建内部折射/扭曲效果
|
||
|
|
// 我们对坐标进行轻微的扰动,然后对水晶本身进行采样
|
||
|
|
vec2 distorted_uv = uv + vec2(noise(uv * detail_noise_scale + TIME * 0.1),
|
||
|
|
noise(uv * detail_noise_scale + TIME * 0.1 + 100.0)) * distortion_strength;
|
||
|
|
float distorted_heart_shape = (pow(distorted_uv.x * distorted_uv.x + distorted_uv.y * distorted_uv.y - 1.0, 3.0) - distorted_uv.x * distorted_uv.x * pow(distorted_uv.y, 3.0));
|
||
|
|
float refraction_mask = 1.0 - smoothstep(-0.1, 0.1, distorted_heart_shape);
|
||
|
|
|
||
|
|
// 4. 创建内部辉光和细节
|
||
|
|
// 使用噪声创建内部纹理
|
||
|
|
float internal_noise = noise(uv * detail_noise_scale - TIME * 0.2);
|
||
|
|
// 将噪声值限制在水晶形状内
|
||
|
|
float internal_glow = internal_noise * crystal_mask;
|
||
|
|
// 增强辉光效果
|
||
|
|
internal_glow = pow(internal_glow, 2.0);
|
||
|
|
|
||
|
|
// 5. 创建高光
|
||
|
|
// 定义一个高光区域
|
||
|
|
vec2 highlight_pos = uv - vec2(-0.2, 0.3); // 高光位置
|
||
|
|
float highlight = 1.0 - smoothstep(0.0, 0.15, length(highlight_pos));
|
||
|
|
// 让高光也受噪声影响,看起来不那么死板
|
||
|
|
highlight *= (1.0 + noise(highlight_pos * 10.0) * 0.5);
|
||
|
|
// 高光也必须在水晶形状内
|
||
|
|
highlight *= crystal_mask;
|
||
|
|
// 让高光更锐利
|
||
|
|
highlight = pow(highlight, 8.0);
|
||
|
|
|
||
|
|
// 6. 创建闪烁效果
|
||
|
|
float flicker = 1.0 + (noise(vec2(TIME * flicker_speed)) - 0.5) * 0.2;
|
||
|
|
|
||
|
|
// 7. 组合所有颜色
|
||
|
|
vec4 final_color = vec4(0.0);
|
||
|
|
|
||
|
|
// 基础水晶颜色
|
||
|
|
final_color += crystal_color * crystal_mask;
|
||
|
|
|
||
|
|
// 叠加内部辉光
|
||
|
|
final_color += glow_color * internal_glow * 0.5;
|
||
|
|
|
||
|
|
// 叠加高光
|
||
|
|
final_color += highlight_color * highlight;
|
||
|
|
|
||
|
|
// 应用闪烁
|
||
|
|
final_color *= flicker;
|
||
|
|
|
||
|
|
// 8. 输出最终颜色
|
||
|
|
// 由于我们使用了 blend_add 混合模式,背景会自动透出
|
||
|
|
COLOR = final_color;
|
||
|
|
}
|