Real_Time_Shading_Languages

Anuncio
1
Eduardo Cortejoso 04-36867, Jormar Arellano 05-37840
Real Time Shading Languages
Resumen (Abstract)— Se tratan dos temas principales, los
Shaders y los Real Time Shading Languages. Los Real Time
shading Languages implementan los distintos tipos de shader
para aprovechar al maximo los beneficios de cada uno. Pasaremos
a explicar que son cada uno de estos conceptos y como se
relacionan.
Palabras clave— Shader, Real Time Shading, Pixel Shader,
Geometry Shader, Vertex Shader
I.
INTRODUCCIÓN
L
OS Real Time Shading Languages son una
herramienta sumamente imporante para generar una
buena calidad de imagen a tiempo real. Cabe destacar que al
renderizar una imagen en tiempo real, tenemos que considerar
el tiempo y costo que pueden tener las implementaciones de
estos lenguajes y sus shaders respectivos. Es importante
analizar como cada Lenguaje implementa los distintos tipos de
shader, como aprovechan sus beneficios y como trabajan entre
ellos.
II. REAL TIME SHADING LANGUAGES
Esta es la categoría de lenguajes que se usan para crear los
Shaders. Existe una variedad de estos lenguejes, pero en
nuestro estudio nos enfocaremos en los 3 más importantes:
GLSL (para openGL), HLSL (Desarrollado por Microsoft), y
Cg (Desaollado por NVIDIA).
Independientemente del lenguaje que utilicemos al momento
de crear Shaders, hay que tener en mente varias cosas:
1. El lenguaje provee, por defecto, acceso a las propiedades
establecidas por el usuario (texturas, luces, etc…), y lo
hace a través de variables. Estas variables son de solo
lectura.
2. Independientemente del lenguaje que se este usando, hay
propiedades que no son modificables desde los Shaders
(texturas, fuentes de luz, matriz de proyección, matriz de
normales, etc…).
3. El lenguaje provee un mecanismo especial para la
intercomunicación entre los Shaders.
Las diferencias entre un lenguaje y otro está en los detalles
sintácticos, y en el alcance del lenguaje. De esto hablaremos
más adelante.
III. GLSL
GLSL es el acrónimo para OpenGL Shading Language.
También conocido como GLslang, GLSL es un lenguaje de
código abierto basado en C/C++, que permite modificar
directamente el pipeline del procesamiento gráfico (por medio
de Shaders).
En nuestro estudio, este fue el lenguaje que tomamos como
referencia principal ilustrar los pasos a seguir para crea un
Shader.
Algunos de los beneficios de este GLSL son:
Soporte multiplataforma, y compactibilidad en múltiples
sistemas operativos, incluyendo mac OS, Windows, y
Linux.
Los Shaders escritos en este lenguaje pueden ser usados en
cualquier trajea de video, independientemente del
vendedor.
Es posible generar código optimizado para la arquitecura
de una tarjeta gráfica en particular en particular, ya que
cada vendedor provee, un driver que incluye el compilador
de GLSL.
A. Tipos de datos en GLSL
Hay 3 tipo de datos primitivos convencionales: float, int, bool.
Para todos estos, disponemos de unos ipos particulares para
manipular vectores (de 2, 3, y cuatro dimensiones,
respectivamente):
vec2, vec3, vec4
vector de float
ivec2, ivec3, ivec4
vector de int
bvec2, bvec3, bvec4
vector de bool
En particular, para los float tenemos un tipo especial para
manejar matrices de 2x2, 3x3, y 4x4, respectivamente:
mat2, mat3, mat4
Samplers son tipos especiales para representar texturas, y
hacer “texture sampling”. Este tipo de variables siempre es
uniform, es decir, no cambia dentro de la ejecución de un
Shader. Los tipos de samplers disponibles son: sampler1D,
sampler2D, sampler3D (para texturas de 1, 2 y 3 dimensiones),
entre otros…
Modificadores de variables
Sirven para determinar las salidas y entradas de un Shader. En
escencia, determinan el comportamiento de una variable
dentro
de
un
Shader.
Son
tres:
Uniforms: son valores que no camian durante el rendering
(posición ó color de la luz, texturas, etc…)
Este tipo de variable es de solo lectura, y esta disponible en
cualquier shader (Vertex, Geometric y Fragment).
Attributes: Disponibles solo en el Vertex Shader. Son variables
2
que contienen toda la información referente a un vertice:
posición, normal, color, etc. Son de solo lectura.
Varyings: Sirven de puente para comunicar un Vertex Shader
conun Fragment Shader. Estas variables son interpoladas entre
las primitivas, y no se puede modificar su valor en el Fragment
Shader. Para usarla, hay que declararla como variable global
en el código fuente de ambos Shaders.
Algunas variables uniformes predefinidas:
gl_ModelViewMatrix,
gl_ModelViewProjectionMatrix,
gl_NormalMatrix
Algunos variables attributes predefinidas (representan una
propiedad de un vertice)
gl_Vertex (posición), gl_Normal (vector normal), gl_Color
(color).
Algunas variables “Varyings” predefinidas:
gl_FrontColor, gl_BackColor
Si, en lugar de establecer la componente z a cero, usamos una
función seno respecto a x tendríamos:
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = sin(5.0*v.x )*0.25;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
El lenguaje también proporciona algunas funciones
predefinidas, a fin de agilizar operaciones comunes con
vecores y matrices. Por ejemplo: dot (producto punto), cross
(producto cruz) , normalize (normaliza un vector).
B. Vertex Shader en GLSL
Cuando estamos escribiendo un Vertex Shader, debemos, por
lo menos, establecer el valor de la variable predefinida
gl_Position (vector de 4 dimensiones), la cual indica la
posición de ese vértice en el espacio.
En el siguiente ejemplo, modificamos directamente la posición
de un vértice (exactamente, establecemos la componente z en
cero).
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = 0.0;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
El resultado (visto desde varios angulos):
C. Fragment Shader en GLSL
Cuando estamos escribiendo un Fragment Shader, debemos,
por lo menos, establecer el valor de la variable predefinida
gl_FragColor (vector de 4 dimensiones), la cual indica el
color final de ese pixel, que va a parar al frame buffer.
Como ejemplo, tenemos este trivial fragment Shader:
void main(void)
{
gl_FragColor = vec4(0.9, 0.2, 0.2, 1.0);
}
Que da como resultado que todos los píxeles se pinen de un
tono rojizo.
D. Geometric Shader
Los geometric Shader estan entre el Vertex Shader, y el
Fragment Shader. Tienen la habilidad de crear nuevos vértices,
y cambiar la geometría a partir de la ya exsitente.
3
void main(void)
{
int i;
for(i=0; i< gl_VerticesIn; i++){
gl_Position = gl_PositionIn[i];
EmitVertex();
}
EndPrimitive();
};
void main( in a2v IN, out v2p OUT )
{
OUT.Position = mul(IN.Position, ModelViewMatrix);
OUT.Color = IN.Color;
}
B. Pixel Shader
//New piece of geometry! We just swizzle the x and y terms
for(i=0; i< gl_VerticesIn; i++){
gl_Position = gl_PositionIn[i];
gl_Position.xy = gl_Position.yx;
EmitVertex();
}
eNdPrimitive();
}
IV. HLSL
Acrónimo para High Level Shading Language, HLSL es un
lenguaje desarrllado por Microsoft para usarlo con el API de
Direct3D de Microsoft. Es análogo a GLSL en cuanto a
funcionalidad, variando sólo en las características propias del
lenguaje.
Para comenzar, HLSL también posee tipos de datos especiales
para denotar vectores y matrices. En ese aspecto, es más
flexible que GLSL, ya que aca si se pueden usar matrices que
no sean cuadradas: 4x3, 2x3, etc. También posee tipos
particulares para manejar texturas.
La forma de crear Shader es ligeramente diferente que en
GLSL, ya que eneste lenguaje, se deben definir las estucturas
de entrada y salida, para Shader, y usarlas en la declaración del
main en el programa principal de un Shader.
A. Vertex Shader
Aca vemos un ejemplo:
float4x4 ModelViewMatrix;
/*
* Estructura de entrada. Es lo que espera el Vertex Shader
*/
struct a2v {
float4 Position : POSITION;
float4 Color : COLOR0;
};
/*
* Estructura de salida. Es lo que el Vertex Shader le pasa al
Fragment Shader
*/
struct v2p {
float4 Position : POSITION;
float4 Color : COLOR0;
float brightness;
sampler2D tex0;
sampler2D tex1;
/*
* Estructura de entrada. Es lo que el Pixel Shader espera del
Vertex Shader
*/
struct v2p {
float4 Position : POSITION;
float2 Texcoord0 : TEXCOORD0;
float2 Texcoord1 : TEXCOORD1;
float4 Color : COLOR0;
};
struct p2f {
float4 Color : COLOR0;
};
void main( in v2p IN, out p2f OUT )
{
float4 color = tex2D(tex0, IN.Texcoord0);
float4 bump = tex2D(tex1, IN.Texcoord1);
OUT.Color = brightness * IN.Color * color;
}
V. CG
Este es un Shading language desarrollado por Nvidia, en
colaboración con Microsoft. Por esto ultimo, es
extremadamente similar al lenguaje HLSL. Por consiguiente,
hereda muchas de las características sintácticas de HLSL,
mientras que ofrece un mayor desempaño para las tarjetas
Nvidia.
Su diferencia principal radica en que este lenguaje puede ser
compilado para diferentes tarjetas de video, brindando asi la
posibilidad de compilar, el mismo código fuente, para openGL
ó DirectX.
La forma de elaborar un Shader es similar a HLSL, por lo que
pasaremos a discutir algunas características de este lenguaje en
particular.
A. Características del lenguaje
4
CG proporciona las estructuras y los arreglos, incluyendo
matrices multidimensionales. También proporciona todos los
operadores aritméticos de C (, *, /, etc.), un tipo booleano y los
operadores
booleanos
y
relacionales
(|
|,
&&, !) . También posee el famoso operador ternario de los
lenguajes de programación (?:).
El usuario puede definir sus propias funciones (aunque no
pueden definirse funciones recursivas). Cg proporciona un
subconjunto de control de flujo de las construcciones C (do,
while, for, if, break, continue)… otras construcciones como
GOTO no se admiten en la aplicación actual del CG actual
sino que se reservan las palabras clave necesarias.
Al momento de compilar un programa en Cg, uno escoge el
perfil que desea para dicha compilación; es decir, se especifica
si se compila un Vertex Shader, un Geometric Shader, o un
Fragment Shader.
Al igual que C, Cg no obliga a la precisión y el alcance de sus
datos tipos. En la práctica, el perfil elegido para la
compilación determina la la representación concreta para cada
tipo de datos. float, half, y double pretenden representar
valores continuos. Int es un entero tipo de datos, normalmente
se usa para recorrer e indexación. CG proporciona # include, #
define, # ifdef, etc emparejar la C preprocesador. También se
soporta la sobrecarga de funciones.
Los tipos especiales de Cg para manejar vectores y matrices,
son los mismos que HLSH. Por ejemplo,
float4 vec1 = float4(4.0, -2.0, 5.0, 3.0);
…declara un vector de 4 dimensiones. El lenguaje provee una
librería estandar para manipular operaciones comunes entre
vectores y matrices
VI. CONCLUSIONES
Existen tres lenguajes principales para programar directamente
en un GPU: GLSL (openGL), HLSL (para DirectX),y Cg
(Nvidia). Sin importar que tipo de Shader se quiera crear,
debemos de usar alguno de estos tres lenguajes.
A la hora de elegir un lenguaje en concreto, lo más importante
es tener claro cual es la plataforma objetivo del programa, y
con que tecnologías contamos. GLSL y Cg son lenguajes
bastante adaptables en cualquier plataforma (soporte para
Windows, linux y mac OS), mientras que HLSL sólo tiene
soporte en Windows.
GLSL es un lenguaje que esta soportado por casi todos los
proveedores de tarjetas graficas, los cuales incluyen en sus
drivers un compilador para dicho lenguaje, logrando
optimizaciones particulares para hardware particulares.
HLSL esta estrechamente ligado con DirectX , y Window.
Algunas consolas de videojuegos (como la X-Box) son
compatibles con este lenguaje. Este lenguaje es mucho más
flexible, sintácticamente hablando, que GLSL, ya que ofrece
dimensiones de matrices variadas (en GLSL todas las matrices
son cuadradas), y algunos alegan que a la hora de escribir un
Shader en particular, quedan mucho más claros los parámetros
de entrada y salida del mismo.
Cg es un lenguaje más neutral. Si bien es extremadamente
similar a HLSL, permite ser compilado para Nvidia y DirectX.
Ofrece compactibilidad con múltiples APIs (OpenGL, DirectX
8 y DirectX 9). Más aún, el compilador puede ser configurado
para que genere el lenguaje ensamblador compactible con el
estandar de openGL, permitiendo optimizar manualmente los
aspectos que se consideren necesarios.
Ninguno de estos lenguajes pretende reemplazar a cualquier
otro de propósito general. Ciertamente, son lenguajes
especializados en el área, que persiguen los mismos objetivos
y tienen el mismo alcance, algunos dotados de optimizaciones
para tecnologías específicas, estableciendo cada uno una
metodología diferente para alcanzar la meta, los Shaders.
VII. REFERENCES
http://en.wikipedia.org/wiki/GLSL
http://en.wikipedia.org/wiki/Cg_%28programming_language%
29
http://nehe.gamedev.net/data/articles/article.asp?article=21
http://cirl.missouri.edu/gpu/glsl_lessons/glsl_geometry_shader
/index.html
http://www.gamedev.net/columns/hardcore/dxshader1/
http://www.gamedev.net/columns/hardcore/dxshader2/
http://www.gamedev.net/columns/hardcore/dxshader3/
http://www.gamedev.net/columns/hardcore/dxshader4/
Descargar