Convertir un render de Blender en un generador: tu enlace se vuelve una ciudad 3D que, vista desde arriba, es un código QR que se escanea de verdad.

01
Todo empezó con un render en Blender: un QR extruido, cada módulo negro convertido en un edificio de altura distinta, iluminado como una maqueta de ciudad. Era bonito, pero era una imagen fija de un solo enlace.
Quería que cualquiera metiera su enlace y viera su propia ciudad girar en un turn-table, y que, sin dejar de ser bonita, siguiera siendo un QR real: que el teléfono la escaneara desde arriba. Una pieza jugable más del Laboratorio, como El Impostor o el Geocaching.
02
Un QR es funcional o no lo es: si al estilizarlo pierdes el contraste o deformas los módulos, deja de escanear y el juguete se rompe. La restricción era binaria: decodifica o no decodifica.
Y cuantos más caracteres tiene el enlace, más módulos necesita el QR: la ciudad se llena de edificios diminutos, fea e ilegible. Había que poner un límite honesto a la longitud del enlace en lugar de dejar que el usuario generara algo que no escanea.
03
Separé el generador del render, igual que el motor puro de El Lobo. Una función pura toma el enlace, calcula la matriz del QR (corrección de errores media, versión ≤4) y le asigna a cada módulo una altura determinista a partir de un hash del propio enlace: el mismo enlace da siempre la misma ciudad, y eso es testeable con un golden-master.
El render 3D vive en su isla WebGL (Three.js) y solo entra bajo demanda: una única malla instanciada y un shell de shader que pinta tejados planos y ventanas en los laterales. La cámara es ortográfica, no en perspectiva. Esa fue la decisión clave: sin fuga de perspectiva, la vista cenital es un QR plano y sin distorsión que el lector acepta.
04
El escaneo es el contrato, así que lo blindé con un test que decodifica de verdad: en cada estilo, la prueba captura el canvas cenital y lo pasa por un lector de QR; si la ciudad no escanea, el build falla. El límite de longitud del enlace no es decorativo: nace de mantener la versión del QR baja para que los edificios sean legibles.
Tres estilos, elegibles con círculos bicolor (mitad placa, mitad edificio): burdeos de marca, día pastel y una ciudad nocturna. El color se interpola sin reconstruir la geometría, y todos los estilos usan tokens del sistema de diseño con contraste WCAG suficiente para que el QR siga decodificando.
Respeto de accesibilidad: con prefers-reduced-motion la ciudad arranca ya en modo cenital estático, sin turn-table. El tap alterna girar / vista de escaneo desde el contenedor, no desde el raycast del 3D, para que funcione aunque la ciudad esté rotando.
05
Un generador que convierte cualquier enlace en una ciudad 3D que gira en un turn-table y, al tocarla, se endereza hasta una vista cenital que un teléfono escanea de verdad. Sin instalar nada, desde una sola URL.
La pieza vive en /laboratorio con la misma estética editorial y el mismo gate de calidad que el resto: typecheck, lint, tokens, build y un test de extremo a extremo que exige que el QR decodifique en los tres estilos.
QR real
un test decodifica la ciudad cenital en cada estilo o el build falla
06
La restricción dura fue la mejor guía de diseño: «tiene que escanear» decidió la cámara (ortográfica), el límite de longitud del enlace y hasta la paleta. Cuando el criterio de éxito es binario, conviene convertirlo en un test que rompe el build.
Separar el generador determinista del render me dio lo mismo que el motor puro de El Lobo: lógica testeable con golden-master y un 3D que solo se preocupa de pintar. Y aislar Three.js en una isla lazy mantiene el coste fuera de los bundles que comparte el resto de la web.
Ya que conoces un poco de cómo trabajo, cuéntame el tuyo: tratemos marca, producto y código como un solo sistema.
Hablemos de tu proyecto