Shader/es

From Valve Developer Community
Jump to: navigation, search

Un shader es un software que se ejecuta en una tarjeta gráfica para determinar cómo debe dibujarse un objeto. Source utiliza shaders para todo en el mundo 3D.

Los shaders se manipulan con parámetros almacenados en archivos de material. Mientras que los más comunes son bastante simples, existen algunos muy complejos para manejar efectos como sombras en tiempo real, iluminación y refracción.

Si falta un shader en un material o modelo, la superficie aparecerá como un marco de alambre blanco. Los cuadros rosados y negros no son el producto de un shader faltante, sino que se generan cuando falta el material en sí.

Warning.pngAviso:El VBSP predeterminado de Source no reconoce shaders de lightmapped personalizados. Usa Slammin' Source Map Tools Slammin' Source Map Tools o Mapbase Mapbase's VBSPs, que fueron modificados para permitir la generación de Lightmap para shaders personalizados.

Tipos

Hay dos variantes de shaders, Shaders de píxeles y Shaders de vértices, cada uno de los cuales realiza una tarea diferente en la cadena de renderizado. Los shaders sustituyen la cadena de funciones fijas y permiten a los desarrolladores tener un mayor control sobre el resultado del renderizado, proporcionando la capacidad de modificar píxeles y vértices dinámicamente. El SDK incluye muchos shaders existentes.

Lenguajes de shader

Actualmente hay tres lenguajes principales de shader: High Level Shader Language (HLSL), C for Graphics (Cg) y OpenGL Shading Language (GLSL). El motor Source utiliza shaders basados en HLSL. Sin embargo, Cg es tan similar que la mayoría de los shaders Cg se pueden portar rápida y fácilmente a HLSL.

Modelos de shader

Un modelo de shader define qué tan avanzadas pueden ser las técnicas de shading en una tarjeta gráfica. Esto impide que las tarjetas gráficas más antiguas puedan reconocer físicamente técnicas de shading más nuevas.

Las versiones modernas de Source son compatibles con Shader Model 2.0 (incluyendo Pixel Shader 2.0b) y Shader Model 3.0.

Note.pngNota:Los shaders escritos para SM3 pueden no funcionar correctamente en sistemas Mac y Linux debido a la falta de soporte en el wrapper de gráficos de tiempo de ejecución de Valve, togl. Deberías planear hacer una versión SM2.0b de tus shaders si planeas dar soporte a estos sistemas.
Confirmar:¿Sigue siendo este el caso para juegos que usan el wrapper Vulkan?

Al crear shaders para tarjetas gráficas más nuevas, es importante recordar dar soporte a aquellas con tarjetas más antiguas, o rápidamente limitarás las especificaciones de tu juego a solo unos pocos. Las tarjetas más antiguas pueden requerir los llamados "shader fallbacks" para especificar, donde se usará un shader de respaldo (que use un modelo de shader más antiguo) si el shader más nuevo falla.

Si quieres aprender más sobre las especificaciones detalladas de los diferentes Modelos de Shader, lee el artículo de Wikipedia.

Para obtener información sobre cómo crear shaders para usar en el motor Source, consulta Shader Authoring.

Shaders de vértices

Los shaders de vértices se aplican para cada vértice en una cadena de renderizado programable. Su objetivo más básico es transformar la geometría en coordenadas de espacio de pantalla para que el Shader de píxeles pueda rasterizar una imagen. Los shaders de vértices pueden modificar estas coordenadas de posición para realizar deformaciones de malla. También pueden recibir información adicional de la malla, incluidos normales, tangentes y coordenadas de textura. Luego, el shader de vértices escribe en registros de salida; los valores escritos se interpolan a través de los vértices en los shaders de píxeles. Los shaders de vértices no pueden crear vértices.

A continuación, se proporciona un ejemplo de shader de vértices muy comentado, listo para usar en Source.

Ejemplo de shader de vértices

