Parte: 4 — Gráficos, shaders y rendering moderno · Fuente: Godot Engine 4.x — Standard Material 3D y Spatial shaders ⏱️ Duración estimada: 65 min · Nivel: Avanzado
Entender qué es el renderizado basado en física (PBR) y el flujo metallic/roughness que usa Godot 4. Aprenderás qué representa cada canal (albedo, metallic, roughness, normal, AO), por qué un material metálico se comporta distinto a uno dieléctrico y cómo la conservación de energía evita que las superficies "brillen más de lo que reciben". Lo montarás dos veces: con un StandardMaterial3D de mapas y con un shader spatial que escribe ALBEDO, METALLIC y ROUGHNESS a mano.
Al finalizar, el alumno podrá:
StandardMaterial3D PBR asignando mapas a cada canal.METALLIC, ROUGHNESS y ALBEDO por parámetro.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Qué es PBR | Materiales consistentes bajo cualquier luz |
| 2 | Flujo metallic/roughness | Estándar de la industria y de Godot |
| 3 | Canal albedo | Color base sin luz ni sombras horneadas |
| 4 | Metallic y dieléctricos | Define si refleja el entorno o difunde color |
| 5 | Roughness | Controla lo pulido o áspero de la superficie |
| 6 | Normal y AO | Detalle y oclusión sin geometría extra |
| 7 | Conservación de energía | Evita materiales físicamente imposibles |
ALBEDO, texturizado con source_color.NORMAL_MAP con hint_normal.Usa Godot 4.x, proyecto 3D. Prepara una escena con un Node3D, dos MeshInstance3D con esferas (una para metal, otra para dieléctrico), un DirectionalLight3D y una WorldEnvironment con un cielo procedural: el reflejo del entorno es lo que hace lucir al metal. Puedes usar texturas PBR propias o colores planos. Consulta el Standard Material 3D y la sección de PBR de los Spatial shaders. Lo observable: dos esferas idénticas de forma pero con comportamiento de luz radicalmente distinto.
Primero con material estándar, luego con shader propio, para ver que ambos escriben los mismos canales.
Paso 1 — Un StandardMaterial3D PBR. Selecciona la primera esfera, crea un StandardMaterial3D y ajusta:
# Vía código (o hazlo en el inspector):
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.9, 0.75, 0.4) # oro
mat.metallic = 1.0
mat.roughness = 0.25
$EsferaMetal.material_override = mat
Si tienes mapas, arrástralos a Albedo, Metallic, Roughness, Normal Map y AO en el inspector, y activa cada canal.
Paso 2 — La segunda esfera, dieléctrica. Repite con metallic 0 para comparar:
var plastico := StandardMaterial3D.new()
plastico.albedo_color = Color(0.1, 0.4, 0.9) # plástico azul
plastico.metallic = 0.0
plastico.roughness = 0.4
$EsferaPlastico.material_override = plastico
Ejecuta (F6): el oro refleja el cielo y apenas tiene color propio difuso; el plástico muestra su azul con un brillo pequeño y claro. Esa es la diferencia metal/dieléctrico.
Paso 3 — Un shader spatial que escribe los canales PBR. Crea un ShaderMaterial en una tercera esfera:
shader_type spatial;
uniform vec4 color_albedo : source_color = vec4(0.9, 0.75, 0.4, 1.0);
uniform float metallic_param : hint_range(0.0, 1.0) = 1.0;
uniform float roughness_param : hint_range(0.0, 1.0) = 0.25;
uniform sampler2D normal_tex : hint_normal;
uniform sampler2D ao_tex : hint_default_white;
void fragment() {
ALBEDO = color_albedo.rgb;
METALLIC = metallic_param;
ROUGHNESS = roughness_param;
NORMAL_MAP = texture(normal_tex, UV).rgb; // relieve por textura
AO = texture(ao_tex, UV).r; // oclusión ambiental
}
Paso 4 — Barrer roughness desde GDScript. Anima el pulido para ver el efecto:
func _process(delta: float) -> void:
var r: float = (sin(Time.get_ticks_msec() * 0.001) * 0.5) + 0.5
$EsferaShader.get_active_material(0).set_shader_parameter("roughness_param", r)
Verás el reflejo pasar de espejo nítido (roughness 0) a un brillo difuso y amplio (roughness 1). Cambia metallic_param entre 0 y 1 y observa cómo el color propio aparece o desaparece.
metallic_param en el inspector y crea tres presets: oro, plástico y goma mate.Construye una fila de cinco esferas con el mismo shader, variando roughness_param de 0.0 a 1.0 en pasos iguales, todas metálicas, bajo un entorno con cielo. Añade una sexta esfera dieléctrica del mismo color para contraste.
Criterio de aceptación: la fila metálica muestra una transición clara de reflejo especular nítido (izquierda) a difuso (derecha); la esfera dieléctrica exhibe color difuso propio y un brillo pequeño, evidenciando la diferencia metallic/dieléctrico bajo la misma luz.
| Síntoma | Causa y arreglo |
|---|---|
| El metal se ve negro y sin reflejo | No hay entorno/cielo que reflejar; añade una WorldEnvironment con sky |
| El normal map se ve invertido o plano | Textura sin hint_normal o sin marcar como Normal Map al importar; corrígelo |
| El albedo trae sombras "pintadas" | Usaste una textura con luz horneada; el albedo debe ser color plano |
| Metallic a 0.5 se ve raro | Los valores intermedios casi no existen en la realidad; usa 0 o 1 salvo transiciones |
| El AO oscurece todo por igual | Estás multiplicándolo sobre la luz directa; el AO solo afecta al ambient |
¿PBR es más lento? Marginalmente; Godot lo tiene optimizado. La ganancia en consistencia visual compensa de sobra.
¿Qué es "conservación de energía" en la práctica? Que no puedes tener a la vez difuso fuerte y especular fuerte sin límite; la BRDF reparte la energía. Godot lo gestiona internamente.
¿Metallic/roughness o specular/glossiness? Godot usa metallic/roughness, el estándar más común y con menos parámetros que ajustar mal.
¿Necesito siempre normal y AO? No. Un color, metallic y roughness ya dan un material creíble; los mapas añaden detalle cuando lo necesitas.
Clase 092 - Iluminación en shaders: Lambert, Phong y especular