godot-3d-materials

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

3D Materials

3D材质

Expert guidance for PBR materials and StandardMaterial3D in Godot.
Godot中PBR材质与StandardMaterial3D的专家级指导。

NEVER Do

绝对不要做的事

  • NEVER use separate metallic/roughness/AO textures — Use ORM packing (1 RGB texture with Occlusion/Roughness/Metallic channels) to save texture slots and memory.
  • NEVER forget to enable normal_enabled — Normal maps don't work unless you set
    normal_enabled = true
    . Silent failure is common.
  • NEVER use TRANSPARENCY_ALPHA for cutout materials — Use TRANSPARENCY_ALPHA_SCISSOR or TRANSPARENCY_ALPHA_HASH instead. Full alpha blending is expensive and causes sorting issues.
  • NEVER set metallic = 0.5 — Materials are either metallic (1.0) or dielectric (0.0). Values between are physically incorrect except for rust/dirt transitions.
  • NEVER use emission without HDR — Emission values > 1.0 only work with HDR rendering enabled in Project Settings.

  • 绝对不要使用单独的金属度/粗糙度/环境光遮蔽纹理 — 使用ORM打包(将遮蔽/粗糙度/金属度通道整合到1张RGB纹理中)以节省纹理插槽和内存。
  • 绝对不要忘记启用normal_enabled — 除非设置
    normal_enabled = true
    ,否则法线贴图不会生效。这种静默失效很常见。
  • 绝对不要为镂空材质使用TRANSPARENCY_ALPHA — 改用TRANSPARENCY_ALPHA_SCISSOR或TRANSPARENCY_ALPHA_HASH。全alpha混合性能开销大,还会导致排序问题。
  • 绝对不要将metallic设为0.5 — 材质要么是金属(1.0)要么是绝缘体(0.0)。除了锈迹/污垢过渡的情况,中间值都不符合物理规律。
  • 绝对不要在未开启HDR的情况下使用自发光 — 只有在项目设置中启用HDR渲染后,自发光值>1.0才会生效。

Available Scripts

可用脚本

MANDATORY: Read the appropriate script before implementing the corresponding pattern.
必须:在实现对应方案前,请先阅读相应脚本。

material_fx.gd

material_fx.gd

Runtime material property animation for damage effects, dissolve, and texture swapping. Use for dynamic material state changes.
用于实现伤害效果、溶解、纹理切换的运行时材质属性动画。适用于动态材质状态变更场景。

pbr_material_builder.gd

pbr_material_builder.gd

Runtime PBR material creation with ORM textures and triplanar mapping.
支持ORM纹理和三平面映射的运行时PBR材质创建工具。

organic_material.gd

organic_material.gd

Subsurface scattering and rim lighting setup for organic surfaces (skin, leaves). Use for realistic character or vegetation materials.
为有机表面(皮肤、树叶)设置次表面散射和边缘光照。适用于创建逼真的角色或植被材质。

triplanar_world.gdshader

triplanar_world.gdshader

Triplanar projection shader for terrain without UV mapping. Blends textures based on surface normals. Use for cliffs, caves, or procedural terrain.

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

StandardMaterial3D Basics

StandardMaterial3D基础

PBR Texture Setup

PBR纹理设置

gdscript
undefined
gdscript
undefined

Create physically-based material

创建基于物理的材质

var mat := StandardMaterial3D.new()
var mat := StandardMaterial3D.new()

Albedo (base color)

反照率(基础颜色)

mat.albedo_texture = load("res://textures/wood_albedo.png") mat.albedo_color = Color.WHITE # Tint multiplier
mat.albedo_texture = load("res://textures/wood_albedo.png") mat.albedo_color = Color.WHITE # 色调乘数

Normal map (surface detail)

法线贴图(表面细节)

mat.normal_enabled = true # CRITICAL: Must enable first mat.normal_texture = load("res://textures/wood_normal.png") mat.normal_scale = 1.0 # Bump strength
mat.normal_enabled = true # 关键:必须先启用 mat.normal_texture = load("res://textures/wood_normal.png") mat.normal_scale = 1.0 # 凹凸强度

ORM Texture (R=Occlusion, G=Roughness, B=Metallic)

ORM纹理(R=遮蔽,G=粗糙度,B=金属度)

mat.orm_texture = load("res://textures/wood_orm.png")
mat.orm_texture = load("res://textures/wood_orm.png")

Alternative: Separate textures (less efficient)

