mcpField
G
godot-3d-materials

godot-3d-materials

github.com/thedivergentai创意与媒体909390 次安装2 周前更新
代码仓库

关于 godot-3d-materials

面向 Godot 的技能,涵盖使用 StandardMaterial3D 和着色器构建及优化 PBR 材质。通过按任务路由的脚本指导材质设置、视觉效果和渲染性能优化。

主要功能

  1. 01PBR 材质与 ORM 贴图打包
  2. 02透明模式与排序问题处理
  3. 03三平面地形材质
  4. 04植被风动画
  5. 05材质复用与批处理

适用场景

  1. 01为叶片和栅栏配置裁切透明
  2. 02为无 UV 悬崖设置材质
  3. 03实现运行时闪光或溶解效果
  4. 04为远景材质配置 LOD 简化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/thedivergentai/game-design-agentic-skills --skill godot-3d-materials

安装后在 Claude Code 中输入/godot-3d-materials确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
migration-notes.md
pbr-workflows.md
scripts/
decal_placer_expert.gd
depth_precision_fix.gd
instance_uniform_batching.gdshader
material_batcher.gd
material_fx.gd
organic_material.gd
pbr_material_builder.gd
pbr_orm_packer.gd
shader_state_manager.gd
subsurface_scattering_setup.gd
transparency_sorting_fix.gd
triplanar_world_projection.gdshader
triplanar_world.gdshader
vertex_wind_sway.gdshader
shaders/
triplanar_smooth.gdshader

详细介绍

3D 材质

Godot 中 PBR 材质和 StandardMaterial3D 的专业指南。

切勿

  • 切勿使用分开的金属度/粗糙度/AO 纹理 — 使用 ORM 打包(1 张 RGB 纹理,分别存储 Occlusion、Roughness 和 Metallic 通道),以节省纹理槽和内存。
  • 切勿忘记启用 normal_enabled — 除非设置 normal_enabled = true,否则法线贴图不会生效。静默失效很常见。
  • 切勿将 TRANSPARENCY_ALPHA 用于镂空材质 — 请改用 TRANSPARENCY_ALPHA_SCISSOR 或 TRANSPARENCY_ALPHA_HASH。完全 Alpha 混合开销很大,还会导致排序问题。
  • 切勿将 metallic 设为 0.5 — 材质要么是金属(1.0),要么是电介质(0.0)。除锈蚀/污垢过渡外,中间值不符合物理规律。
  • 切勿在未启用 HDR 的情况下使用 emission — emission 值 > 1.0 仅在“项目设置”中启用 HDR 渲染后才有效。
  • 切勿为大型环境表面使用透明材质 — 透明对象无法依靠 Z 缓冲进行早期片段剔除,导致大量过度绘制。如果网格只有很小一部分透明,请将其拆分成两个表面:一个不透明表面,一个透明表面。
  • 切勿在性能下降时仍创建数百个只有细微差别的 StandardMaterial3D 资源 — Godot 会自动复用底层着色器,以尽量减少 GPU 状态更改,前提是材质的配置标志(复选框)完全相同。请尝试将材质配置分组。
  • 切勿只靠拉远对象来解决 Z-fighting — 浮点精度会随距离增加而下降。要修复纹理闪烁,请增大 Camera3D 的 Near 平面属性,并减小 Far 属性,以压缩精度范围。
  • 切勿为每个 MeshInstance3D 使用独立的 Material 资源 — 这会破坏绘制调用批处理。请使用“实例 Uniform”,在保持单个共享材质的同时调整参数。
  • 切勿在运行时修改共享的 Material .tres/表面材质 — 调用 duplicate(true) 或启用 Local To Scene,然后先分配唯一实例再调整参数。用于闪光/溶解时,必须使用 material_fx.gd 中的 ensure_unique_override()/叠加辅助方法。
  • 切勿在没有 Cull Mask 的情况下对动态移动角色使用 Decal — 子弹孔不应该在玩家走动时粘在玩家脸上。请屏蔽角色图层。

可用脚本

必须:实现相应模式前,请先阅读对应脚本。

