HLSL

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 31 de diciembre de 2016; las comprobaciones requieren 13 ediciones .

HLSL ( lenguaje de sombreado de alto nivel ) es un lenguaje similar a C de alto nivel para la programación de sombreadores . 

Fue creado por Microsoft e incluido en el paquete DirectX 9.0.

Tipos de datos

HLSL admite tipos escalares, tipos vectoriales, matrices y estructuras.

Tipos escalares

Tipos de vectores

Ejemplo: vector <float, 4> color;

Ejemplo: float4 nuevo color;

Ejemplo: float oldcolor[4]

Ejemplo: newcolor = float4(oldcolor[0], oldcolor[1], oldcolor[2], oldcolor[3])

Matrices

Ejemplo: matriz <float, 4> view_matrix;

Ejemplo: float 4x4 view_matrix;

Estructuras

estructura vs_input {

float4 pos:POSICIÓN; float3 ni:NORMAL; float2uv:TEXCOORD0;

}; estructura ps_input {

float4 pos:POSICIÓN; float3 ni:NORMAL; float2uv:TEXCOORD0; flotar CustomVar; textura2D CustomTexture; //y así sucesivamente... :POSICIÓN :NORMAL etc. son sentimáticos, más sobre ellos a continuación.

};

Operadores

Operaciones Operadores
Aritmética -, +, *, /, %
incrementar, decrementar ++, --
rompecabezas \|, ?:
unario !, -, +
comparaciones <, >, <=, >=, ==, !=
Objetivo =, -=, +=, *=, /=
Emitir (tipo de)
Coma ,
Miembro de estructura .
miembro de la matriz [índice]

Sucursales

if (expresión) <sentencia> [ else <sentencia>]

Ciclos

Hay 3 tipos de bucles en HLSL:

Funciones

funciones matematicas

abdominales(x) devuelve el valor absoluto de cada componente x
acos(x) devuelve el arcocoseno de cada componente x. Cada componente debe estar en el rango [-1, 1]
asen(x) devuelve el arcoseno de cada componente x. Cada componente debe estar en el rango [-pi/2, pi/2]
atán(x) devuelve el arco tangente de cada componente x. Cada componente debe estar en el rango [-pi/2, pi/2]
techo(x) devuelve el entero más pequeño que es mayor o igual a x (redondear hacia arriba)
porque(x) devuelve el coseno de x
efectivo (x) devuelve el coseno hiperbólico de x
abrazadera (x, a, b) Si x < a, entonces devuelve a, si x > b, entonces devuelve b, de lo contrario, devuelve x.
ddx(x) devuelve la derivada parcial de x con respecto a la coordenada x del espacio de pantalla
dy(x) devuelve la derivada parcial de x con respecto a la coordenada y del espacio de pantalla
grados(x) Convertir x de radianes a grados
distancia (a, b) devuelve la distancia entre dos puntos a y b
punto (a, b) devuelve el producto escalar de dos vectores a y b
exp(x) devuelve el exponente con base e, o e x
piso(x) devuelve el entero más grande que es menor o igual que x (redondeado hacia abajo)
fracción( x ) devuelve la parte fraccionaria de x.
ancho(x) devuelve abs(ddx(x))+abs(ddy(x))
len(v) Longitud vectorial
longitud devuelve la longitud del vector v
lerp(a, b, s) devuelve a + s (b - a)
registro (x) devuelve el logaritmo de x
registro10(x) devuelve el logaritmo decimal de x
modf(x, ip de salida) vuelve a las partes fraccionaria y entera de x, cada parte tiene el mismo signo que x
mu(a, b) hace una multiplicacion de matrices entre a y b
normalizar(v) devuelve un vector normalizado v
pow(x, y) devuelve x y
radianes(x) convertir x de grados a radianes
reflejar (yo, n) devuelve el vector de reflexión
refractar(i, n, eta) devuelve el vector de refracción.
ronda( x ) devuelve el entero más cercano.
rsqrt(x) devuelve 1 / sqrt(x)
saturar(x) Igual que abrazadera(x,0,1)
pecado(x) devuelve el seno de x.
sincos(x, fuera s, fuera c) devuelve el seno y el coseno de x
sen(x) devuelve el seno hiperbólico de x
sqrt(x) devuelve la raíz cuadrada de cada componente
paso (a, x) devuelve 1 si x >= a, de lo contrario devuelve 0
bronceado(x) devuelve la tangente de x
tanh(x) devuelve la tangente hiperbólica de x

