尧图网络科技 Logo 尧图网络科技
  • 首页
  • 关于我们
  • 建站服务
  • UI 设计
  • 案例展示
  • SEO 优化
  • 资讯中心
  • 联系我们

资讯详情

深度解读 · 专业分析

  • 首页
  • 资讯中心
  • /
  • Godot Outline

最新资讯

  • 全部资讯
  • 行业动态
  • UI 设计
  • SEO 优化
  • 网站开发

Godot Outline

📅 发布时间:2026/6/27 0:46:14 👁 浏览次数:
Godot Outline

Godot Outline

Godot 4.5 这几天更新了,补全了模板缓冲,

在渲染Depth Buffer时,一般使用D32S8的类似格式。在Godot中,原本Depth Buffer就只渲染了Depth,因此S8的通道没有被使用。Stencil即特定材质可以向这个通道里写入内容,本文先称为Stencil通道,在后续过程中被其他材质读取使用。

但是直接使用 Stencil 中的 Outline 创建的几何体边框在

https://www.reddit.com/r/godot/comments/1nniemv/finally_clean_1pixel_outlines_in_godot_using/

The method still needs some work. I haven’t found a way to read the stencil buffer directly in a shader, so I created two post-processing effects: one that renders the stencil buffer in green and another in red to a SubViewport. Then I use that SubViewport texture for the edge detection.

Could you achieve this using a customized version of the default stencil outline (which uses BaseMaterial3D Grow), but change the grow effect to always be 1 pixel in screen space? Surely there's a way to compute this in a custom shader, without needing separate viewports.

I wish. The current grow technique moves the faces along their normals, leaving gaps in low poly geometry. I could simplify my shader a bunch if the stencil buffer as a whole could be passed to a shader, to my knowledge this is not possible as of version 4.5 but I would love to be proven wrong.

Edit for clarification: by simplify I mean remove the need for a subviewport

回顾 Unity 中的 Stencil Outline

方案一:生成平滑法线

I extended the SurfaceTool to bake smooth normals into the COLOR of my low poly models and used that to do the classic "pixel perfect" outline.

ColorOutline.gdshader

shader_type spatial;
render_mode unshaded, cull_front, depth_draw_always;uniform float outline_width = 3.0;
uniform float distance_fade_max = 75.0;
uniform float distance_fade_min = 125.0;void fragment() {float distance_modifier = clamp(smoothstep(distance_fade_min, distance_fade_max, length(VERTEX)), 0.0, 1.0);ALBEDO = vec3(0.0);ALPHA = 0.8 * distance_modifier;
}void vertex() {vec4 clip_position = PROJECTION_MATRIX * (MODELVIEW_MATRIX * vec4(VERTEX, 1.0));vec3 packed_normal = (COLOR.rgb * 2.0) - vec3(1.0);vec3 clip_normal = mat3(PROJECTION_MATRIX) * (mat3(MODELVIEW_MATRIX) * packed_normal);vec2 offset = normalize(clip_normal.xy) / VIEWPORT_SIZE * clip_position.w * outline_width * 2.0;clip_position.xy += offset;POSITION = clip_position;
}

MeshOutlinePostImportColor.gd

@tool
extends EditorScenePostImportfunc _post_import(scene: Node) -> Object:# Loop through any child mesh instances# If the mesh has a path ending in tres, we use it so baked some smooth normals to its tangentfor child: Node in scene.get_children():if child is MeshInstance3D:if child.mesh.resource_path.ends_with('.tres'):        _pack_smooth_normals(child.mesh)return scenefunc _pack_smooth_normals(mesh: ArrayMesh) -> void:    var new_mesh := ImporterMesh.new()for i: int in range(mesh.get_surface_count()):var st := SurfaceTool.new()st.create_from(mesh, i)st.generate_normals_to_color(false)new_mesh.add_surface(st.get_primitive_type(), st.commit_to_arrays(), [], {}, mesh.surface_get_material(i), mesh.surface_get_name(i))var new_array_mesh := new_mesh.get_mesh()  ResourceSaver.save(new_array_mesh, mesh.resource_path)

surface_tool.cpp