工作流路由器(必须/不要加载)
任务加载不要加载
StandardMaterial3D/ORM/透明度pbr_orm_packer.gd、transparency_sorting_fix.gd、material_batcher.gd、material_fx.gdtriplanar_world*.gdshader、vertex_wind_sway.gdshader
无 UV 地形/峭壁triplanar_world.gdshader 或 triplanar_world_projection.gdshader + pbr_material_builder.gd除非处理植被,否则不要加载风摆动脚本
植被风动vertex_wind_sway.gdshader除非还需要岩石/地形处理,否则不要加载 Triplanar
运行时伤害/溶解必须 material_fx.gd编辑共享的导入材质
实例颜色/生命值/纹理数组变体必须 instance_uniform_batching.gdshader每个网格各自使用 StandardMaterial3D 副本;身体纹理数组采样
HLOD/远距离材质简化material_batcher.gd(setup_lod_materials)Alpha 混合距离淡出(请使用 Pixel Dither)
有机材质 SSS/边缘光/清漆层organic_material.gd、subsurface_scattering_setup.gdMobile/Compatibility 上的 SSS 配置方案

纯 StandardMaterial3D 反照率/ORM/透明度处理:不要加载 Triplanar、风动或纹理数组着色器。

material_fx.gd

运行时特效必须使用。使用 ensure_unique_override()/叠加闪光/剪裁溶解 — 切勿对共享的 .tres 材质执行 Tween。

pbr_material_builder.gd

运行时创建 PBR 材质,支持 ORM 纹理和三平面映射。

organic_material.gd

为有机表面(皮肤、树叶)设置次表面散射和边缘光照。用于制作逼真的角色或植被材质。

triplanar_world.gdshader

适用于无 UV 映射地形的三平面投影着色器。根据表面法线混合纹理。适用于悬崖、洞穴或程序化生成的地形。

pbr_orm_packer.gd

专业 PBR 资源工具。将环境光遮蔽、粗糙度和金属度打包到单张 ORM 纹理中,以优化显存占用和绘制调用。

vertex_wind_sway.gdshader

高性能、由 GPU 驱动的植被动画。使用顶点世界坐标和顶点颜色权重绘制,在无需骨架的情况下模拟风吹效果。

triplanar_world_projection.gdshader

无需 UV 的环境映射。沿 X/Y/Z 轴投影纹理,使其在复杂岩石和地形表面自然融合。

subsurface_scattering_setup.gd

配置逼真的有机材质。介绍 Forward+ 渲染的皮肤模式、透射和深度散射设置。

instance_uniform_batching.gdshader

高速批处理的架构模式。允许 10,000 个网格共用一种材质,同时通过实例 uniform 保持各自的颜色或生命值状态。

decal_placer_expert.gd

动态 3D 贴花系统,支持剔除掩码和生命周期管理,可用于冲击效果。

transparency_sorting_fix.gd

使用 Alpha Hash 和 Depth Prepass 策略解决视觉伪影。

shader_state_manager.gd

用于在多个实体上切换基于着色器的视觉状态(冻结、烧伤)的简洁模式。

depth_precision_fix.gd

从摄像机端修复大规模世界中的 Z-fighting 和纹理闪烁问题。

material_batcher.gd

全局覆盖系统,确保环境网格以优化且状态锁定的批次进行绘制。


StandardMaterial3D 清单(脚本优先)

  1. 打包 AO/粗糙度/金属度 → 必需 pbr_orm_packer.gd;设置 orm_texture(切勿使用三张独立贴图)。
  2. 在指定 normal_texture 之前启用 normal_enabled(否则会静默无效)。
  3. 从下方矩阵中选择透明度模式——镂空材质不要使用文档默认的 ALPHA。
  4. 有机皮肤/树叶 → organic_material.gd + subsurface_scattering_setup.gd(仅 Forward+ 支持真正的 SSS)。
  5. 运行时闪烁/溶解 → 必需,先调用 material_fx.gd ensure_unique_override()。
  6. 共享网格的色调/变体 → instance_uniform_batching.gdshader;切勿为每个实例创建独有的 .tres。
  7. 简化远距离 LOD / 像素抖动淡出 → material_batcher.gd setup_lod_materials()。
  8. 启用 SSS/透明涂层/各向异性之前,请检查 Forward+ 与 Mobile 的功能矩阵。