funciones de textura

tex1D(s, t) Lectura de una textura unidimensional
s - sampler, t - escalar.
tex1D(s, t, ddx, ddy) Lectura de una textura unidimensional, siendo las derivadas
s sampler, t, ddx y ddy escalares.
tex1Dproj(s, t) Lectura de una textura proyectiva unidimensional
s - sampler, t - vector 4D.
t se divide por tw antes de ejecutar la función.
tex1Dsesgo(s, t) Al leer de una textura unidimensional con un desplazamiento, s es una muestra, t es un vector de 4 dimensiones.
El nivel de mip se cambia por tw antes de que se realice la búsqueda.
tex2D(s, t) Lectura de una textura 2D
s es una muestra, t es un vector 2D.
tex2D(s, t, ddx, ddy) Lectura de una textura 2D, con derivadas.
s - muestra, t - coordenadas de textura 2D. ddx, ddy- Vectores 2D.
tex2Dproj(s, t) Lectura de una textura proyectiva 2D.
s - muestra, t - vector 4D.
t se divide por tw antes de ejecutar la función.
tex2Dsesgo(s, t) Lectura de una textura 2D con un desplazamiento.
s es un muestreador, t es un vector de 4 dimensiones.
El nivel de mip se cambia por tw antes de que se realice la búsqueda.
tex3D(s, t) Lectura de una textura 3D.
s - muestra, t - vector 3D.
tex3D(s, t, ddx, ddy) Lectura a partir de una textura 3D, con derivadas.
s - sampler, t - coordenadas de textura 2D, ddx, ddy - vectores 3D.
tex3Dproj(s, t) Lectura de una textura proyectiva 3D.
s - muestra, t - vector 4D.
t se divide por tw antes de ejecutar la función.
tex3Dsesgo(s, t) Lectura de una textura 3D con un desplazamiento.
s es un muestreador, t es un vector de 4 dimensiones.
El nivel de mip se cambia por tw antes de que se realice la búsqueda.
texCUBO(s, t) Lectura de una textura de cubo.
s - muestra, t - coordenadas de textura 3D.
texCUBO(s, t, ddx, ddy) Lectura de una textura de cubo.
s - sampler, t - coordenadas de textura 3D, ddx, ddy - vectores 3D.
texCUBEproj(s, t) Lectura desde una textura proyectiva cúbica.
s - muestra, t - vector 4D.
t se divide por tw antes de ejecutar la función.
texCUBEbias(s, t) Lectura de una textura de cubo.
muestreador, t es un vector 4D.
El nivel de mip se cambia por tw antes de que se realice la búsqueda.

Datos de entrada y salida para sombreadores de vértices y píxeles

Los sombreadores de vértices y fragmentos tienen dos tipos de entrada: variables y uniformes .

Uniforme  : datos que son constantes para uso múltiple en el shader. La declaración de datos uniformes en HLSL se puede hacer de dos maneras:

1) Declarar los datos como una variable externa. Por ejemplo:

valor flotante4; float4 main() : COLOR { valor de retorno; }

2) Declarar los datos a través del calificador uniforme. Por ejemplo:

float4 principal (valor uniforme de float4): COLOR { valor de retorno; }

Las variables uniformes se especifican a través de una tabla de constantes. La tabla de constantes contiene todos los registros que se utilizan constantemente en el shader.

Variando  son los datos que son únicos para cada llamada de shader. Por ejemplo: posición, normal, etc. En el sombreador de vértices, esta semántica describe los datos variables que se pasan desde el búfer de vértices, y en el sombreador de fragmentos, los datos interpolados recibidos desde el sombreador de vértices.

Principales tipos semánticos entrantes:

BINORMALES binormal
MEZCLA DE PESO Coeficiente de peso
MEZCLAS ÍNDICES índice de matriz de peso
COLOR Color
NORMAL Normal
POSICIÓN Posición
TAMAÑO Tamaño de punto
TANGENTE Tangente
factor de prueba factor de teselado
TEXCOORD Coordenadas de textura

El uso de datos variables en un sombreador de fragmentos determina el estado de un solo fragmento. Principales tipos semánticos entrantes:

COLOR Color
TEXCOORD Coordenadas de textura

Datos salientes para el sombreador de vértices:

POSICIÓN Posición
TAMAÑO Tamaño de punto
NIEBLA Factor de nebulosa para el vértice
COLOR Color
TEXCOORD Coordenadas de textura

Datos salientes para el sombreador de fragmentos:

COLOR Color
PROFUNDIDAD Valor de profundidad

Programas para crear shaders

Para facilitar la escritura de shaders, hay una serie de programas que le permiten componer shaders y ver inmediatamente el resultado.

Los renderizadores también utilizan sombreadores de píxeles, por ejemplo,

Ejemplos

el sombreador de "Mapeo de texturas" más simple

El código de esta lista funciona en ATI Rendermonkey y Nvidia FX composer. Para usarlo en un motor personalizado, debe especificar SamplerState y la técnica.

/* ========== VERTEX SHADER ========== */ /* world_matrix, view_matrix, proj_matrix deben obtenerse de la aplicación configurando constantes de sombreado. Las constantes de sombreado se cargan en los registros. */ float4x4 matriz_mundial ; // matriz mundial float4x4 view_matrix ; // matriz como float4x4 proj_matrix ; // matriz de proyección struct VS_OUTPUT // una instancia de esta estructura devolverá un vertex shader { float4 Pos : POSITION0 ; /* POSITION0 y TEXCOORD0 son semánticas que indican las ranuras de las que el sombreador de píxeles recibirá datos más tarde. La semántica especificada aquí debe coincidir con la semántica en la entrada del sombreador de píxeles. Los nombres y el orden de las variables pueden variar.*/ float2 TexCoord : TEXCOORD0 ; }; VS_OUTPUT VS_Main ( float4 InPos : POSITION0 , float2 InTexCoord : TEXCOORD0 ) /* El sombreador de vértices se ejecuta para cada vértice del objeto de salida. InPos e InTexCoord obtenidos de datos de mapeo de flujo */ { VS_OUTPUT Out ; float4x4 worldViewProj_matrix = mul ( world_matrix , view_matrix ); worldViewProj_matrix = mul ( worldViewProj_matrix , proj_matrix ); fuera _ Pos = mul ( InPos , worldViewProj_matrix ); // transforma el vértice en espacio de recorte Out . TexCoord = InTexCoord ; // obtenemos coordenadas de textura desde el exterior, no es necesario modificar nada volver a salir ; } /* ========== PIXEL SHADER ========== */ mapa base sampler2D ; // sampler2D es una "ranura de textura" especial en la que se puede cargar una textura. float4 PS_Main ( float2 texCoord : TEXCOORD0 ) : COLOR0 /* El sombreador de píxeles siempre devuelve el color del píxel renderizado con semántica COLOR0 en formato float4. El sombreador de píxeles se ejecuta para cada píxel de la imagen renderizada (no para cada texel de textura) */ { return tex2D ( baseMap , texCoord ); /* tex2d(sampler2D, float2) lee del sampler de texturas (de la textura) el color de su texel con las coordenadas de textura dadas. Este será el color del píxel de salida. */ }

un simple shader Vertigo

float4x4 view_proj_matrix : registro ( c0 ); struct VS_OUTPUT { float4 Pos : POSICIÓN ; float2 texCoord : TEXCOORD0 ; }; VS_OUTPUT VS_Mareado ( float4 Pos : POSICIÓN ) { VS_OUTPUT Salida ; pos . xy = signo ( Pos . xy ); fuera _ Pos = float4 ( Pos . xy , 0 , 1 ); fuera _ texCoord = Pos . xy ; volver a salir ; } flotar time_0_X : registro ( c0 ); anillos flotantes : registro ( c1 ); velocidad de flotación : registro ( c2 ); exponente flotante : registro ( c3 ); float4 PS_Mareado ( float2 texCoord : TEXCOORD0 ) : COLOR { float ang = atan2 ( texCoord . x , texCoord . y ); float rad = pow ( punto ( texCoord , texCoord ), exponente ); return 0.5 * ( 1 + sin ( ang + anillos * rad + velocidad * time_0_X )); }

