OpenGL Core Details
Graphics Command Buffers

Sombreadores de Computación(Compute Shaders)

Los Compute Shaders son programas que corren en la tarjeta gráfica, afuera del canalizado(pipeline) normal de renderización. Ellos pueden ser utilizados para algoritmos GPGPU masivamente paralelos, o para acelerar partes del renderizado del juego. Con el fin de utilizarlos eficientemente, a veces un conocimiento a profundidad de arquitectura de GPU y de algoritmos paralelos es necesitado; también conocimiento de DirectCompute, OpenCL o CUDA.

Compute shaders in Unity closely match DirectX 11 DirectCompute technology. Platforms where compute shaders work:

  • Windows and Windows Store, with a DirectX 11 graphics API and Shader Model 5.0 GPU.
  • Modern OpenGL platforms (OpenGL 4.3 on Linux or Windows; OpenGL ES 3.1 on Android). Note that Mac OS X does not support OpenGL 4.3, so no compute shaders there yet.
  • Consolas Modernas (Sony PS4 y Microsoft XboxOne).

Assets del Compute Shader

Similar a normal shaders, Computes Shaders son archivos assets en su proyecto, con una extensión de archivo *.compute. Son escritos en un lenguaje estilo DirectX 11 HLSL, con una cantidad mínima de directivas de compilación #pragma para indicar qué funciones compilar 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.

Please note when using multiple #pragma kernel lines that comments of the style // text are not permitted on the same line as the #pragma kernel directives and will cause compilation errors.

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.

Muestreadores 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.

Cross-platform support

As with regular shaders, Unity is capable of translating compute shaders from HLSL to GLSL. Therefore for the easiest cross-platform builds it is recommended to write compute shaders in HLSL.

OpenGL compute differences from D3D

In order to achieve shaders working on multiple different platforms one should consider these limitations:

  • D3D and OpenGL have different data layout rules. Automatically translated GLSL shaders use std430 layout on compute buffers. Therefore for example using float3 based structured buffers will cause compatibility issues as DX allows tight packing but OpenGL enforces padding to float4. Scalars, two-component and four-component vectors are safe to use as they are. Extra care should be taken when constructing structs.
  • OpenGL ES 3.1 guarantees support for only 4 simultaneous shader storage buffers. Actual implementations typically support a bit more but in general one should consider grouping related data in structs as opposed to having each data item in its own buffer.

HLSL-only or GLSL-only compute shaders

Typically compute shader files are written in HLSL, and compiled or translated into all needed platforms automatically. However it is possible to either prevent translation to GLSL (i.e. only keep HLSL platforms), or to write GLSL compute code manually.

  • Compute shader source surrounded by CGPROGRAM and ENDCG keywords will not be processed for OpenGL/GLSL platforms.
  • Compute shader source surrounded by GLSLPROGRAM and ENDGLSL keywords will be treated as GLSL source, and emitted verbatim. This will only work when targetting OpenGL/GLSL platforms.

Note that for cross-platform builds neither of the above is recommended, since it very much ties compute shader source into being excluded from some platforms.

OpenGL Core Details
Graphics Command Buffers