Forward+ 与 Mobile(材质功能)
功能Forward+Mobile / Compatibility原因
次表面散射 / Skin Mode完整支持有限支持 / 通常不可用SSS 需要 Forward+ 光照路径;在 Mobile 上可通过边缘光 + 透射烘焙来模拟
Clearcoat支持通常会被剥离 / 近似处理额外高光波瓣会产生开销;远距离 LOD 和 Mobile 上应移除
Anisotropy支持建议关闭流动贴图 + 各向异性 BRDF 会占用大量移动设备片元预算
Alpha Hash / Pixel Dither 淡出支持建议使用 Alpha Scissor 或不透明抖动哈希噪声 + 过度绘制会影响瓦片式 GPU
实例化 uniform(批处理)支持支持(建议使用)保持使用同一种材质;避免因资源各不相同而中断绘制

透明模式

决策矩阵
模式使用场景性能排序问题
ALPHA_SCISSOR植被、铁丝网快无
ALPHA_HASH抖动淡出、LOD 过渡快有噪点
ALPHA玻璃、水、godot-particles慢有(渲染顺序)
Alpha Scissor(镂空)
# For leaves, grass, fences
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
mat.alpha_scissor_threshold = 0.5  # Pixels < 0.5 alpha = discarded
mat.albedo_texture = load("res://leaf.png")  # Must  have alpha channel

# Enable backface culling for performance
mat.cull_mode = BaseMaterial3D.CULL_BACK
Alpha Hash(抖动)
# For smooth fade-outs without sorting issues
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH
mat.alpha_hash_scale = 1.0  # Dither pattern scale

# Animate fade
var tween := create_tween()
tween.tween_property(mat, "albedo_color:a", 0.0, 1.0)
Alpha Blend(完全透明)
# For glass, water (expensive)
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mat.blend_mode = BaseMaterial3D.BLEND_MODE_MIX

# Disable depth writing for correct blending
mat.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_DISABLED
mat.cull_mode = BaseMaterial3D.CULL_DISABLED  # Show both sides

纹理通道打包

必需使用 pbr_orm_packer.gd 处理 R=AO / G=Roughness / B=Metallic。不要在此处内联打包方案。仅当导入的图集与 ORM 布局不一致时,才自定义通道映射。


着色器转换

何时转换为 ShaderMaterial
  • 需要自定义效果(溶解、顶点位移)
  • 遇到 StandardMaterial3D 的功能限制
  • 着色器优化(移除未使用的功能)
转换工作流
# 1. Create StandardMaterial3D with all settings
var std_mat := StandardMaterial3D.new()
std_mat.albedo_color = Color.RED
std_mat.metallic = 1.0
std_mat.roughness = 0.2

# 2. Convert to ShaderMaterial
var shader_mat := ShaderMaterial.new()
shader_mat.shader = load("res://custom_shader.gdshader")

# 3. Transfer parameters manually
shader_mat.set_shader_parameter("albedo", std_mat.albedo_color)
shader_mat.set_shader_parameter("metallic", std_mat.metallic)
shader_mat.set_shader_parameter("roughness", std_mat.roughness)

材质变体(Godot 4.0+)

高效复用材质
# Base material (shared)
var base_red_metal := StandardMaterial3D.new()
base_red_metal.albedo_color = Color.RED
base_red_metal.metallic = 1.0

# Variant 1: Rough
var rough_variant := base_red_metal.duplicate()
rough_variant.roughness = 0.8

# Variant 2: Smooth
var smooth_variant := base_red_metal.duplicate()
smooth_variant.roughness = 0.1

# Note: Use resource_local_to_scene for per-instance tweaks

性能优化

材质批处理
# ✅ GOOD: Reuse materials across meshes
const SHARED_STONE := preload("res://materials/stone.tres")

func _ready() -> void:
    for wall in get_tree().get_nodes_in_group("stone_walls"):
        wall.material_override = SHARED_STONE
    # All walls batched in single draw call

