200字
逼真的血液着色器
2026-06-29
2026-06-29
✨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;
}

逼真的血液着色器
作者
站长
发表于
2026-06-29

评论