Elegir material: el árbol de decisión y la tabla de coste
Cinco preguntas en orden que resuelven qué material usar, con el coste relativo de cada uno y los tres casos en los que la respuesta obvia es la equivocada.
Con el catálogo entero visto, la elección deja de ser una cuestión de gusto y pasa a ser un árbol corto. Las preguntas no valen lo mismo: la primera descarta la mitad del catálogo y la última rara vez llega a hacerse. Lo que sigue es esa secuencia, el coste que estás aceptando en cada hoja del árbol, y los casos donde la respuesta que parece obvia sale cara.
- Aplicar en orden las preguntas que determinan el material correcto.
- Estimar el coste relativo por fragmento de cada opción.
- Reconocer las tres situaciones en las que el material más simple gana al más completo.
- Compartir instancias de material entre mallas sin romper nada.
El árbol
flowchart TB
A[Necesito un material para una superficie] --> B{Debe reaccionar a las luces de la escena}
B -->|No| C{Quiero volumen sin luces}
C -->|Si| MC[MeshMatcapMaterial]
C -->|No| MB[MeshBasicMaterial]
B -->|Si| D{Busco realismo fisico}
D -->|No| E{Quiero bandas de color plano}
E -->|Si| MT[MeshToonMaterial]
E -->|No| F{Necesita brillo especular}
F -->|Si| MP[MeshPhongMaterial]
F -->|No| ML[MeshLambertMaterial]
D -->|Si| G{La superficie tiene dos capas}
G -->|No| MS[MeshStandardMaterial]
G -->|Si| MF[MeshPhysicalMaterial]
style A fill:#cba6f7,color:#11111b
style MB fill:#a6e3a1,color:#11111b
style MC fill:#a6e3a1,color:#11111b
style ML fill:#94e2d5,color:#11111b
style MT fill:#94e2d5,color:#11111b
style MP fill:#f9e2af,color:#11111b
style MS fill:#89b4fa,color:#11111b
style MF fill:#fab387,color:#11111bLa primera pregunta descarta más de lo que parece. Interfaz dentro de la escena, geometría de depuración, iluminación horneada en la textura, esquemas y diagramas: todo eso no necesita luces, y usar un material que las consulte es pagar por nada.
La tercera pregunta, la de “realismo físico”, tiene una trampa. No pregunta si tu escena debe parecer real, pregunta si quieres que el material se comporte correctamente bajo cualquier iluminación. Un estilo ilustrado puede necesitar perfectamente un MeshStandardMaterial con colores planos, porque lo que quieres del PBR no es el fotorrealismo sino que la superficie reaccione de forma coherente cuando el usuario mueva la cámara.
La última pregunta, la de las dos capas, es la más operativa de todas. Pintura más barniz, jabón más aire, fibra más pelusa, líquido más recipiente, metal más óxido: si tu material se describe con dos superficies apiladas, es un MeshPhysicalMaterial. Si se describe con una, MeshStandardMaterial te basta y te ahorras el coste.
El coste, en órdenes de magnitud
Los números exactos dependen de la GPU, del número de luces y de cuántas texturas tenga el material, pero la proporción se mantiene notablemente estable entre dispositivos:
| material | coste relativo | qué lo domina |
|---|---|---|
MeshBasicMaterial |
1 | una lectura de textura |
MeshMatcapMaterial |
1 | una lectura de textura |
MeshLambertMaterial |
2 | un producto escalar por luz |
MeshToonMaterial |
2 | lo anterior más una consulta al gradiente |
MeshPhongMaterial |
3 | un lóbulo especular por luz |
MeshStandardMaterial |
6 | BRDF de microfacetas más entorno prefiltrado |
MeshPhysicalMaterial sin capas |
6 | igual que Standard |
con clearcoat |
8 | un lóbulo y una normal más |
con transmission |
15 o más | obliga a redibujar la escena a un render target |
La fila que importa es la última. transmission no es una capa más: cuando hay al menos un material con transmisión en la escena, el renderer tiene que dibujar todo lo demás a una textura auxiliar para que el objeto transmisivo pueda muestrear lo que hay detrás de él. Estás dibujando la escena dos veces. Con un objeto de cristal en primer plano puede merecer la pena; con quince botellas en una estantería, casi nunca.
Tres casos donde el material simple gana
Las etiquetas y los marcadores. Cualquier cosa que sea información sobre la escena y no parte de la escena debe ser MeshBasicMaterial. Un marcador con MeshStandardMaterial se oscurece cuando queda en sombra, que es justo lo que no quieres de un marcador.
El fondo y el atrezo lejano. Un objeto que ocupa treinta píxeles en pantalla no muestra ninguna diferencia entre Lambert y Standard, y si tienes cien de esos, la diferencia de coste sí se nota. Es la aplicación natural del nivel de detalle: geometría más simple y material más simple a partir de cierta distancia.
El visor de modelos. Un matcap bien elegido produce un resultado más legible que un PBR con un entorno mediocre, cuesta una fracción, y no depende de que hayas cargado un HDRI de varios megabytes. Es la razón por la que los visores profesionales de modelos lo ofrecen como modo por defecto.
Cada instancia de material distinta es una entrada distinta en la caché de programas y, sobre todo, un cambio de estado más en el bucle de dibujado. Three.js ordena la lista de opacos agrupando por programa y por material precisamente para minimizar esos cambios, así que mil mallas que comparten la misma instancia de MeshStandardMaterial se dibujan mucho más rápido que mil mallas con mil materiales idénticos pero distintos. La trampa es que compartir instancia significa compartirla de verdad: cambiar material.color afecta a las mil mallas. Si necesitas colores distintos con el mismo material, la respuesta no es clonar el material, es activar vertexColors y meter el color en un atributo de la geometría, o usar InstancedMesh con setColorAt. Un material.clone() por objeto es el patrón que más silenciosamente destroza el rendimiento de una escena grande, porque no se nota hasta que hay cientos.
Con la elección hecha, lo que queda es parametrizar bien el material que has elegido. Si has llegado a MeshStandardMaterial o a MeshPhysicalMaterial, esa parametrización no es cuestión de mover deslizadores hasta que quede bonito: hay un modelo físico detrás que dice qué valores son posibles y cuáles no, y es lo que viene a continuación.