# ❌ BAD: Unique material per mesh
func _ready() -> void:
    for wall in get_tree().get_nodes_in_group("stone_walls"):
        var mat := StandardMaterial3D.new()  # New material!
        mat.albedo_color = Color(0.5, 0.5, 0.5)
        wall.material_override = mat
    # Each wall is separate draw call
纹理图集
# Combine multiple materials into one texture atlas
# Then use UV offsets to select regions

# material_atlas.gd
extends StandardMaterial3D

func set_atlas_region(tile_x: int, tile_y: int, tiles_per_row: int) -> void:
    var tile_size := 1.0 / tiles_per_row
    uv1_offset = Vector3(tile_x * tile_size, tile_y * tile_size, 0)
    uv1_scale = Vector3(tile_size, tile_size, 1)

边缘情况

法线贴图不起作用
# Problem: Forgot to enable
mat.normal_enabled = true  # REQUIRED

# Problem: Wrong texture import settings
# In Import tab: Texture → Normal Map = true
模型上出现纹理接缝
# Problem: Mipmaps causing seams
# Solution: Disable mipmaps for tightly-packed UVs
# Import → Mipmaps → Generate = false
材质看起来很平
# Problem: Missing normal map or roughness variation
# Solution: Add normal map + roughness texture

mat.normal_enabled = true
mat.normal_texture = load("res://normal.png")
mat.roughness_texture = load("res://roughness.png")

专家技巧与优化

1. 使用 Pixel Dither 进行 LOD 过渡

使用分层细节级别(HLOD)或可见性范围在远距离淡出物体时,标准 Alpha 混合会因透明边界重叠而造成严重的性能损耗。请将材质的 Distance Fade 模式设为 Pixel Dither。这样既能实现视觉上平滑的淡出,又能完全使用高性能的不透明渲染管线。

2. 模板缓冲区(Godot 4.5+)

直接在 StandardMaterial3D 中使用模板缓冲区。这样无需为基本效果编写自定义着色器,即可轻松为被墙壁遮挡的物体渲染轮廓或 X 射线效果。

3. AR 阴影叠加着色器

如果你正在开发 AR 游戏,可能希望虚拟阴影显示在现实世界的摄像头画面上。不要使用标准混合,而应在空间着色器中使用 Godot 内置的 shadow_to_opacity 渲染模式。

shader_type spatial;
// shadow_to_opacity makes the material invisible when lit, 
// but opaque (dark) when it receives a shadow from another 3D object.
render_mode blend_mix, depth_draw_opaque, cull_back, shadow_to_opacity;

void fragment() {
    // The surface color is black; opacity will be driven by incoming shadows
    ALBEDO = vec3(0.0, 0.0, 0.0);
}

专家模式:材质-纹理数组(实例化变体)

对于每个实例的颜色/生命值以及纹理数组索引变体,必须使用 instance_uniform_batching.gdshader。通过 GeometryInstance3D.set_instance_shader_parameter 设置 texture_index——切勿为每种树木/人群变体创建独立材质。


专家模式:溶解着色器集成(Alpha Scissor)

使用 Alpha Scissor 实现高性能溶解效果(保留阴影,避免 Alpha 排序)。必须使用 material_fx.gd 中的 dissolve_scissor()——该函数会先复制材质覆盖项。


专家模式:材质 LOD 系统(HLOD)

网格 LOD 会自动处理;材质着色则不会。对于可见性范围切换、远距离材质功能剥离,以及 Pixel Dither 距离淡出(而非 Alpha 混合),必须使用 material_batcher.gd 中的 setup_lod_materials()。

专家见解(WHY — 保留在正文中)

  • ORM 打包 — WHY:三张独立贴图会让采样器槽位增加到三倍,并破坏批处理。将 AO、粗糙度和金属度打包到一张 RGB 贴图中(pbr_orm_packer.gd)。
  • 金属度设为 0.5 — WHY:PBR 金属的金属度为 0 或 1;中间值仅用于污垢/锈蚀过渡,不应用作默认涂装。
  • 共享材质修改 — WHY:调整共享的 .tres 会影响每个实例。在运行时应用 FX 前,使用 duplicate(true) 或 Local To Scene(material_fx.gd)。
  • 像素抖动 LOD 淡出 — WHY:Alpha 混合距离淡出会使片段留在透明渲染管线中;抖动则保持不透明(material_batcher.gd)。