替代方案:单独纹理(效率较低)

mat.roughness_texture = load("res://textures/wood_roughness.png")

mat.roughness_texture = load("res://textures/wood_roughness.png")

mat.metallic_texture = load("res://textures/wood_metallic.png")

mat.metallic_texture = load("res://textures/wood_metallic.png")

mat.ao_texture = load("res://textures/wood_ao.png")

mat.ao_texture = load("res://textures/wood_ao.png")

Apply to mesh

应用到网格

$MeshInstance3D.material_override = mat

---
$MeshInstance3D.material_override = mat

---

Metallic vs Roughness

金属度与粗糙度

Metal Workflow

金属工作流

gdscript
undefined
gdscript
undefined

Pure metal (steel, gold, copper)

纯金属(钢、金、铜)

mat.metallic = 1.0 mat.roughness = 0.2 # Polished metal mat.albedo_color = Color(0.8, 0.8, 0.8) # Metal tint
mat.metallic = 1.0 mat.roughness = 0.2 # 抛光金属 mat.albedo_color = Color(0.8, 0.8, 0.8) # 金属色调

Rough metal (iron, aluminum)

粗糙金属(铁、铝)

mat.metallic = 1.0 mat.roughness = 0.7
undefined
mat.metallic = 1.0 mat.roughness = 0.7
undefined

Dielectric Workflow

绝缘体工作流

gdscript
undefined
gdscript
undefined

Non-metal (wood, plastic, stone)

非金属(木材、塑料、石头)

mat.metallic = 0.0 mat.roughness = 0.6 # Typical for wood mat.albedo_color = Color(0.6, 0.4, 0.2) # Brown wood
mat.metallic = 0.0 mat.roughness = 0.6 # 木材的典型值 mat.albedo_color = Color(0.6, 0.4, 0.2) # 棕色木材

Glossy plastic

高光塑料

mat.metallic = 0.0 mat.roughness = 0.1 # Very smooth
undefined
mat.metallic = 0.0 mat.roughness = 0.1 # 非常光滑
undefined

Transition Materials (Rust/Dirt)

过渡材质(锈迹/污垢)

gdscript
undefined
gdscript
undefined

Use texture to blend metal/non-metal

使用纹理混合金属/非金属

mat.metallic_texture = load("res://rust_mask.png")
mat.metallic_texture = load("res://rust_mask.png")

White areas (1.0) = metal

白色区域(1.0)= 金属

Black areas (0.0) = rust (dielectric)

黑色区域(0.0)= 锈迹(绝缘体)


---

---

Transparency Modes

透明度模式

Decision Matrix

决策矩阵

ModeUse CasePerformanceSorting Issues
ALPHA_SCISSORFoliage, chain-link fenceFastNo
ALPHA_HASHDithered fade, LOD transitionsFastNoisy
ALPHAGlass, water, godot-particlesSlowYes (render order)
模式使用场景性能排序问题
ALPHA_SCISSORfoliage、铁丝网围栏
ALPHA_HASH抖动淡入淡出、LOD过渡有噪点
ALPHA玻璃、水、Godot粒子有(渲染顺序)

Alpha Scissor (Cutout)

Alpha Scissor(镂空)

gdscript
undefined
gdscript
undefined

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
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR mat.alpha_scissor_threshold = 0.5 # alpha值<0.5的像素会被丢弃 mat.albedo_texture = load("res://leaf.png") # 必须包含alpha通道

Enable backface culling for performance

启用背面剔除以提升性能

mat.cull_mode = BaseMaterial3D.CULL_BACK
undefined
mat.cull_mode = BaseMaterial3D.CULL_BACK
undefined

Alpha Hash (Dithered)

Alpha Hash(抖动)

gdscript
undefined
gdscript
undefined

For smooth fade-outs without sorting issues

适用于无排序问题的平滑淡出

mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH mat.alpha_hash_scale = 1.0 # Dither pattern scale
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH mat.alpha_hash_scale = 1.0 # 抖动图案缩放比例

Animate fade

动画淡入淡出

var tween := create_tween() tween.tween_property(mat, "albedo_color:a", 0.0, 1.0)
undefined
var tween := create_tween() tween.tween_property(mat, "albedo_color:a", 0.0, 1.0)
undefined

Alpha Blend (Full Transparency)

Alpha混合(全透明)

gdscript
undefined
gdscript
undefined

For glass, water (expensive)

适用于玻璃、水(性能开销大)

mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA mat.blend_mode = BaseMaterial3D.BLEND_MODE_MIX
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

---
mat.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_DISABLED mat.cull_mode = BaseMaterial3D.CULL_DISABLED # 显示两面

---

Advanced Features

高级特性

Emission (Glowing Materials)

自发光(发光材质)

gdscript
mat.emission_enabled = true
mat.emission = Color(1.0, 0.5, 0.0)  # Orange glow
mat.emission_energy_multiplier = 2.0  # Brightness (HDR)
mat.emission_texture = load("res://lava_emission.png")
gdscript
mat.emission_enabled = true
mat.emission = Color(1.0, 0.5, 0.0)  # 橙色发光
mat.emission_energy_multiplier = 2.0  # 亮度(HDR)
mat.emission_texture = load("res://lava_emission.png")

Animated emission

动画自发光

func _process(delta: float) -> void: mat.emission_energy_multiplier = 1.0 + sin(Time.get_ticks_msec() * 0.005) * 0.5
undefined
func _process(delta: float) -> void: mat.emission_energy_multiplier = 1.0 + sin(Time.get_ticks_msec() * 0.005) * 0.5
undefined

Rim Lighting (Fresnel)

边缘光照(菲涅尔)

gdscript
mat.rim_enabled = true
mat.rim = 1.0  # Intensity
mat.rim_tint = 0.5  # How much albedo affects rim color
gdscript
mat.rim_enabled = true
mat.rim = 1.0  # 强度
mat.rim_tint = 0.5  # 反照率对边缘颜色的影响程度

Clearcoat (Car Paint)

清漆(汽车漆面)

gdscript
mat.clearcoat_enabled = true
mat.clearcoat = 1.0  # Layer strength
mat.clearcoat_roughness = 0.1  # Glossy top layer
gdscript
mat.clearcoat_enabled = true
mat.clearcoat = 1.0  # 图层强度
mat.clearcoat_roughness = 0.1  # 高光顶层

Anisotropy (Brushed Metal)

各向异性(拉丝金属)

gdscript
mat.anisotropy_enabled = true
mat.anisotropy = 1.0  # Directional highlights
mat.anisotropy_flowmap = load("res://brushed_flow.png")

gdscript
mat.anisotropy_enabled = true
mat.anisotropy = 1.0  # 方向高光
mat.anisotropy_flowmap = load("res://brushed_flow.png")

Texture Channel Packing

纹理通道打包

ORM Texture (Recommended)

ORM纹理(推荐)

python
undefined
python
undefined

External tool (GIMP, Substance, Python script):

外部工具(GIMP、Substance、Python脚本):

Combine 3 grayscale textures into 1 RGB:

将3张灰度纹理合并为1张RGB纹理:

R channel = Ambient Occlusion (bright = no occlusion)

R通道 = 环境光遮蔽(越亮=无遮蔽)

G channel = Roughness (bright = rough)

G通道 = 粗糙度(越亮=越粗糙)

B channel = Metallic (bright = metal)

B通道 = 金属度(越亮=金属)


```gdscript

```gdscript

In Godot:

在Godot中:

mat.orm_texture = load("res://textures/material_orm.png")
mat.orm_texture = load("res://textures/material_orm.png")

This replaces ao_texture, roughness_texture, and metallic_texture!

这会替代ao_texture、roughness_texture和metallic_texture!

undefined
undefined

Custom Packing

自定义打包

gdscript
undefined
gdscript
undefined

If using custom channel assignments:

如果使用自定义通道分配:

mat.roughness_texture_channel = BaseMaterial3D.TEXTURE_CHANNEL_GREEN mat.metallic_texture_channel = BaseMaterial3D.TEXTURE_CHANNEL_BLUE

---
mat.roughness_texture_channel = BaseMaterial3D.TEXTURE_CHANNEL_GREEN mat.metallic_texture_channel = BaseMaterial3D.TEXTURE_CHANNEL_BLUE

---

Shader Conversion

着色器转换

When to Convert to ShaderMaterial

何时转换为ShaderMaterial

  • Need custom effects (dissolve, vertex displacement)
  • StandardMaterial3D limitations hit
  • Shader optimizations (remove unused features)
  • 需要自定义效果(溶解、顶点位移)
  • 达到StandardMaterial3D的限制
  • 着色器优化(移除未使用特性)

Conversion Workflow

转换工作流

gdscript
undefined
gdscript
undefined

