
Soporte de Texture Views en la API de bajo nivel
En esta nueva versión de Evergine, hemos introducido los Texture Views como concepto de primera clase en la API gráfica de bajo nivel. Los Texture Views permiten referenciar subrangos dentro de una textura, reinterpretar formatos de píxel y cambiar el tipo de vista — todo ello sin crear copias ni reservar memoria adicional en la GPU. Esta funcionalidad alinea Evergine con las APIs gráficas modernas y elimina copias de texturas innecesarias que antes afectaban al rendimiento.
¿Qué es un Texture View?
Una textura en la GPU puede adoptar muchas formas: 1D, 2D, 3D, cube maps, arrays y combinaciones de estos. Las APIs gráficas modernas como DirectX 12, Vulkan, Metal y WebGPU no permiten bindear una textura directamente al pipeline de renderizado. En su lugar, requieren un Texture View — un objeto que describe cómo debe interpretar la GPU los datos de la textura.
Un Texture View no contiene datos propios. Referencia una textura existente y proporciona una lente a través de la cual la GPU lee o escribe esos datos. Se puede pensar en él como una ventana hacia una textura: puede mostrar la textura completa, o solo una parte, e incluso presentar los datos en un formato o estructura diferente al original.

Capacidades principales
Los Texture Views en Evergine proporcionan cuatro capacidades principales:
Selección de subrango
Se puede seleccionar un subconjunto de niveles de mip y capas de array de una textura. Esto se controla con cuatro parámetros: baseMip, mipCount, baseLayer y layerCount.
Por ejemplo, imaginemos un Texture2DArray con 18 capas que representan los shadow maps de 3 luces puntuales (6 caras de cubo cada una). Se pueden crear Texture Views individuales que referencien las capas 0–5, 6–11 y 12–17, dando a cada luz su propia vista de cube map sin duplicar ningún dato.
Reinterpretación de formato
Los Texture Views pueden presentar los mismos datos con un formato de píxel diferente, siempre que los formatos sean compatibles. Por ejemplo, una textura almacenada como R8G8B8A8_UNorm puede verse como R8G8B8A8_UNorm_SRgb para aplicar corrección gamma. De forma similar, un depth buffer almacenado como D32_Float puede verse como R32_Float para que un compute shader pueda leerlo como un valor float normal.
Cambio de tipo de vista
Un Texture View puede cambiar cómo interpreta la GPU la estructura de la textura. Un Texture2DArray con exactamente 6 capas puede verse como un TextureCube, permitiendo a los shaders muestrearlo usando coordenadas de cube map. Esto es especialmente útil para técnicas de renderizado basadas en cubos, como shadow maps de luces puntuales o environment probes.
Binding dual
Con los Texture Views, se pueden crear tanto un Shader Resource View (para lectura) como un Unordered Access View (para escritura) a partir de la misma textura. Esto significa que un compute shader puede escribir en una textura y un pixel shader puede leerla sin necesidad de crear una copia intermedia.
El problema antes de los Texture Views
Antes de introducir los Texture Views, Evergine creaba cada textura con un tipo de vista fijo. En DirectX 11, por ejemplo, una textura se bindeaba como Shader Resource View o como Unordered Access View en el momento de su creación — y esa elección no podía cambiarse después.
Esta limitación hacía imposible usar la misma textura como entrada y como salida. Si un compute shader necesitaba escribir en una textura y luego un pixel shader necesitaba leerla, el motor tenía que mantener dos texturas separadas y realizar una copia en la GPU entre ellas. Esto duplicaba el uso de memoria y consumía ancho de banda de la GPU en cada operación de copia.
El pipeline de post-procesado se veía especialmente afectado: cada efecto de la cadena requería sus propias texturas intermedias y operaciones de copia, acumulando una sobrecarga significativa en escenas complejas.

Cómo se usan los Texture Views en Evergine
Con esta versión, ya hemos aplicado los Texture Views internamente en tres áreas clave del motor:
Pipeline de post-procesado
Cada efecto de post-procesado crea ahora un Texture View con el formato adecuado sobre su textura de entrada. Mediante la reinterpretación de formato (vía ToColorFormat()), el pipeline elimina las copias intermedias que antes eran necesarias entre los nodos de procesamiento.
Tone Mapping
El pase de tone mapping antes requería una copia completa de la textura para poder leer la entrada HDR. Con los Texture Views, la misma textura se referencia directamente con un formato compatible, eliminando la copia por completo.
Compute Depth Bounds
Este compute shader calcula los valores mínimo y máximo de profundidad en un frame para ajustar dinámicamente los planos near y far de la cámara, preservando la precisión de profundidad. Necesita leer el depth buffer, pero los formatos de profundidad no pueden muestrearse directamente como datos de color. Un Texture View reinterpreta el formato para que el compute shader pueda leerlo.
Uso de Texture Views en la API de bajo nivel
Crear un Texture View en Evergine es sencillo. El método Factory.CreateTextureView acepta la textura de origen y parámetros opcionales para personalizar la vista:
TextureView CreateTextureView(
Texture texture,
PixelFormat pixelFormat = PixelFormat.Unknown,
uint baseMip = 0,
uint mipCount = uint.MaxValue,
uint baseLayer = 0,
uint layerCount = uint.MaxValue,
TextureType? viewType = null);Estos son tres ejemplos prácticos:
Crear una vista CubeMap a partir de un array 2D con 6 capas
// facesTexture es un Texture2DArray con ArraySize = 6
var cubeView = gfxFactory.CreateTextureView(facesTexture, viewType: TextureType.TextureCube);Crear una vista de almacenamiento sin gamma para escritura con compute shader
UAV no soporta formatos sRGB:
var facesTextureDesc = new TextureDescription
{
Type = TextureType.Texture2DArray,
Format = PixelFormat.R8G8B8A8_UNorm_SRgb,
Width = 1024,
Height = 1024,
ArraySize = 6,
Flags = TextureFlags.ShaderResource | TextureFlags.UnorderedAccess,
};
var facesTexture = graphicsContext.Factory.CreateTexture(ref facesTextureDesc, "Faces");
// Quitar gamma para compatibilidad con UAV
var storeView = graphicsContext.Factory.CreateTextureView(
facesTexture, pixelFormat: facesTextureDesc.Format.WithoutGamma());Reinterpretar un depth buffer para lectura desde un compute shader
var depthView = graphicsContext.Factory.CreateTextureView(
depthTexture, pixelFormat: PixelFormat.R32_Float);Los Texture Views están implementados en todos los backends de renderizado: DirectX 11, DirectX 12, Vulkan, Metal, WebGPU y OpenGL.
Próximos pasos
Esta versión sienta las bases de los Texture Views en Evergine. En próximas versiones, planeamos ampliar su uso a más partes del motor.
Etapas adicionales del pipeline de renderizado adoptarán Texture Views para eliminar copias intermedias en la medida de lo posible.
También planeamos exponer los Texture Views de forma más amplia en la API de alto nivel, facilitando a los desarrolladores aprovechar esta funcionalidad en sus propios proyectos sin necesidad de trabajar directamente con la capa de bajo nivel.
Conclusión
Los Texture Views son un concepto fundamental en las APIs gráficas modernas, y Evergine ahora los soporta completamente. Eliminan copias de texturas innecesarias, reducen el uso de memoria de la GPU y permiten reinterpretación flexible de datos — todo sin reservar recursos adicionales. El pipeline de post-procesado, el tone mapping y el cálculo de depth bounds ya se benefician de esta funcionalidad, y más sistemas del motor seguirán en futuras versiones.
Daniel Cáceres Maña – Senior Researcher