深入方案(按需查阅)

主题参考资料/脚本
金属/电介质预设/SSS/清漆层pbr-workflows.md

参考资料

渐进式披露:仅在研究特定 API 时打开官方文档链接; 将工作分派给相关领域时再加载相关技能,不要预加载整个技能网络。

官方文档
  • Standard Material 3D 和 ORM Material 3D — 关于反照率/金属度/粗糙度、ORM 打包、透明模式,以及 StandardMaterial3D 功能标志的主要 PBR 教程。
  • BaseMaterial3D — 提供透明度枚举、纹理通道、剔除/深度绘制、距离淡出和次表面散射控制的通用 API。
  • StandardMaterial3D — 本技能的构建器、FX 助手和预设中使用的具体材质类。
  • ORMMaterial3D — 当遮蔽/粗糙度/金属度已位于同一张 RGB 纹理中时,使用专用的 ORM 打包材质路径。
  • 使用 Decal — 投影 Decal、剔除掩码,以及用于弹孔和细节表现且无需唯一材质的性能限制。
  • 导入图像 — 正确的法线贴图和通道导入设置,确保 PBR 贴图不会被当作颜色数据处理。
  • 可见性范围(HLOD) — 距离切换/淡出模式,可与简化的远景材质和像素抖动距离淡出配合使用。
  • Spatial 着色器 — 当 StandardMaterial3D 无法满足需求时,用于三平面映射、风吹摆动、instance uniform 和 shadow_to_opacity 的内置功能。
  • 第一个 3D 着色器 — 将 StandardMaterial3D 设置转换为可编辑 Spatial ShaderMaterial 的方法。
  • GeometryInstance3D — 用于共享材质批处理的 set_instance_shader_parameter、材质叠加/覆盖和可见性范围属性。
  • GPU 优化 — 过度绘制、透明度开销和批处理方面的指导,说明了 ORM 打包及避免使用唯一材质的原因。
相关技能
前置条件
  • godot-project-foundations — 在编写可复用的 .tres 材质和纹理集之前,必须掌握节点、资源和导入基础知识。
  • godot-resource-data-patterns — 材质/纹理资源、复制与共享,以及可保持绘制调用批处理完整的数据驱动预设。
  • godot-shaders-basics — 转换 StandardMaterial3D 或编写三平面/实例 uniform 着色器之前,需掌握着色语言和 ShaderMaterial 基础知识。
补充
  • godot-3d-lighting — 发射能量、HDR、GI 和 AreaLight3D 的交互,这些因素决定了 PBR 材质和发光材质在场景中的实际观感。
  • godot-3d-world-building — 在大型关卡几何体上应用共享环境材质、贴花和三平面投影。
  • godot-camera-systems — Camera3D 的近远裁剪面和取景设置,可解决单靠材质无法处理的 Z-fighting / 深度精度问题。
  • godot-particles — 粒子绘制模式和 Alpha 管线必须与材质透明度选项(scissor/hash 与 blend)保持一致。
  • godot-performance-optimization — 扩展使用独特材质与共享材质时的绘制调用批处理、MultiMesh 和 GPU 预算。
  • godot-debugging-profiling — 使用 GPU/过度绘制分析器,验证材质变更后透明度和材质状态是否出现回归。
下游 / 使用方
  • godot-genre-open-world — 大型世界会用到此技能中的 HLOD 可见范围、抖动式距离淡出和共享材质批处理模式。
  • godot-procedural-generation — 缺少 UV 或 UV 不稳定时,程序化网格和地形通常需要三平面/世界投影材质。
  • godot-adapt-2d-to-3d — 将平面美术素材转入 3D 时,需要设置 PBR 贴图、法线导入和透明度模式;这些内容均在此介绍。
主入口
  • godot-master — 用于跨技能发现的库路由器和镜像模块入口。

评论

支持 Markdown