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:
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:
Texture2D MyTex; SamplerState samplerMyTex
). En este caso, sampler será inicializado a los ajustes de filter/wrap/aniso de esa textura."SamplerState MyLinearClampSampler"
- este va a tener un filtro lineal y modo clamp de envoltura.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.
In order to achieve shaders working on multiple different platforms one should consider these limitations:
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.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.
CGPROGRAM
and ENDCG
keywords will not be processed for OpenGL/GLSL platforms.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.