Este es un shader de paso a través, en el sentido de que no realiza modificaciones importantes en los datos de los vértices, sino que solo pasa los datos a la etapa del shader de píxeles.

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
// definiciones comunes de shader de vértices proporcionadas con este encabezado #include "common_vs_fxc.h" // define una estructura de salida struct VS_OUTPUT { // vector de posición (float4) float4 pos : POSITION0; // coordenadas de textura (uv - float2) float2 texCoord : TEXCOORD0; }; // función principal - nota la definición de estilo C // toma un vector de posición (float4) // devuelve una estructura VS_OUTPUT VS_OUTPUT main( float4 inPos: POSITION ) { // declara un VS_OUTPUT vacío para llenar VS_OUTPUT o = (VS_OUTPUT) 0; // calcula el signo de la posición de entrada inPos.xy = sign( inPos.xy); // establece la posición de salida usando xy de la entrada o.pos = float4( inPos.xy, 0.0f, 1.0f); // ajusta al rango [0,1] o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f; return o; }

Shaders de píxeles

Los shaders de píxeles se aplican para cada píxel renderizado en la pantalla. Un shader de píxeles espera recibir valores de vértices interpolados, que luego utiliza para rasterizar la imagen. Los shaders de píxeles pueden producir una amplia gama de efectos que implican el color de los píxeles individuales, como refracción, iluminación por píxel o reflexión.

A continuación, se proporciona un ejemplo de shader de píxeles muy comentado, listo para usar en Source.

Ejemplo de shader de píxeles

El shader de píxeles a continuación está destinado a usarse como un shader de postproceso y crea un efecto en escala de grises.

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
// especifica un sampler de textura, la fuente real de esto se especifica en un vmt sampler2D Texture0 : register( s0 );<br> // mismo estilo de declaración de función que los shaders de vértices // los shaders de píxeles devuelven el valor de color del píxel (por eso el float4) float4 main( float2 texCoord : TEXCOORD0 ) : COLOR { // muestra la textura en las coordenadas de textura especificadas float4 tex = tex2D( Texture0, texCoord );<br> // escala de grises los valores de color del píxel // - realiza un producto punto entre el color del píxel y el vector especificado // - 0.222, 0.707, 0.071 se encuentra en todo el procesamiento de imágenes para efectos de escala de grises. float4 grey = dot(float3(0.222, 0.707, 0.071), tex);<br> // devuelve el color del píxel en forma de float4. return grey; }

Aplicaciones de shaders en Source

El motor Source proporciona dos formas separadas de shaders, Postproceso y Por Objeto, la mayoría de los efectos y materiales utilizados en el motor Source dependen en gran medida de sus componentes de Shader de píxeles.

Postproceso

Un shader de postproceso es típicamente un Shader de píxeles que trabaja en un quad renderizado en toda la pantalla. El quad se texturiza con una copia del frame buffer, el Shader de píxeles puede luego alterar y modificar la salida renderizada para crear una variedad de efectos, como la modificación básica del color hasta procesos más avanzados como el motion blur y el bloom.

Note.pngNota: Esta información está desactualizada y los archivos ya no están incluidos en el SDK. 🖿sdk_bloom.cpp y 🖿sdk_bloom.ps20.fxc definen un posible shader que podría usarse como ejemplo alternativo

El Source SDK proporciona un ejemplo de este tipo de shader en los archivos de postproceso (🖿sdk_postprocess.cpp, 🖿sdk_postprocess_vs20.fxc, y 🖿sdk_postprocess_ps20.fxc)

Los shaders de postproceso avanzados, como los shaders de bloom y motion blur incluidos en Source, también pueden necesitar usar Render Targets personalizados. Para obtener más información sobre cómo integrar un shader de postproceso en un mod, consulta Custom Postprocessing Effects

Por objeto

Un shader por objeto en el motor Source se usa en cualquier objeto con el shader referenciado en el archivo Valve Material (.vmt) relevante, como un modelo o pieza de brushwork. Un shader por objeto podría usarse para crear un material refractivo, modificar dinámicamente los vértices de un modelo u otros efectos de renderizado avanzados.

El Source SDK proporciona un ejemplo de un shader por objeto en los archivos de lightmap (🖿sdk_lightmap.cpp, 🖿sdk_lightmap_vs20.fxc, y 🖿sdk_lightmap_ps20.fxc)

Enlaces externos