✨sjy官网bot✨
将以下着色器代码放到mesh上,再配合噪声纹理,即可实现逼真的血液流淌的效果。
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_disabled;
//颜色与深度
uniform vec4 liquid_color : source_color = vec4(0.4, 0.01, 0.01, 1.0); // 边缘薄处的鲜血红
uniform vec4 deep_color : source_color = vec4(0.05, 0.0, 0.0, 1.0); // 中心厚处的凝血黑红
//物理光泽
uniform float roughness_val : hint_range(0.0, 1.0) = 0.05;
uniform float metallic_val : hint_range(0.0, 1.0) = 0.0;
//形状与蔓延
uniform sampler2D flow_noise;
uniform float progress : hint_range(0.0, 1.0) = 0.0;
uniform float edge_softness : hint_range(0.01, 0.5) = 0.05;
uniform float spread_width : hint_range(0.1, 3.0) = 1.0;
//法线与厚度系统
uniform sampler2D normal_texture : hint_normal; // 真正的表面波纹法线贴图
uniform float normal_strength : hint_range(0.0, 2.0) = 1.0; // 法线凹凸强度
uniform vec2 flow_speed = vec2(0.0, 0.05); // 血液流动的速度
uniform float edge_thickness : hint_range(0.01, 0.5) = 0.1; // 边缘水滴凸起的宽窄
void fragment() {
// 1. 计算扇形形状
float noise = texture(flow_noise, UV).r;
vec2 origin = vec2(0.5, 0.0);
vec2 offset = UV - origin;
offset.x *= spread_width;
float distance_from_source = length(offset);
// 核心流体遮罩 (值越大代表越靠近血液中心,值越小代表越靠近边缘)
float flow_mask = (progress * 1.8) - distance_from_source - (noise * 0.5);
// 生成带柔和边缘的透明度
float alpha = smoothstep(0.0, edge_softness, flow_mask);
// 2. 提取厚度层级 (区分“边缘区域”和“中心深水区”)
float thickness = smoothstep(0.0, edge_thickness, flow_mask);
// 3. 动态流动法线 (Surface Ripples)
// 让法线贴图随着时间缓缓向外流淌,模拟液体的动态
vec2 scrolling_uv = UV + TIME * flow_speed;
vec3 surface_normal = texture(normal_texture, scrolling_uv).rgb;
// 4. 伪造边缘厚度 (Edge Meniscus)
// 纯数学:计算出边缘朝外的方向,强制生成一个“水滴状凸起”的假法线
vec2 edge_dir = normalize(offset);
vec3 fake_bevel_normal = normalize(vec3(edge_dir.x * 2.0, edge_dir.y * 2.0, 1.0));
// 将法线向量 [-1, 1] 转换成 Godot 法线贴图需要的颜色范围 [0, 1]
vec3 edge_normal_map = fake_bevel_normal * 0.5 + 0.5;
// 5. 混合法线:边缘使用“凸起假法线”,中心使用“流动波纹法线”
vec3 final_normal = mix(edge_normal_map, surface_normal, thickness);
// 根据厚度混合颜色:中心发黑,边缘鲜红
vec3 final_color = mix(liquid_color.rgb, deep_color.rgb, thickness);
ALBEDO = final_color;
ROUGHNESS = roughness_val;
METALLIC = metallic_val;
ALPHA = alpha;
// 输出最终的法线计算结果
NORMAL_MAP = final_normal;
NORMAL_MAP_DEPTH = normal_strength;
}