LOG 03 · TÉCNICA

Renderizado Híbrido CSS3D + WebGL

Contenido DOM real y accesible colocado dentro de una escena WebGL 3D genuina usando el CSS3DRenderer de Three.js — el texto sigue siendo seleccionable y rastreable incluso mientras orbita en el espacio 3D.

¿Por qué no renderizar el texto directamente en WebGL?

Hornear la interfaz en un canvas WebGL (como textura, o mediante una librería de mallas de texto) permite colocarla rápidamente en el espacio 3D, pero deja de ser contenido real — sin selección de texto, sin búsqueda en la página, nada que un lector de pantalla o un rastreador de búsqueda pueda leer. El CSS3DRenderer de Three.js resuelve esto al revés: elementos DOM reales se posicionan y rotan en verdadero 3D, transformados mediante CSS matrix3d, mientras un segundo renderizador WebGL ordinario dibuja la escena detrás de ellos — ambos guiados por la misma cámara, de modo que la perspectiva coincide exactamente entre las dos capas.

En este sitio, cada sección de la página de inicio es un componente React real, montado mediante portal en un div que CSS3DRenderer coloca en una trayectoria helicoidal alrededor del globo. El scroll o el swipe impulsan un tween de GSAP de la cámara compartida; CSS3DRenderer y el renderizador WebGL redibujan a partir del mismo estado de cámara en cada fotograma, de modo que el contenido DOM y el globo 3D se mantienen en perfecta sincronía como si ocuparan una sola escena.

La trampa del contexto de apilamiento

El punto delicado de esta técnica: `perspective`, `transform` y `filter` en cualquier elemento ancestro crean un nuevo contexto de apilamiento CSS — y se convierten en el bloque contenedor para los descendientes con `position:fixed`. Un canvas WebGL de posición fija que se supone debe quedar detrás de todo puede quedar silenciosamente atrapado dentro del contexto de apilamiento equivocado en el momento en que un ancestro adquiere una de esas propiedades, rompiendo el orden de capas de una forma fácil de confundir con un bug de z-index cuando en realidad es un bug de bloque contenedor.

La solución es arquitectónica, no un parche de z-index: mantener el canvas WebGL y el contenedor CSS3D como verdaderos hermanos en la raíz del documento, cada uno con su propio z-index explícito, en lugar de anidar cualquiera de los dos dentro de un elemento que algún día podría adquirir un `transform` o `filter` por una razón no relacionada.