godot shader 等高线的绘制 和 模型描边的绘制 和 shader 常用算法
特效/VFX Shader常用算法
https://zhuanlan.zhihu.com/p/1895926855187554873
// Shader for Godot 4.x - Single Contour Line at a Specific Height
shader_type spatial;
// -- 全局变量 --
varying vec3 world_pos;
// -- 等高线参数 --
uniform vec4 contour_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
// 【替换】不再需要间隔,而是指定一个目标高度
uniform float target_height : hint_range(0.25, 1.5, 0.01) = 1.0;
uniform float line_width_pixels : hint_range(0.5, 10.0, 0.1) = 2.0;
uniform float line_smoothness : hint_range(0.0, 5.0, 0.1) = 1.0;
// -- 地形基础颜色 --
uniform vec4 base_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
void vertex() {
world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
}
void fragment() {
vec3 albedo = base_color.rgb;
float height = world_pos.y;
// 动态世界宽度和模糊度的计算保持不变,这是正确的
float dynamic_world_width = line_width_pixels * fwidth(height);
float dynamic_smoothness = line_smoothness * fwidth(height);
// 【核心修改】计算当前高度与目标高度的绝对垂直距离
float distance_from_target = abs(height - target_height);
// 我们希望线条的总宽度是 dynamic_world_width,所以中心线两边各占一半宽度
float half_width = dynamic_world_width * 0.5;
// 使用 smoothstep 来创建混合因子
// 当 distance_from_target 在 half_width 范围内时,我们认为是线上
// 1.0 减去 smoothstep 的结果,可以得到一个中心为1,向外平滑衰减到0的混合因子
float contour_mix = 1.0 - smoothstep(half_width, half_width + dynamic_smoothness, distance_from_target);
// 混合基础颜色和等高线颜色
vec3 final_color = mix(albedo, contour_color.rgb, contour_mix);
ALBEDO = final_color;
}
//=================================================================================================================================
//// Shader for Godot 4.x - Screen-Space Constant Width Contours (CORRECTED)
//shader_type spatial;
//
//// -- 全局变量 --
//// varying 用于将数据从 vertex() 函数传递到 fragment() 函数
//// GPU 会自动为每个像素对顶点之间的值进行插值
//varying vec3 world_pos;
//
//// -- 等高线参数 --
//uniform vec4 contour_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
//uniform float contour_interval : hint_range(0.1, 50.0, 0.1) = 10.0;
//uniform float line_width_pixels : hint_range(0.5, 10.0, 0.1) = 2.0;
//uniform float line_smoothness : hint_range(0.0, 5.0, 0.1) = 1.0;
//
//// -- 地形基础颜色 --
//uniform vec4 base_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
//
//
//// 【新增】vertex() 函数
//// 这个函数在渲染模型的每个顶点时执行一次
//void vertex() {
//// 计算顶点的世界坐标并将其存入 varying 变量
//// MODEL_MATRIX 将模型的本地坐标 (VERTEX) 转换到世界坐标
//world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
//}
//
//
//// fragment() 函数在渲染模型的每个像素时执行一次
//void fragment() {
//vec3 albedo = base_color.rgb;
//
//// 1. 【修正】使用从 vertex() 传递过来的 varying 变量 world_pos
//// world_pos 在这里是经过GPU插值后,当前像素的精确世界坐标
//float height = world_pos.y;
//
//// 2. 计算动态世界宽度 (这部分逻辑不变且正确)
//// fwidth(height) 计算插值后的 height 值在一个像素内的变化范围
//float dynamic_world_width = line_width_pixels * fwidth(height);
//float dynamic_smoothness = line_smoothness * fwidth(height);
//
//// 3. 计算等高线混合因子 (这部分逻辑不变且正确)
//float height_frac = fract(height / contour_interval);
//float distance_to_line = min(height_frac, 1.0 - height_frac) * contour_interval;
//
//// 使用动态计算的宽度和模糊度进行平滑过渡
//float line_factor = smoothstep(dynamic_world_width - dynamic_smoothness, dynamic_world_width, distance_to_line);
//
//// 4. 混合颜色 (这部分逻辑不变且正确)
//vec3 final_color = mix(contour_color.rgb, albedo, line_factor);
//
//ALBEDO = final_color;
//}
//=================================================================================================================================
//shader_type spatial;
//
//// Paramètres de l'outline
//uniform float outline_width : hint_range(0.0, 10.0, 0.1) = 5.0;
//uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); // Couleur du contour
//
//// Couleurs pour le dégradé
//uniform vec4 color_start : source_color = vec4(0.0, 0.0, 1.0, 1.0); // Bleu
//uniform vec4 color_end : source_color = vec4(1.0, 0.5, 0.0, 1.0); // Orange
//
//// Fonction pour calculer l'effet Fresnel
//float fresnel(float amount, vec3 normal, vec3 view)
//{
//return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), amount);
//}
//
//void fragment()
//{
//// Calcul de l'effet Fresnel pour déterminer l'outline
//float basic_fresnel = fresnel(outline_width, NORMAL, VIEW);
//basic_fresnel = step(0.5, basic_fresnel); // 0.5 est une valeur qui contrôle l'épaisseur de l'outline
//
//// Génération du dégradé basé sur les coordonnées UV.y
//float gradient_factor = clamp(UV.y, 0.0, 1.0);
//vec3 gradient_color = mix(color_start.rgb, color_end.rgb, gradient_factor);
//
//// Appliquer la couleur de l'outline et mélanger avec la couleur du dégradé
//vec3 final_color = mix(gradient_color, outline_color.rgb, basic_fresnel);
//
//// Assigner la couleur finale au matériau
//ALBEDO = final_color;
//ALPHA = mix(color_start.a, color_end.a, gradient_factor); // Transparence basée sur le dégradé
//}
浙公网安备 33010602011771号