Niveles Objetivo de Compilación Shader
Sintaxis ShaderLab

Tipos de dato Shader y precisión

The standard Shader language in Unity is HLSL, and general HLSL data types are supported. However, Unity has some additions to the HLSL types, particularly for better support on mobile platforms.

Tipos de datos básicos

La mayoría de los cálculos en shaders se llevan a cabo en números de punto flotante (que sería float en lenguajes de programación regulares como C#). Existen varias variantes de tipos de punto flotante: float,half y fixed (así como las variantes de vector/matriz de ellas, comohalf3 y float4x4). Estos tipos difieren en precisión (y, en consecuencia, en rendimiento o consumo de energía):

Precisión alta: float

Valor de punto flotante de precisión más alta; Generalmente 32 bits (como float desde lenguajes de programación regulares).

La precisión completa del float se utiliza generalmente para las posiciones del espacio del mundo, coordenadas de textura, o cálculos escalares involucrando funciones complejos como trigonometría o Potencia/exponenciación.

Precisión mediana: half

Valor de punto flotante de precisión media; Generalmente 16 bits (rango de –60000 a +60000, con unos 3 dígitos decimales de precisión).

La media precisión es útil para vectores cortos, direcciones, posiciones de espacio de objeto, colores de alto rango dinámico.

Precisión baja: fixed

Valor de punto fijo de precisión más baja. Generalmente 11 bits, con un rango de –2.0 a +2.0 y precisión 1 / 256th.

La precisión fija es útil para los colores regulares (normalmente almacenados en texturas regulares) y para realizar operaciones sencillas sobre ellos.

Tipos de dato Integer

Los enteros (tipo de datos int) se utilizan a menudo como contadores de bucle o índices de matriz. Para este propósito, generalmente funcionan bien en varias plataformas.

Dependiendo de la plataforma, los tipos enteros podrían no ser compatibles con la GPU. Por ejemplo, las GPU Direct3D 9 y OpenGL ES 2.0 sólo funcionan con datos de punto flotante, y las expresiones enteras de apariencia simple (que implican bits o operaciones lógicas) pueden emularse utilizando instrucciones matemáticas de punto flotante bastante complicadas.

Direct3D 11, OpenGL ES 3, Metal y otras plataformas modernas tienen soporte adecuado para tipos de datos enteros, por lo que el uso de los desplazamientos de bit y el bit masking funciona como se esperaba.

Tipos de vector/matriz compuestos

HLSL incorpora tipos vectoriales y matriciales que se crean a partir de los tipos básicos. Por ejemplo, float3 es un vector 3D con componentes .x, .y, .z, yhalf4 es un vector 4D de precisión media con componentes .x, .y, .z, .w. Alternativamente, los vectores pueden indexarse utilizando los componentes .r, .g, .b, .a, que es útil cuando se trabaja en colores.

Los tipos de matriz se construyen de manera similar; Por ejemplo float4x4 es una matriz de transformación 4x4. Tenga en cuenta que algunas plataformas sólo admiten matrices cuadradas, especialmente OpenGL ES 2.0.

Texture/Sampler types

Typically you declare textures in your HLSL code as follows:

sampler2D _MainTex;
samplerCUBE _Cubemap;

For mobile platforms, these translate into “low precision samplers”, i.e. the textures are expected to have low precision data in them. If you know your texture contains HDR colors, you might want to use half precision sampler:

sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;

Or if your texture contains full float precision data (e.g. depth texture), use a full precision sampler:

sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;

Precision, Hardware Support and Performance

Una complicación del uso de tipo de datos float/half/fixed es que las GPUs de PC son siempre de alta precisión. Es decir, para todas las PC (Windows/Mac/Linux) GPUs, no importa si usted escribe tipos de datos float, half or fixed en sus shaders. Siempre calculan todo en una precisión punto flotante completo de 32-bit.

Los tipos half y fixed solo se vuelven relevantes cuando se apunta a GPUs móviles, donde estos tipos principalmente existen para restricciones de poder (y a veces rendimiento). Tenga en cuenta que usted necesitará probar sus shaders en móvil para ver Si o no se está ejecutando en problemas de precisión/ numéricos.

Incluso en GPUs móviles, el soporte de precisión diferente varia entre familias GPU. A continuación se ofrece una descripción general de cómo la familia GPU trata cada tipo de punto flotante (indicado por el número de bits utilizados para este):

Familia GPU float half fixed
PowerVR Series 6/7 32 16
PowerVR SGX 5xx 32 16 11
Qualcomm Adreno 4xx/3xx 32 16
Qualcomm Adreno 2xx 32 vertex 24 fragment
ARM Mali T6xx/7xx 32 16
ARM Mali 400/450 32 vertex 16 fragment
NVIDIA X1 32 16
NVIDIA K1 32
NVIDIA Tegra 3/4 32 16

La mayoría de las GPU móviles actuales sólo soportan ya sea números de 32 bits (utilizados para el tipo float) o números de 16 bits (Utilizado tanto para los tipos half comofixed). Algunas GPU más antiguas tienen diferentes precisiones para los cálculos de vertex shader y de fragment shader.

El uso de una precisión más baja a menudo puede ser más rápido, ya sea debido a la mejora de la asignación de registro GPU, o debido a una ejecución especial “ruta rápido” de unidades para ciertas operaciones matemáticas de menor precisión. Incluso cuando no hay ventaja de rendimiento en bruto, el uso de menor precisión a menudo utiliza menos energía en la GPU, lo que lleva a una mejor duración de la batería.

Una regla general es comenzar con la mitad de precisión para todo, excepto las posiciones y las coordenadas de textura. Sólo aumentar la precisión si la media precisión no es suficiente para algunas partes del cálculo.

Soporte para infinito, NaNs y otros valores especiales de punto flotante

El soporte para valores de punto flotante especiales puede ser diferente dependiendo de la familia de GPU (principalmente móvil) que esté ejecutando.

Todas las GPUs de PC que soportan Direct3D 10 soportan un estándar punto flotante IEEE 754 muy bien especificado. Esto significa que los número float se comportan exactamente como lo hacen regularmente en lenguajes de programación en la CPU.

Las GPUs móviles tienen niveles diferentes de soporte. En algunos, dividir cero por cero podría resultar en un NaN (“no un número”); en otros podría dar como resultado infinito, cero u otro valor sin especificar. Asegúrese de probar sus shader en el dispositivo objetivo para revisar si son soportados.

Documentación GPU externa

Los proveedores de GPU tienen guías detalladas sobre rendimiento y capacidades de sus GPUs. Mire estos por detalles:

Véase también

Niveles Objetivo de Compilación Shader
Sintaxis ShaderLab