Ir al contenido

Fijación de Texturas

La primera vez que activas un efecto de partículas con una textura de alta resolución, a veces ves un breve instante en el que las primeras partículas se renderizan sin imagen — solo una forma de color plano — y luego la textura aparece de golpe. Un par de fotogramas después, todas las partículas siguientes muestran la textura correctamente.

Eso es la carga diferida de recursos de Roblox. Cuando una propiedad Texture o Image hace referencia a un id de recurso, Roblox no carga ese recurso hasta que algo visible lo referencia. La primera referencia activa una descarga (si el recurso no está en caché) y una decodificación (que convierte los bytes en una textura lista para la GPU). La decodificación tarda entre 50 y 200 milisegundos en un recurso típico — tiempo suficiente para abarcar varios fotogramas a 60 fps. Durante esa ventana, la partícula se renderiza sin textura.

Para la mayoría de los efectos, esto no es visible. Cuando ya estás emitiendo cientos de partículas, la textura está cargada y el resto se reproducen correctamente. Pero para la primera emisión — especialmente en momentos cinemáticos o de impacto donde el primer fotograma importa — el fotograma sin textura puede percibirse como un fallo visual.

PreloadTexture es la solución del plugin. Fuerza la carga del recurso y lo mantiene residente en memoria GPU antes de que cualquier partícula visible lo referencie.

El plugin mantiene una superficie de UI oculta que alberga una referencia casi invisible a cada recurso de textura fijado. La referencia es funcionalmente invisible pero cuenta como una referencia de “renderizado”, lo que mantiene el recurso residente en memoria GPU bajo presión normal.

Cuando activas PreloadTexture = true en un elemento transformado, el plugin recorre el subárbol del elemento (incluido su RenderTemplate), recopila todos los ids de recursos de textura que puede encontrar — Decal.Texture, MeshPart.TextureID, Beam.Texture, ImageLabel.Image, Trail.Texture, etc. — y fija cada id único (o reutiliza una fijación existente si otro elemento ya fijó el mismo id). La fijación mantiene el recurso en memoria, y cualquier referencia posterior a ese id de recurso se renderiza inmediatamente sin el retraso de decodificación.

El atributo está expuesto en la sección Advanced del panel de propiedades para estos tipos:

  • Part
  • Beam
  • Trail
  • ImageLabel
  • Model (añadido en v33; recopila todos los ids de textura alcanzables a través del subárbol del Model al activarlo)
  • ParticleEmitter nativo

Estos son los tipos que tienen referencias de textura que vale la pena precargar. PointLight, Attachment, Atmosphere y los tipos de postprocesado no tienen texturas propias, por lo que el atributo no se estampa en ellos.

Para Model, tienes una elección: activa PreloadTexture en el Model mismo (v33+) y el plugin recorre todo el subárbol en tu nombre, o activa cada Part/Beam/Trail hijo individualmente para un control más preciso. Las versiones anteriores del plugin solo admitían la ruta por hijo; la v33 añadió el selector a nivel de Model como atajo.

Conteo de referencias — compartir fijaciones

Sección titulada «Conteo de referencias — compartir fijaciones»

Múltiples elementos pueden referenciar el mismo recurso. Una escena con una docena de emisores Beam usando rbxassetid://12345 produce solo una fijación en el ScreenGui oculto. El plugin rastrea la propiedad con un conteo de referencias: cada elemento que fija el recurso se añade a la lista de propietarios del recurso. Cuando un elemento desactiva la fijación (desactiva PreloadTexture, o es destruido), se elimina de la lista. La fijación permanece activa mientras algún propietario aún la referencie.

Esto es importante porque la precarga no es gratuita. Cada fijación mantiene un recurso residente en memoria GPU. Una escena con cientos de texturas únicas de alta resolución fijadas a la vez puede agotar la VRAM en dispositivos de gama baja. El modelo de conteo de referencias evita que las fijaciones redundantes multipliquen el coste.