shader que simula una descarga eléctrica

struct VS_OUTPUT { float4 Pos : POSICIÓN ; float2 texCoord : TEXCOORD ; }; VS_OUTPUT VS_Electricidad ( float4 Pos : POSICIÓN ) { VS_OUTPUT Salida ; // Limpiar imprecisiones Pos . xy = signo ( Pos . xy ); fuera _ Pos = float4 ( Pos . xy , 0 , 1 ); fuera _ texCoord = Pos . xy ; volver a salir ; } float4 color : registro ( c1 ); float resplandorFuerza : registro ( c2 ); altura flotante : registro ( c3 ); float glowFallOff : registro ( c4 ); velocidad de flotación : registro ( c5 ); float sampleDist : registro ( c6 ); float ambientGlow : registro ( c7 ); float ambientGlowHeightScale : registro ( c8 ); float vertNoise : registro ( c9 ); flotar time_0_X : registro ( c0 ); Muestreador Ruido : registro ( s0 ); float4 PS_Electricity ( float2 texCoord : TEXCOORD ) : COLOR { float2 t = float2 ( velocidad * time_0_X * 0.5871 - vertNoise * abs ( texCoord . y ), velocidad * time_0_X ); // Muestree en tres posiciones para obtener algo de desenfoque horizontal // El shader debería desdibujarse bien por sí mismo en dirección vertical float xs0 = texCoord . x - muestraDist ; float xs1 = texCoord . x ; float xs2 = texCoord . x + muestraDist ; // Ruido para las tres muestras float noise0 = tex3D ( Noise , float3 ( xs0 , t )); float ruido1 = tex3D ( Ruido , float3 ( xs1 , t )); float ruido2 = tex3D ( Ruido , float3 ( xs2 , t )); // La posición del flash float mid0 = altura * ( ruido0 * 2 - 1 ) * ( 1 - xs0 * xs0 ); float mid1 = altura * ( ruido1 * 2 - 1 ) * ( 1 - xs1 * xs1 ); float mid2 = altura * ( ruido2 * 2 - 1 ) * ( 1 - xs2 * xs2 ); // Distancia a flash float dist0 = abs ( texCoord . y - mid0 ); float dist1 = abs ( texCoord . y - mid1 ); float dist2 = abs ( texCoord . y - mid2 ); // Resplandor según la distancia al flash float glow = 1.0 - pow ( 0.25 * ( dist0 + 2 * dist1 + dist2 ), glowFallOff ); // Agregue un poco de brillo ambiental para obtener algo de poder en el aire sintiendo float ambGlow = ambientGlow * ( 1 - xs1 * xs1 ) * ( 1 - abs ( ambientGlowHeightScale * texCoord . y )); return ( fuerzabrillante * resplandor * resplandor + ambGlow ) * color ; }

modelo de plastilina

float4x4 view_proj_matrix : registro ( c0 ); float4 view_position : registro ( c4 ); struct VS_OUTPUT { float4 Pos : POSICIÓN ; float3 normal : TEXCOORD0 ; float3 viewVec : TEXCOORD1 ; }; VS_OUTPUT VS_Plastic ( float4 Pos : POSICIÓN , float3 normal : NORMAL ) { VS_OUTPUT Salida ; fuera _ Pos = mul ( view_proj_matrix , Pos ); fuera _ normales = normales ; fuera _ viewVec = view_position - Pos ; volver a salir ; } float4 color : registro ( c0 ); float4 PS_Plastic ( float3 normal : TEXCOORD0 , float3 viewVec : TEXCOORD1 ) : COLOR { float v = 0.5 * ( 1 + dot ( normalize ( viewVec ), normal )); devuelve v * color ; }

Enlaces