1. Create StandardMaterial3D with all settings

1. 创建包含所有设置的StandardMaterial3D

var std_mat := StandardMaterial3D.new() std_mat.albedo_color = Color.RED std_mat.metallic = 1.0 std_mat.roughness = 0.2
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

2. 转换为ShaderMaterial

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

3. Transfer parameters manually

3. 手动传递参数

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)

---
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)

---

Material Variants (Godot 4.0+)

材质变体(Godot 4.0+)

Efficient Material Reuse

高效复用材质

gdscript
undefined
gdscript
undefined

Base material (shared)

基础材质(共享)

var base_red_metal := StandardMaterial3D.new() base_red_metal.albedo_color = Color.RED base_red_metal.metallic = 1.0
var base_red_metal := StandardMaterial3D.new() base_red_metal.albedo_color = Color.RED base_red_metal.metallic = 1.0

Variant 1: Rough

变体1:粗糙

var rough_variant := base_red_metal.duplicate() rough_variant.roughness = 0.8
var rough_variant := base_red_metal.duplicate() rough_variant.roughness = 0.8

Variant 2: Smooth

变体2:光滑

var smooth_variant := base_red_metal.duplicate() smooth_variant.roughness = 0.1
var smooth_variant := base_red_metal.duplicate() smooth_variant.roughness = 0.1

Note: Use resource_local_to_scene for per-instance tweaks

注意:使用resource_local_to_scene实现每个实例的微调


---

---

Performance Optimization

性能优化

Material Batching

材质批处理

gdscript
undefined
gdscript
undefined

✅ 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
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 # 所有墙会被批处理为单个绘制调用

❌ 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
undefined
func _ready() -> void: for wall in get_tree().get_nodes_in_group("stone_walls"): var mat := StandardMaterial3D.new() # 新材质! mat.albedo_color = Color(0.5, 0.5, 0.5) wall.material_override = mat # 每个墙都是单独的绘制调用
undefined

Texture Atlasing

纹理图集

gdscript
undefined
gdscript
undefined

Combine multiple materials into one texture atlas

将多个材质合并到一张纹理图集中

Then use UV offsets to select regions

然后使用UV偏移选择区域

material_atlas.gd

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)

---
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)

---

Edge Cases

边缘情况

Normal Maps Not Working

法线贴图不生效

gdscript
undefined
gdscript
undefined

Problem: Forgot to enable

问题:忘记启用

mat.normal_enabled = true # REQUIRED
mat.normal_enabled = true # 必须设置

Problem: Wrong texture import settings

问题:纹理导入设置错误

In Import tab: Texture → Normal Map = true

在导入标签页:纹理 → 法线贴图 = 开启

undefined
undefined

Texture Seams on Models

模型上的纹理接缝

gdscript
undefined
gdscript
undefined

Problem: Mipmaps causing seams

问题:Mipmap导致接缝

Solution: Disable mipmaps for tightly-packed UVs

解决方案:对紧密排列的UV禁用Mipmap

Import → Mipmaps → Generate = false

导入 → Mipmaps → 生成 = 关闭

undefined
undefined

Material Looks Flat

材质看起来很平

gdscript
undefined
gdscript
undefined

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")

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

---

Common Material Presets

常见材质预设

gdscript
undefined
gdscript
undefined

Glass

玻璃

func create_glass() -> StandardMaterial3D: var mat := StandardMaterial3D.new() mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA mat.albedo_color = Color(1, 1, 1, 0.2) mat.metallic = 0.0 mat.roughness = 0.0 mat.refraction_enabled = true mat.refraction_scale = 0.05 return mat
func create_glass() -> StandardMaterial3D: var mat := StandardMaterial3D.new() mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA mat.albedo_color = Color(1, 1, 1, 0.2) mat.metallic = 0.0 mat.roughness = 0.0 mat.refraction_enabled = true mat.refraction_scale = 0.05 return mat

Gold

黄金

func create_gold() -> StandardMaterial3D: var mat := StandardMaterial3D.new() mat.albedo_color = Color(1.0, 0.85, 0.3) mat.metallic = 1.0 mat.roughness = 0.3 return mat
undefined
func create_gold() -> StandardMaterial3D: var mat := StandardMaterial3D.new() mat.albedo_color = Color(1.0, 0.85, 0.3) mat.metallic = 1.0 mat.roughness = 0.3 return mat
undefined

Reference

参考

  • Master Skill: godot-master
  • 主技能:godot-master