Cg (abreviatura de C for Graphics ) y High-Level Shader Language (HLSL) son dos nombres dados a un lenguaje de sombreado de alto nivel desarrollado por Nvidia y Microsoft para programar sombreadores . Cg/HLSL se basa en el lenguaje de programación C y, aunque comparten la misma sintaxis básica, se modificaron algunas características de C y se agregaron nuevos tipos de datos para hacer que Cg/HLSL sea más adecuado para programar unidades de procesamiento de gráficos . [1] [2]
Existen dos ramas principales del lenguaje Cg/HLSL: el compilador Cg de Nvidia (cgc), que genera DirectX u OpenGL , y el HLSL de Microsoft, que genera sombreadores DirectX en formato de bytecode. [3] [4] El cgc de Nvidia quedó obsoleto en 2012, sin desarrollo ni soporte adicional disponible. [5]
Los sombreadores HLSL pueden permitir muchos efectos especiales en gráficos de computadora tanto en 2D como en 3D . El lenguaje Cg/HLSL originalmente solo incluía compatibilidad con sombreadores de vértices y sombreadores de píxeles , pero gradualmente también se introdujeron otros tipos de sombreadores:
Debido a los avances técnicos en hardware gráfico, algunas áreas de la programación de gráficos 3D se han vuelto bastante complejas. Para simplificar el proceso, se agregaron nuevas funciones a las tarjetas gráficas, incluida la capacidad de modificar sus canales de renderizado mediante sombreadores de vértices y píxeles.
Al principio, los sombreadores de vértices y píxeles se programaban a un nivel muy bajo con solo el lenguaje ensamblador de la unidad de procesamiento gráfico. Aunque el uso del lenguaje ensamblador le daba al programador un control total sobre el código y flexibilidad, era bastante difícil de usar. Se necesitaba un lenguaje portátil de nivel superior para programar la GPU, por lo que se creó Cg para superar estos problemas y facilitar el desarrollo de sombreadores.
Algunas de las ventajas de utilizar Cg en lugar de ensamblaje son:
Cg tiene seis tipos de datos básicos. Algunos de ellos son los mismos que en C, mientras que otros se agregaron especialmente para la programación de GPU. Estos tipos son:
Cg también cuenta con tipos de datos vectoriales y matriciales que se basan en los tipos de datos básicos, como float3 y float4x4. Dichos tipos de datos son bastante comunes cuando se trabaja con programación de gráficos 3D. Cg también tiene tipos de datos de estructura y matriz , que funcionan de manera similar a sus equivalentes de C.
Cg admite una amplia gama de operadores, incluidos los operadores aritméticos comunes de C, los operadores aritméticos equivalentes para tipos de datos vectoriales y matriciales y los operadores lógicos comunes .
Cg comparte las estructuras de control básicas con C, como if/else, while y for. También tiene una forma similar de definir funciones.
Cg implementa muchas directivas del preprocesador C y su sistema de expansión de macros. Implementa #include
. [7]
Los programas Cg están diseñados para diferentes perfiles de sombreadores que representan GPU con diferentes capacidades. [8] Estos perfiles deciden, entre otras cosas, cuántas instrucciones puede haber en cada sombreador, cuántos registros están disponibles y qué tipo de recursos puede usar un sombreador. Incluso si un programa es correcto, puede ser demasiado complejo trabajar en un perfil. [7]
A medida que aumentó el número de perfiles y tipos de sombreadores, Microsoft comenzó a utilizar el término "Shader Model" para agrupar un conjunto de perfiles que se encuentran en una generación de GPU. [9] Cg admite algunos de los perfiles más nuevos hasta Shader Model 5.0, así como la traducción a glsl o hlsl. [8]
"32 + 64" para instrucciones ejecutadas significa "32 instrucciones de textura y 64 instrucciones aritméticas".
Al igual que en C, Cg/HLSL cuenta con un conjunto de funciones para tareas comunes en la programación de GPU. Algunas de las funciones tienen equivalentes en C, como las funciones matemáticas abs y sin, mientras que otras están especializadas en tareas de programación de GPU, como las funciones de mapeo de texturas tex1D y tex2D.
Los programas Cg son simplemente sombreadores de vértices y píxeles, y necesitan programas de soporte que se encarguen del resto del proceso de renderizado. Cg se puede utilizar con dos API de gráficos : OpenGL o DirectX . Cada una tiene su propio conjunto de funciones Cg para comunicarse con el programa Cg, como configurar el sombreador Cg actual, pasar parámetros y tareas similares.
Además de poder compilar el código fuente de Cg en código ensamblador, el entorno de ejecución de Cg también tiene la capacidad de compilar sombreadores durante la ejecución del programa de soporte. Esto permite que el entorno de ejecución compile el sombreador utilizando las últimas optimizaciones disponibles para el hardware en el que se está ejecutando el programa en ese momento. Sin embargo, esta técnica requiere que el código fuente del sombreador esté disponible en texto sin formato para el compilador, lo que permite al usuario del programa acceder al código fuente del sombreador. Algunos desarrolladores consideran que esto es un inconveniente importante de esta técnica.
Para evitar exponer el código fuente del sombreador y mantener algunas de las optimizaciones específicas del hardware, se desarrolló el concepto de perfiles. Los sombreadores se pueden compilar para adaptarse a diferentes plataformas de hardware gráfico (según los perfiles). Al ejecutar el programa de soporte, se carga el sombreador mejor/más optimizado según su perfil. Por ejemplo, puede haber un perfil para una tarjeta gráfica que admita sombreadores de píxeles complejos y otro perfil para una que admita solo sombreadores de píxeles mínimos. Al crear un sombreador de píxeles para cada uno de estos perfiles, un programa de soporte amplía la cantidad de plataformas de hardware compatibles sin sacrificar la calidad de la imagen en sistemas potentes.
El dialecto Cg solo ha tenido un compilador, en forma del kit de herramientas Cg de Nvidia.
Microsoft ha lanzado dos compiladores para HLSL. El compilador original era FXC (Effect Compiler) de código cerrado, compatible hasta 2015. Se dejó de usar en favor de DXC (DirectXShaderCompiler) de código abierto basado en LLVM con soporte para funciones HLSL más nuevas. [21] Ambos compiladores generan código de bytes: mientras que el antiguo FXC usaba DXBC, DXC ahora usa DXIL. DXC también puede emitir código de bytes SPIR-V . [22]
El Grupo Khronos también ha escrito un compilador HLSL basado en LLVM, en forma de interfaz para glslang , su compilador GLSL a SPIR_V. La compatibilidad con SPIR-V significa que los sombreadores pueden ser multiplataforma, sin limitarlos a una pila DirectX. [23] Esta tarea la realizaban anteriormente convertidores a nivel de fuente como HLSL2GLSL , pero el código resultante suele estar inflado. [24]
El lenguaje PlayStation Shader (PSSL) se basa en Cg/HLSL. [25]
El lenguaje de sombreado ReshadeFX también se basa en Cg/HLSL. Los sombreadores escritos en ReshadeFX se compilan en OpenGL, DX o Vulkan y se inyectan en los juegos para que actúen como filtros de posprocesamiento. [26]