Detalles de OpenGL Core
Buffers de comando de gráficos (buffers de comando de gráficos)

Compute Shaders

Compute Shaders son unos programas que corren en la tarjeta gráfica, a fuera del pipeline normal de rendering. Estos se pueden utilizar para algoritmos GPGPU masivamente paralelos, o para acelerar partes del rendering del juego. Con el fin de utilizarlos eficientemente, a veces se necesita un profundo conocimiento de arquitecturas GPU y algoritmos; al igual que conocimiento de DirectCompute, OpenCL o CUDA.

Los Compute Shaders en Unity coinciden cerca con la tecnología DirectX 11 DirectCompute. Plataformas dónde los compute shaders funcionan:

  • Windows y Windows Store, con una API gráfica DirectX 11 y un GPU Shader Model 5.0.
  • Plataformas modernas OpenGL (OpenGL 4.3 en Linux o Windos; OpenGL ES 3.1 en Android). Tenga en cuenta que Mac OS X no soporta OpenGL 4.3, por lo que no habrá compute shaders ahí.
  • Consolas Modernas (Sony PS4 y Microsoft XboxOne).

Assets Compute Shader

Similar a los shaders regulares, los Computer Shaders son archivos asset en su proyecto, con una extensión de archivo *.compute. Están escritos en un estilo de lenguaje DirectX 11 HLSL, con una cantidad minima de directivas de compilación #pragma para indicar qué funciones se compilan como compute shader kernels.

He aquí un ejemplo mínimo de un archivo compute shader:

// test.compute

#pragma kernel FillWithRed

RWTexture2D<float4> res;

[numthreads(1,1,1)]
void FillWithRed (uint3 dtid : SV_DispatchThreadID)
{
    res[dtid.xy] = float4(1,0,0,1);
}

Tenga en cuenta que el ejemplo de arriba no hace nada remotamente interesante, simplemente llena la textura output con rojo.

El lenguaje es DX11, HLSL, estándar con la única excepción de una directiva #pragma kernel FillWithRed.Un archivo compute shader asset debe tener al menos un “compute kernel” que se pueda invocar, y esa función es indicada por la directiva #pragma. Puede haber más kernels en el archivo; simplemente agregue múltiples lineas #pragma kernel.

Por favor tenga en cuenta que cuando utilice varias lineas #pragma kernel que comentan el estilo // text no se permiten en la misma linea que las directivas #pragma kernel y causará errores de compilación.

La linea #pragma kernel puede opcionalmente ser seguida por un número de macros de pre-procesador para definir mientras se compila ese kernel, por ejemplo:

#pragma kernel KernelOne SOME_DEFINE DEFINE_WITH_VALUE=1337
#pragma kernel KernelTwo OTHER_DEFINE
// ...

Invocando compute shaders

En su script, defina una variable de tipo ComputeShader, asigne una referencia al asset, y luego usted puede invocarlas con la función ComputeShader.Dispatch. Vea la referencia scripting de ComputeShader class para más detalles.

Cercanamente relacionado a compute shaders está la clase ComputeBuffer, que define información búfer arbitraria (“structured buffer” en DX11 lingo). Render Textures también puede ser escrita en desde compute shaders, si tienen una bandera “random access” establecida (“unordered access view” en DX11), vea RenderTexture.enableRandomWrite.

Muestradores de textura en compute shaders

Las Texturas y los muestradores no son objetos separados en Unity, entonces con el fin de utilizarlos en compute shader usted debe seguir las siguientes reglas especificas de Unity:

  • Podemos tanto utilizar el mismo nombre de la textura, con “sampler” en frente (e.g. Texture2D MyTex; SamplerState samplerMyTex). En este caso, sampler será inicializado a los ajustes de filter/wrap/aniso de esa textura.
  • O utilice una de los muestradores “predefinidos”; nombre debe tener “Linear” o “Point” (para modo de filtración) y “Clamp” o “Repeat” ( para modo de envoltura). Por ejemplo, "SamplerState MyLinearClampSampler" - este va a tener un filtro lineal y modo clamp de envoltura.

Soporte multi-plataforma

Al igual que con los shaders regulares, Unity es capaz de traducir los compute shaders de HLSL a GLSL. Por lo tanto para las construcciones multiplataforma sencillas se recomienda escribir compute shaders en HLSL.

Diferencias de calculo OpenGL de D3D

Con el fin de lograr unos shaders que funcionen en varias plataformas, uno debe considerar estas limitaciones:

  • Los buffers de D3D y OpenGL tienen diferentes reglas en los diseños de datos. Los shaders GLSL automáticamente traducidos funcionen alrededor de este problema para que el mismo diseño de datos se puede utilizar en tanto D3E y OpenGL. Sin embargo, en el caso de escribir manualmente código GLSL las reglas de de diseño diferentes se deben tomar en cuenta.
  • OpenGL ES 3.1 garantiza soporte para 4 buffers de almacenamiento shader simultáneos. Las implementaciones actuales típicamente soportan un poco más pero en general uno debería considerar agrupar los datos relacionados en structs opuesto a tener cada item de dato en su propio buffer.

Compute shaders HLSL-solamente o GLSL-solamente

Típicamente los archivos compute shader están escritos en HLSL, y compilados o traducidos en todas las plataformas necesitadas automáticamente. Sin embargo, es posible prevenir la traducción a GLSL (i.e. solo mantiene plataformas HLSL), o para escribir código de calculo GLSL manualmente.

*Las fuentes compute shader en vueltas por las palabras clave CGPROGRAMyENDCGno serán procesadas para las plataformas OpenGL/GLSL. * Las fuentes compute shader envueltas por las palabras claveGLSLPROGRAMyENDGLSL` serán tratadas como fuentes GLSL, y emitidas verbatim. Esto solamente funciona cuando se apunte a plataformas OpenGL/GLSL.

Tenga en cuenta que para las construcciones multi-plataforma ninguna de las dos se recomienda, ya que significa que las fuentes compute shader serán excluidas para algunas plataformas.

Detalles de OpenGL Core
Buffers de comando de gráficos (buffers de comando de gráficos)