Basic, Lambert y Phong: los materiales anteriores al PBR
Los tres modelos de iluminación no físicos que Three.js sigue manteniendo, qué aproximación hace cada uno y en qué casos concretos siguen siendo la elección correcta.
Antes de que el renderizado basado en física se volviera el estándar, los motores usaban modelos de iluminación empíricos: fórmulas que no describen lo que hace la luz, sino que producen algo que se le parece con poco cálculo. Three.js conserva tres de ellos, y no por nostalgia: siguen siendo la respuesta correcta cuando el presupuesto de fragment shader es ajustado o cuando el aspecto que buscas no es realista.
- Describir el modelo de iluminación exacto de
MeshBasicMaterial,MeshLambertMaterialyMeshPhongMaterial. - Identificar qué propiedades tiene cada uno y cuáles no, y por qué.
- Reconocer los artefactos visuales característicos de cada aproximación.
- Justificar la elección de un material no físico con un argumento que no sea la costumbre.
Basic: ningún modelo de iluminación
MeshBasicMaterial no consulta ninguna luz de la escena. Su color de salida es el producto de color por map, opcionalmente modulado por lightMap, aoMap, specularMap y un envMap combinado según combine. Eso es todo. Añadir un DirectionalLight a la escena no cambia ni un píxel de un objeto con este material, lo cual es la fuente de la pregunta más repetida en todos los foros de Three.js.
Que no reaccione a la luz es exactamente lo que lo hace útil. Es el material correcto para tres cosas: interfaz dentro de la escena, geometría de depuración, y superficies cuya iluminación ya está horneada en la textura. También es el único que no necesita normales, así que una geometría sin atributo normal se dibuja perfectamente con él y con nada más.
Fíjate en un detalle revelador: MeshBasicMaterial no tiene flatShading. No es un olvido; es que flatShading recalcula la normal por cara y aquí no hay normal que recalcular. Cuando un material no tiene una propiedad, casi siempre es porque su modelo no la puede usar.
Lambert: solo difuso, y por fragmento
MeshLambertMaterial implementa reflectancia lambertiana: la luz que refleja un punto de la superficie es proporcional al coseno del ángulo entre la normal y la dirección de la luz, y no depende de dónde esté el observador. Es la definición de una superficie perfectamente mate. Madera sin tratar, yeso, papel, piedra sin pulir.
Como no hay término especular, no hay brillo. Puedes poner una luz muy intensa apuntando a una esfera Lambert y no aparecerá ningún punto brillante, solo un degradado. Si tu superficie necesita brillo, este no es el material.
Durante años, MeshLambertMaterial calculaba la iluminación en el vertex shader y la interpolaba entre vértices, el clásico sombreado de Gouraud. Ese es el origen de la mala fama del material: en una esfera de pocos segmentos, la interpolación producía bandas visibles y el punto más iluminado se movía a saltos de vértice en vértice. Eso ya no es así. La documentación de r184 dice explícitamente que MeshLambertMaterial usa sombreado por fragmento, igual que Phong y Standard. La iluminación se evalúa por píxel, la geometría de pocos polígonos ya no produce bandas, y la única diferencia real que queda con Phong es la ausencia del término especular. Si has leído lo contrario en un tutorial, el tutorial es viejo.
Lambert conserva la vía antigua de mapa de entorno: envMap combinado con combine, reflectivity y refractionRatio. Ese refractionRatio es un pseudo-refractivo que consiste en muestrear el cubemap con el vector refractado; no es transmisión real, no ve la geometría que hay detrás y no tiene nada que ver con el transmission de MeshPhysicalMaterial. Sirve para simular cristal barato en escenas donde nadie va a mirar de cerca.
Phong: el especular de Blinn
MeshPhongMaterial añade al término difuso un lóbulo especular calculado con el modelo de Blinn-Phong, que es la variante de Phong que usa el vector medio entre la dirección de la luz y la de la vista en lugar del vector reflejado. Es más barato y produce brillos ligeramente más anchos en incidencia rasante, lo que resulta que se parece más a la realidad que el Phong original.
Dos propiedades lo controlan. specular es un color, por defecto 0x111111, un gris muy oscuro: es el color e intensidad del brillo. shininess es el exponente, por defecto 30: cuanto más alto, más pequeño y concentrado el punto brillante.
import * as THREE from 'three';
const scene = new THREE.Scene();
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const foco = new THREE.DirectionalLight(0xffffff, 2.5);
foco.position.set(3, 4, 5);
scene.add(foco);
const geometria = new THREE.SphereGeometry(0.8, 48, 24);
const materiales = [
new THREE.MeshBasicMaterial({ color: 0x89b4fa }),
new THREE.MeshLambertMaterial({ color: 0x89b4fa }),
new THREE.MeshPhongMaterial({
color: 0x89b4fa,
specular: 0x555555,
shininess: 60
}),
new THREE.MeshPhongMaterial({
color: 0x89b4fa,
specular: 0xffffff,
shininess: 400 // brillo diminuto: plastico muy pulido
})
];
materiales.forEach((material, i) => {
const esfera = new THREE.Mesh(geometria, material);
esfera.position.x = (i - 1.5) * 2;
scene.add(esfera);
});
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const camera = new THREE.PerspectiveCamera(
45, window.innerWidth / window.innerHeight, 0.1, 100
);
camera.position.z = 8;
renderer.setAnimationLoop(() => renderer.render(scene, camera));
La primera esfera se ve como un círculo plano de color, sin ninguna pista de volumen. La segunda tiene volumen pero parece de yeso. La tercera parece plástico. La cuarta parece plástico muy pulido. Ese salto de la segunda a la tercera es la aportación entera del término especular, y explica por qué durante veinte años todo el 3D en tiempo real parecía de plástico: el modelo de Blinn-Phong describe bien exactamente un material, el plástico, y aproxima mal todos los demás.
En Blinn-Phong, el término difuso y el especular se suman sin ninguna restricción: un material con color blanco y specular blanco puede reflejar más luz de la que recibe, algo físicamente imposible. Ese exceso es la razón por la que las escenas Phong “brillan” de una forma característica que se reconoce a diez metros. La compensación que aprendió a hacer todo el mundo era mantener specular muy oscuro, y por eso el valor por defecto de Three.js es 0x111111 y no un gris medio. En un material PBR ese equilibrio no lo mantienes tú: lo impone la BRDF, que reparte la energía entre reflexión especular y difusa según el Fresnel. Es la diferencia conceptual entre los dos mundos, y es de donde sale todo lo demás.
Cuándo siguen valiendo
El argumento a favor de estos tres materiales en 2026 no es estético, es de presupuesto. En un dispositivo móvil de gama baja con una escena de muchos objetos, el fragment shader de Standard con muestreo de entorno prefiltrado cuesta varias veces lo que cuesta Lambert. Si tu escena es un mapa isométrico con doscientos edificios sin brillo, Lambert produce un resultado indistinguible a una fracción del coste.
El otro argumento es el estilístico. Un aspecto deliberadamente retro, un diagrama técnico, una visualización de datos donde el realismo estorba: Basic y Lambert no intentan parecer nada, y eso a veces es justo lo que quieres.
Lo que no es un argumento válido es “no tengo tiempo de configurar el PBR”. Un MeshStandardMaterial con roughness y metalness bien puestos y un mapa de entorno cualquiera se configura en tres líneas y se ve mejor que cualquier Phong ajustado durante una hora. Si eliges Phong, que sea por el presupuesto o por el estilo.