mcpField
G
godot-3d-materials

godot-3d-materials

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

关于 godot-3d-materials

面向 Godot 开发者的 3D 材质技能,提供 StandardMaterial3D 与 PBR 材质的设置和优化指导。内容涵盖 ORM 贴图、透明模式、材质复用、实例化参数及运行时效果。

主要功能

  1. 01PBR 与 ORM 通道打包
  2. 02透明模式与排序处理
  3. 03共享材质和实例参数
  4. 04三平面投影与风摆动
  5. 05运行时闪烁和溶解效果

适用场景

  1. 01为场景材质整理 AO、粗糙度与金属度贴图
  2. 02为树叶和栅栏配置透明裁切
  3. 03在多个网格间复用材质以减少批次开销
  4. 04为角色或植被制作次表面散射效果

安装

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

$npx skills add https://github.com/thedivergentai/game-dev-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