惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MongoDB | Blog
MongoDB | Blog
B
Blog
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
博客园 - Franky
V
V2EX
IT之家
IT之家
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
F
Fortinet All Blogs
I
InfoQ
云风的 BLOG
云风的 BLOG
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog

博客园 - porter_代码工作者

给 codex 的长期任务,长沙一个定时任务,做保活功能 .net nupkgs 配置 Vibe Coding ---- 2026年3月 很火的词 bigemap 软件 godot 透明 与 混合模式 叠加使用效果 AI 回复 godot 描边插件 C# ScottPlot 高性能图表 高性能绘图库 godot + Avalonia 渲染第三方UI 判断左手坐标系和右手坐标系的方法 国产操作系统: 项目配置 .net 添加Nuget源 godot 位置 和 角度 的平滑插值 godot 通过代码程序化地生成一个三维数据场,然后使用光线步进(Ray Marching)着色器将其渲染出来。 godot shader 控制 颜色绘制的 金典公式 godot 四元数 旋转 godot 二维报表库 godot 5.4.4 线程安全的调用方法 godot FPS 第三人称教程 UE4脸部捕捉 LiveLink 数据 常用四元数的值 unity Avatar (化身) 使用electron-builder打包 vue3 项目 exe
godot shader 等高线的绘制 和 模型描边的绘制 和 shader 常...
porter_代码工作者 · 2025-08-16 · via 博客园 - porter_代码工作者

特效/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é
//}