La llamada ContentProvider:PreloadAsync de precarga ocurre en el momento en que activas el atributo, no al iniciar el plugin ni al momento de emitir. Activarlo desencadena un lote asíncrono — el plugin genera una tarea que llama a PreloadAsync con todas las fijaciones nuevas, deja que Roblox las procese en orden y retorna cuando termina.

Esto significa:

  • Activar muchos indicadores PreloadTexture a la vez (por ejemplo, en una selección múltiple de emisores) inicia una sola precarga en lote, más rápida que fijar de uno en uno.
  • Activar en el momento en que necesitas el efecto es demasiado tarde — la precarga se ejecuta de forma asíncrona y puede no terminar antes de que el efecto emita. Activa PreloadTexture en los elementos fuente durante la configuración de la escena, no durante el tiempo de ejecución.
  • Reiniciar el plugin (desactivarlo y reactivarlo) borra todas las fijaciones, por lo que es necesario volver a activarlas tras el reinicio.

Los ids de recursos inválidos fallan silenciosamente. Si la Texture de un elemento referencia un id de recurso inexistente (un error tipográfico, un recurso eliminado), PreloadAsync no lanza ningún error — Roblox gestiona los ids incorrectos internamente. La fijación sigue creándose (el ImageLabel permanece ahí sin imagen), pero no se carga nada útil. El destello de “textura ausente” persiste en la primera emisión porque no hay nada que precargar.

La desactivación del plugin borra todas las fijaciones. Desactivar el plugin (cerrar Studio, deshabilitar el plugin) destruye el ScreenGui oculto y todas las fijaciones que contiene. Roblox puede o no expulsar los recursos dependiendo de la presión de memoria; normalmente permanecen en caché durante una breve ventana después, pero no puedes confiar en ello. Vuelve a habilitar el plugin para volver a fijar.

Fijar muchos recursos no es gratuito. Cada fijación mantiene un recurso en memoria GPU. Fijar 200 texturas grandes a la vez puede causar un pico de memoria notable en dispositivos de gama baja. Para bibliotecas de recursos masivas, precarga de forma selectiva (solo las texturas que necesitas para la escena actual), no de forma exhaustiva.

La fijación ocurre para el id de textura, no para el contenido de la textura. Si cambias la Texture de un Beam para apuntar a un id de recurso diferente después de fijar, el plugin no desactiva automáticamente la fijación del recurso anterior y fija el nuevo. Desactiva PreloadTexture y vuelve a activarlo para actualizar el conjunto de fijaciones.

Para padres Model, las fijaciones de los hijos son independientes. Un Part hijo fijado dentro de un Model no fijado sigue estando fijado. El selector PreloadTexture propio del Model (si existe — confírmalo en el panel) no se propaga a los hijos automáticamente.

Úsalo cuando:

  • Tu efecto utiliza una textura grande y personalizada que será visible en momentos cinemáticos o de impacto donde el primer fotograma importa.
  • Estás publicando un juego pulido y quieres eliminar el breve destello de “textura en blanco”.
  • Estás creando un emisor con muchas texturas y quieres un rendimiento en tiempo de ejecución predecible (la fijación de texturas intercambia RAM en tiempo de carga por fluidez en tiempo de ejecución).

Omítelo cuando:

  • Tu textura es un recurso integrado de Roblox o de caché frecuente (esos se decodifican rápidamente de todos modos).
  • El primer fotograma del efecto no es visible para los jugadores (es parte de una acumulación más lenta).
  • Tienes restricciones de memoria en la plataforma de destino y no puedes permitirte fijar muchos recursos.

El último capítulo de Profundidades Ocultas es la inmersión profunda en las matemáticas de GraphBlender — una visión de más alto nivel sobre cómo el motor renderiza el Color y la Transparencia multi-estado de Beam en cada fotograma, además de los casos límite que sorprenden a los usuarios por primera vez (estado único, carpeta vacía, Time fuera del rango 0–1, dos estados compartiendo un Time).