void SurfaceTool::generate_normals_to_color(bool p_flip) {ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES);bool was_indexed = index_array.size();deindex();ERR_FAIL_COND((vertex_array.size() % 3) != 0);HashMap<SmoothGroupVertex, Vector3, SmoothGroupVertexHasher> smooth_hash;for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) {Vertex *v = &vertex_array[vi];Vector3 normal;if (!p_flip) {normal = Plane(v[0].vertex, v[1].vertex, v[2].vertex).normal;} else {normal = Plane(v[2].vertex, v[1].vertex, v[0].vertex).normal;}for (int i = 0; i < 3; i++) {// Add face normal to smooth vertex influence if vertex is member of a smoothing groupif (v[i].smooth_group != UINT32_MAX) {Vector3 *lv = smooth_hash.getptr(v[i]);if (!lv) {smooth_hash.insert(v[i], normal);} else {(*lv) += normal;}} else {normal += Vector3(1.0, 1.0, 1.0);normal /= 2.0;v[i].color = Color(normal.x, normal.y, normal.z);}}}for (Vertex &vertex : vertex_array) {if (vertex.smooth_group != UINT32_MAX) {Vector3 *lv = smooth_hash.getptr(vertex);if (!lv) {vertex.color = Color();} else {Vector3 smooth_normal = lv->normalized();Vector3 packed_normal = smooth_normal + Vector3(1.0, 1.0, 1.0);packed_normal /= 2.0;vertex.color = Color(packed_normal.x, packed_normal.y, packed_normal.z);}}}format |= Mesh::ARRAY_FORMAT_COLOR;if (was_indexed) {index();}
}// And in bind_methods add
ClassDB::bind_method(D_METHOD("generate_normals_to_color", "flip"), &SurfaceTool::generate_normals_to_color, DEFVAL(false));// And add the function to the surface_tool.h
void generate_normals_to_color(bool p_flip = false);

方案二:使用 CompositorEffect

https://github.com/dmlary/godot-stencil-based-outline-compositor-effect
https://github.com/pink-arcana/godot-distance-field-outlines
https://godotshaders.com/shader/fake-stencil-silhouette-outline-object-based-but-without-depth-test/

相关新闻

gen-ui-python

gen-ui-python

2026/6/26 10:40:48 查看详情
2025国内裱纸机厂家最新推荐排行榜:聚焦智能高速与全自动机型,权威精选综合实力 TOP3 厂家

2025国内裱纸机厂家最新推荐排行榜:聚焦智能高速与全自动机型,权威精选综合实力 TOP3 厂家

2026/6/22 19:49:07 查看详情
使用Windbg分析dmp文件的方法以及实战分析实例分享 - 教程

使用Windbg分析dmp文件的方法以及实战分析实例分享 - 教程

2026/6/26 2:46:29 查看详情
RPA与Python测试自动化集成:pytest+email.mime实现智能报告分发

RPA与Python测试自动化集成:pytest+email.mime实现智能报告分发

2026/6/27 1:07:30 查看详情
软件工程实验全流程指南:从需求到部署的工程化实践

软件工程实验全流程指南:从需求到部署的工程化实践

2026/6/27 1:01:23 查看详情
正交模格与动态代数的范畴等价:量子逻辑与算子代数的统一视角

正交模格与动态代数的范畴等价:量子逻辑与算子代数的统一视角

2026/6/27 0:57:27 查看详情
Spring Boot应用XSS与SQL注入防护实战指南

Spring Boot应用XSS与SQL注入防护实战指南

2026/6/27 0:57:27 查看详情
步态感知 + 跨镜全域联动 营区人员活动空间透明化智控网络 技术解析白皮书

步态感知 + 跨镜全域联动 营区人员活动空间透明化智控网络 技术解析白皮书

2026/6/27 0:55:17 查看详情
最新Facefusion 4.7 整合包发布!解压即用/一键启动/免装环境

最新Facefusion 4.7 整合包发布!解压即用/一键启动/免装环境

2026/6/27 0:55:17 查看详情
Claude Code国内配置总失败?macOS保姆级安装教程:从Node.js到API直连,10分钟跑通

Claude Code国内配置总失败?macOS保姆级安装教程:从Node.js到API直连,10分钟跑通

2026/6/27 0:00:58 查看详情
PCL2启动器Java配置终极指南:5步彻底解决Minecraft启动问题

PCL2启动器Java配置终极指南:5步彻底解决Minecraft启动问题

2026/6/27 0:00:58 查看详情
Web身份验证漏洞实战:从密码重置到会话固定的攻防解析

Web身份验证漏洞实战:从密码重置到会话固定的攻防解析

2026/6/27 0:02:52 查看详情
WSL2下部署Openclaw:Windows开发者高效落地AI智能体的实践指南

WSL2下部署Openclaw:Windows开发者高效落地AI智能体的实践指南

2026/6/26 3:08:21 查看详情
GameServerManager:游戏服务器管理的终极解决方案

GameServerManager:游戏服务器管理的终极解决方案

2026/6/26 3:08:17 查看详情
实验室无尘室设计规范解析——华川洁净 - 华川洁净

实验室无尘室设计规范解析——华川洁净 - 华川洁净

2026/6/27 2:11:16 查看详情
YOLOv11涨点改进| CVPR 2026 | 独家创新首发、特征融合改进篇| 引入CMGF 引导特征融合机制,实现对不同模态特征的自适应增强与高效融合,助力多模态目标检测,小目标检测或分割有效涨点

YOLOv11涨点改进| CVPR 2026 | 独家创新首发、特征融合改进篇| 引入CMGF 引导特征融合机制,实现对不同模态特征的自适应增强与高效融合,助力多模态目标检测,小目标检测或分割有效涨点

2026/6/26 15:23:39 查看详情
E-E-A-T 成第一权重:2027 年无经验内容将被彻底淘汰

E-E-A-T 成第一权重:2027 年无经验内容将被彻底淘汰

2026/6/26 3:08:20 查看详情
深圳福田园岭老小区搬家公司推荐 经验足师傅高效搬运攻略 - 从来都是英雄出少年

深圳福田园岭老小区搬家公司推荐 经验足师傅高效搬运攻略 - 从来都是英雄出少年

2026/6/26 3:08:20 查看详情

关于尧图

立足北京本地的一站式网站建设服务与设计教学平台,深耕企业网站定制开发、全网 SEO 优化及网络推广服务。

快速链接

  • 关于我们
  • 建站服务
  • 案例展示
  • 资讯中心

服务项目

  • 企业官网定制
  • UI 界面设计
  • SEO 优化推广
  • 移动端适配

联系方式

电话:400-XXX-XXXX

邮箱:info@zskr.cn

地址:北京市朝阳区 XXX 路 XX 号

© 2026 尧图网络科技 版权所有 | 京 ICP 备 XXXXXXXX 号