Parte: 2 — Desarrollo 3D: motores, escenas y transformaciones · Fuente: Documentación oficial de Godot 4 — 3D rendering y Standard Material 3D ⏱️ Duración estimada: 55 min · Nivel: Intermedio
Entender qué es realmente una malla (los vértices, caras, normales y coordenadas UV que forman la superficie de un objeto) y cómo MeshInstance3D la dibuja en la escena con un material. Aprenderás a crear mallas primitivas por código, a asignarles un StandardMaterial3D y a controlar el aspecto físico de cada superficie con propiedades como albedo, metallic, roughness y emission.
El resultado es la capacidad de dar personalidad visual a tus objetos: distinguir un metal pulido de un plástico mate o de una superficie que brilla con luz propia, y cambiar esas propiedades en tiempo de ejecución.
Al finalizar, el alumno podrá:
MeshInstance3D.BoxMesh, SphereMesh) y asignarlas a instancias.StandardMaterial3D con albedo, metallic, roughness y emission.material_override.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Qué es una malla | Es la unidad de geometría; sin ella no hay nada que dibujar. |
| 2 | Vértices, caras, normales, UV | Definen forma, orientación de superficie e iluminación y texturizado. |
| 3 | MeshInstance3D | El nodo que instancia y renderiza una malla en la escena. |
| 4 | Mallas primitivas | Prototipar rápido sin modelar en Blender. |
| 5 | StandardMaterial3D | El material PBR estándar que da aspecto físico creíble. |
| 6 | Albedo, metallic, roughness, emission | Controlan color, reflejo metálico, rugosidad y luz propia. |
| 7 | material_override vs surface | Dos formas de asignar material con distinto alcance. |
Trabaja en Godot 4.x. Las referencias clave son la clase StandardMaterial3D en https://docs.godotengine.org/en/stable/classes/class_standardmaterial3d.html, la clase MeshInstance3D en https://docs.godotengine.org/en/stable/classes/class_meshinstance3d.html y la guía de materiales espaciales en https://docs.godotengine.org/en/stable/tutorials/3d/standard_material_3d.html. Para entender mallas primitivas revisa https://docs.godotengine.org/en/stable/classes/class_primitivemesh.html. Crea un proyecto 3D nuevo con iluminación básica.
Generaremos tres objetos por código, cada uno con un material distinto (metal, plástico y emisivo), y animaremos una propiedad en runtime.
Crea una escena con Node3D raíz Materiales, una Camera3D, una DirectionalLight3D y un WorldEnvironment con un cielo simple para que los metales tengan algo que reflejar.
Adjunta este script al nodo raíz. Crea tres MeshInstance3D por código, cada una con su malla y material:
extends Node3D
var emisivo_mat: StandardMaterial3D
var pulso: float = 0.0
func _ready() -> void:
# --- Objeto 1: esfera metálica pulida ---
var metal := MeshInstance3D.new()
metal.mesh = SphereMesh.new()
var mat_metal := StandardMaterial3D.new()
mat_metal.albedo_color = Color(0.8, 0.8, 0.85)
mat_metal.metallic = 1.0
mat_metal.roughness = 0.1 # bajo = pulido y reflectante
metal.material_override = mat_metal
metal.position = Vector3(-2.5, 0, 0)
add_child(metal)
# --- Objeto 2: cubo de plástico mate ---
var plastico := MeshInstance3D.new()
plastico.mesh = BoxMesh.new()
var mat_plastico := StandardMaterial3D.new()
mat_plastico.albedo_color = Color(0.9, 0.2, 0.2)
mat_plastico.metallic = 0.0
mat_plastico.roughness = 0.8 # alto = mate, sin reflejos nítidos
plastico.material_override = mat_plastico
plastico.position = Vector3(0, 0, 0)
add_child(plastico)
# --- Objeto 3: esfera emisiva (brilla con luz propia) ---
var emisivo := MeshInstance3D.new()
emisivo.mesh = SphereMesh.new()
emisivo_mat = StandardMaterial3D.new()
emisivo_mat.albedo_color = Color(0.1, 0.1, 0.1)
emisivo_mat.emission_enabled = true
emisivo_mat.emission = Color(0.1, 0.6, 1.0)
emisivo_mat.emission_energy_multiplier = 2.0
emisivo.material_override = emisivo_mat
emisivo.position = Vector3(2.5, 0, 0)
add_child(emisivo)
func _process(delta: float) -> void:
# Animamos la intensidad de emisión en runtime: un latido.
pulso += delta * 2.0
var energia := 1.5 + 1.5 * abs(sin(pulso))
emisivo_mat.emission_energy_multiplier = energia
Ajusta la Camera3D para ver los tres objetos en fila (por ejemplo position = Vector3(0, 1.5, 6) y un look_at al origen). Ejecuta con F6.
Observa las diferencias: la esfera de la izquierda refleja el entorno como un metal pulido; el cubo rojo se ve mate y difuso; la esfera de la derecha late con luz azul propia, iluminando incluso sin recibir la luz direccional.
Experimenta en caliente: sube roughness del metal a 0.6 y verás cómo pierde nitidez en los reflejos. Baja la emission_energy_multiplier base y el latido se hará más sutil.
metallic = 0.5 y roughness = 0.3 y describe dónde queda entre metal y plástico.albedo_color del plástico por código cada segundo usando un temporizador o Engine.get_physics_frames().transparency = BaseMaterial3D.TRANSPARENCY_ALPHA y un alpha < 1 en el albedo) en una esfera y observa el efecto.StandardMaterial3D a dos instancias y confirma que cambiarlo afecta a ambas.material_override por asignar el material a la superficie 0 con set_surface_override_material(0, mat) y comenta la diferencia.roughness del metal entre 0.05 y 0.9 con una función seno y describe el resultado visual.Construye una "vitrina de materiales" con al menos cinco esferas idénticas en fila, cada una con un StandardMaterial3D que varíe progresivamente el metallic de 0.0 a 1.0 (0, 0.25, 0.5, 0.75, 1.0), todas generadas por código. Criterio de aceptación: al ejecutar se aprecia una transición clara de aspecto plástico a metálico a lo largo de la fila, cada material es un recurso independiente, y la escena incluye iluminación y un WorldEnvironment con cielo para que los reflejos metálicos sean visibles.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| El metal se ve negro y sin reflejos | No hay WorldEnvironment con cielo que reflejar. Añade un Environment con sky. |
| Todos los objetos comparten el mismo material sin querer | Reutilizaste la misma instancia de material. Crea un StandardMaterial3D.new() por objeto. |
| La emisión no se ve | Olvidaste emission_enabled = true o la energía es 0. Actívala y sube emission_energy_multiplier. |
| El objeto se ve plano y sin sombreado | La malla no tiene normales correctas o falta luz. Usa mallas primitivas y añade una DirectionalLight3D. |
Cambiar material_override no afecta nada |
Estás modificando otro material (el de superficie). material_override tiene prioridad; edita el mismo recurso que asignaste. |
❓ ¿Cuál es la diferencia entre material_override y el material de superficie? El de superficie se define por cada superficie de la malla; material_override reemplaza a todos ellos en esa instancia sin alterar el recurso malla. Úsalo para cambios rápidos por instancia.
❓ ¿Qué significan metallic y roughness juntos? metallic indica cuánto se comporta la superficie como metal (refleja el entorno); roughness indica cuán difusos son esos reflejos. Metal bajo + roughness alto = plástico mate; metal alto + roughness bajo = espejo.
❓ ¿La emisión ilumina otros objetos? El material emisivo brilla por sí mismo, pero no ilumina la escena como una luz real salvo que uses técnicas adicionales (como GI). Para iluminar de verdad usa un nodo de luz.
❓ ¿Puedo reutilizar una malla entre muchas instancias? Sí, y es recomendable. La malla es un recurso; varias MeshInstance3D pueden compartir la misma geometría con distinta posición y material.
Clase 048 - Sistemas de coordenadas 3D y Transform3D (basis y origin)
Clase 050 - Importar modelos 3D: glTF, Blender y el pipeline