Saltar al contenido

El mapa de decisiones técnicas del track completo

Los árboles de decisión que resumen cincuenta y dos niveles: qué geometría, qué material, qué shading, qué renderer y qué entrega, con el criterio explícito de cada bifurcación.

Primero: qué limita tu escena

Ninguna decisión posterior tiene sentido sin esta. Todas las técnicas de optimización atacan un recurso concreto, y aplicarlas cuando el cuello está en otro es trabajo perdido con degradación visual gratuita.

Las dos pruebas de la izquierda cuestan un minuto y descartan tres cuartas partes de las hipótesis. Bajar la resolución cambia el número de fragmentos sin tocar nada más; renderizar una escena vacía elimina todo el trabajo de render y deja solo tu lógica. Entre las dos acotan el problema antes de perfilar nada.

El detalle que más gente se salta: la respuesta cambia entre dispositivos. La misma escena puede estar limitada por CPU en un escritorio con gráfica potente y por relleno en un móvil con pantalla de alta densidad. Las decisiones de esta lección hay que tomarlas para el dispositivo objetivo, no para el de desarrollo.

Geometría y objetos

La pregunta que resuelve este árbol no es “cuál es más rápido” sino “qué necesito que varíe entre objetos”. Todo lo demás sale de ahí, y se desarrolla en fusionar o instanciar.

El nodo rojo es el que más veces se salta y el que más veces bloquea todo lo demás: si los objetos tienen materiales distintos, ninguna técnica de agrupación se aplica. El trabajo previo es unificar materiales, y de ahí que el atlas y los texture arrays aparezcan en el camino y no como una optimización aparte.

mergeGeometries está en amarillo porque su ventaja viene con una pérdida seria: multiplica la memoria por el número de copias y elimina el culling individual. Es correcto para grupos estáticos y compactos, y una mala idea para cualquier cosa repartida por un mundo grande.

Sobre el detalle de la malla, la regla que resume el nivel de mundos grandes: si un objeto puede ocupar menos de cincuenta píxeles de altura en pantalla, necesita un nivel de detalle. Por debajo de eso, los triángulos son subpíxel y el hardware los procesa en cuadrados de dos por dos, desperdiciando tres cuartas partes del trabajo.

Material, luz y shading

Aquí hay dos decisiones encadenadas: qué modelo de iluminación necesitas y cuánto control quieres sobre el código.

Tres criterios explícitos que cierran las bifurcaciones dudosas.

Entorno frente a luces. Un buen mapa de entorno con PMREMGenerator mejora más el aspecto de una escena PBR que añadir cuatro luces, y cuesta menos: una luz dinámica añade código al shader de todos los materiales afectados y una luz con sombra añade además una pasada de geometría. La secuencia correcta es entorno primero, y luego las mínimas luces que hagan falta para dar dirección.

Cuándo MeshPhysicalMaterial. Está en rojo porque cada capa que activas tiene un coste real y transmission en particular obliga a dibujar la escena una segunda vez sobre un render target aparte. Esa pasada es una sola por fotograma y la comparten todos los objetos transmisivos, así que lo caro es el primer cristal y no el décimo. Es el material correcto para el cristal, el barniz de un coche o una tela con brillo direccional, y es un desperdicio para todo lo demás.

TSL frente a GLSL. Si la escena va a vivir solo en WebGLRenderer y el shader es corto, GLSL directo es más rápido de escribir y de depurar. Si hay alguna posibilidad de migrar a WebGPURenderer, TSL compila el mismo grafo a GLSL y a WGSL, y esa portabilidad se paga sola en cuanto la migración deja de ser hipotética.

Sobre sombras, la tabla que resume las decisiones del nivel correspondiente:

Situación Solución Coste
Todo estático Lightmap horneado Cero en tiempo real
Un objeto móvil sobre suelo plano Sombra de contacto o textura proyectada Muy bajo
Pocos objetos móviles, escena pequeña Un shadow map de 1024 con PCF Medio
Escena grande al aire libre Cascadas de shadow maps Alto
Móvil o visor XR Horneado más una sombra dinámica Presupuesto obliga

Renderer, entrega y carga

La última decisión encadenada: con qué se dibuja, en qué formato llegan los recursos y cuándo.

WebGPURenderer cae automáticamente a WebGL cuando no hay WebGPU, así que elegirlo no excluye a nadie: lo que cambia es que las funcionalidades exclusivas de WebGPU, como el compute, no estarán disponibles en el camino de reserva y tu código tiene que contemplarlo.

El criterio para Draco frente a Meshopt merece explicitarse porque casi nunca se explica. Draco comprime más, sobre todo en mallas densas, pero descomprime más despacio y necesita un decodificador de un tamaño considerable. Meshopt comprime algo menos y descomprime muy rápido, con un decodificador pequeño. Para un modelo grande que se carga una vez, Draco. Para muchos modelos pequeños que se cargan durante la sesión, Meshopt. Y para geometría que además se cuantiza, Meshopt encaja mejor porque están pensados juntos.

compileAsync al final del árbol no es opcional: sin él, el parón de compilación ocurre en el momento en que el objeto entra en cámara, que es el peor momento posible.

Y la lista final, la que se consulta antes de dar por terminada una experiencia. Cada línea corresponde a un nivel entero del track, y ninguna se puede responder con una opinión.

El cuello está identificado con una medición, no con una intuición. El número de programas de shader es el que esperabas. renderer.info vuelve a sus valores iniciales tras montar y desmontar veinte veces. La escena arranca en menos de tres segundos en el dispositivo objetivo. Existe una alternativa sin WebGL y es contenido real, no una disculpa. La escena se opera entera con teclado. prefers-reduced-motion cambia el comportamiento y no lo congela. El presupuesto de memoria de vídeo se verifica en la construcción. Y hay un límite de tiempo en cada descarga, con su camino de degradación.

Ocho comprobaciones. Una experiencia que las pasa todas está por delante de la inmensa mayoría de lo que se publica.