Shader Based OpenGL Programming

Anuncio
1
Shader Based OpenGL Programming
Juan Garcia 05-30207, Carlos Castillo 04-36817

Resumen— El siguiente informe tiene como objetivo
explicar el uso y la teoría computacional detrás de la
implementación de los Shaders. Trabajamos con Vertex y
Fragments shaders, y se hace énfasis en la ventaja que
tiene este tipo de técnicas de renderizado gráfico con
respecto a otras. Además como se da una pequeña guía de
cómo implantarlos, trabajando sobre un plataforma
Linux, en donde nombramos las diferentes librerías y
métodos existentes para hacer uso en aplicaciones gráficas.
2.0 algunas etapas son programables usando un lenguaje de
programación llamado GLSL.
I. INTRODUCCION
Inicializar el
estado de
OpenGL
l siguiente trabajo quiere explicar el uso de shaders en el
Edesarrollo de aplicaciones graficas en openGL. Partiendo de
la idea de que el proceso de shading fue siempre hecho a
través de las funciones fijas que el lenguaje ofrecía, se ofrece
una nueva solución más que usa shaders definidos
separadamente que trabajando paralelamente en el GPU
(Graphics Processor Unit), permiten hacer un mejor y más
eficiente trabajo de modelado.
El trabajo será dividido en dos partes, dando un
enfoque mas teórico en la primera parte. Se explicaran las
bases de funcionamiento de dichos shaders, y las ventajas que
ofrecen sobre el modelo de desarrollo con funciones fijas del
lenguaje. Ya en una segunda parte se hablara de cómo
implantar dichos shaders en nuestra aplicación openGL,
explicando un poco el lenguaje de shading GLSL, sus tipos de
datos, y aquellas nuevas funciones que nos permitirán integrar
nuestras aplicaciones bases con los distintos shaders.
Configurar y
abrir una
ventana
Procesar
eventos de
usuario
Dibujar una
imagen
III. GLSL - OPENGL SHADING LANGUAGE
II. DESARROLLANDO EN OPENGL
OpenGL está diseñado como una máquina de estados y los
gráficos se generan mediante la computación de una serie de
etapas. Este conjunto de etapas y las conexiones que existen
entre ellas es el llamado pipeline de rendering.
El funcionamiento básico de OpenGL consiste en aceptar
primitivas tales como puntos, líneas y polígonos, y
convertirlas en píxeles. Este proceso es realizado por
una pipeline gráfica conocida como Máquina de estados de
OpenGL. La mayor parte de los comandos de OpenGL bien
emiten primitivas a la pipeline gráfica o bien configuran cómo
la pipeline procesa dichas primitivas. Hasta la aparición de la
versión 2.0 cada etapa de la pipeline ejecutaba una función
prefijada, resultando poco configurable. A partir de la versión
GLSL (OpenGL Shading Language) es un lenguaje de
programación (similar a C/C++) creado por OpenGL ARB
(Architecture Review Board) para crear programas (llamados
shaders) que serán ejecutados en la GPU (Graphics Processing
Unit).
Llamamos Shader de OpenGL a un programa escrito en el
lenguaje GLSL que se puede añadir al pipeline de
procesamiento y permite añadir nuevas funcionalidades.
GLSL permitió utilizar shaders más complejos y de tamaño
variable, subrutinas, ciclos, arreglos de longitud variable, pero
sobre todo un lenguaje de programación más familiar para la
mayoría de los desarrolladores.
La ventaja de usar shaders es la gran mejora en el despeño de
cálculos de iluminación y transformación de geometría. Los
shaders pueden aplicar transformaciones sobre un gran
conjunto de elementos al mismo tiempo. Con shaders es
2
posible crear un modelo de iluminación propio en lugar de
usar el modelo fijado para la iluminación de OpenGL.
Otro gran beneficio de los shaders es que podemos transferir
carga de trabajo, como el movimiento de algunos gráficos, del
CPU al GPU, liberando al CPU para que pueda realizar tareas
adicionales. También es posible manipular sistemas de
partículas, renderizado de alto rango dinámico HDR,
iluminación pixel por pixel, cómputo de propósito general
(GPGPU), etc.
Existen dos tipos de shaders en GLSL: Vertex
Shader y Fragment Shader. Ambos forman parte del pipeline
de rendering de OpenGL.
Los shaders de GLSL no son usos independientes, requieren
un uso que utilice OpenGL
Los shaders son definidos como un arreglo de cadenas. Para
usar un shader, se siguen cuatro pasos:
 Enviar el código del shader a OpenGL
 Compilar el Shader
 Crear un ejecutable (enlazando los vertex y fragment
programs)
Instalar el ejecutables como parte del estado actual de
OpenGL
1) Ejecución



Los datos de los vértices (posición, color,
coordenadas de textura) son cargados en el GPU.
Cada vértice genera una ejecución en el shader.
El shader arroja una posición que va a ser interpolada
por el rasterizador.
Los vertex Shaders se ejecutan en unidades de vértices y esta
opera con los vértices que van llegando y sus datos asociados.
El procesador de vértices suele hacer operaciones gráficas
tradicionales como:
•
•
•
•
•
•
Transformación de los vértices
Transformación de las normales
Generación de las coordenadas de texturas
Transformación de las coordenadas de texturizado
Iluminación
Aplicación de color al material
IV. VERTEX SHADER
Es una herramienta capaz de trabajar con la estructura de
vértices de figuras modeladas en 3D, y realizar operaciones
matemáticas sobre ella para definir colores, texturas e
incidencia de la luz.
Este tipo de shader se ejecuta sobre cada uno de los vértices de
entrada al procesador gráfico. Proporcionan un control general
sobre todos los vértices, sus datos asociados y su
manipulación (transformaciones, normalización, iluminación,
color, etc.). Cuando un conjunto completo de vertex shaders es
compilado y enlazado, se genera un vertex shader
ejecutable que trabaja sobre el procesador de vértices.
Desde otro punto de vista, el vertex shader es un archivo
fuente que contiene el código de entrada para el procesador
gráfico.
El procesador de vértices es una unidad programable que
opera en los vértices y sus datos asociados. Cuando un
conjunto completo de vertex shaders son compilados y
enlazados ellos dan como resultado un vertex shader
ejecutable, que se ejecuta en el vertex processor. El vertex
processor funciona sobre un vértice a la vez. Además, no
sustituye las operaciones gráficas que necesitan el
conocimiento de varios vértices a la vez. El vértice shaders se
ejecuta en el procesador de vértices que debe de calcular la
posición homogénea del próximo vértice.
V. FRAGMENT SHADER
Es un programa ejecutado luego de la rasterización que
permite hacer diversas transformaciones como cambiar la
profundidad o trabajar con texels(es la unidad mínima de
una textura aplicada a una superficie) así como calcular
efectos de iluminación con gran precisión. También es útil
para modificar la profundidad.
Trabaja sobre cada fragmento generado durante el proceso
de rasterización, al igual que el vertex shader permite
manipular vértices, el fragment shader permite manipular
fragmentos (aplicación de texturas, niebla, convoluciones,
etc.). Cuando un conjunto de fragment shaders es compilado,
se genera un fragment shader ejecutable que trabaja sobre el
3
procesador de fragmentos. Un shader de fragmentos no puede
cambiar una posición de algún fragmento, así como tampoco
es permitido el acceso a fragmentos vecinos.
Desde otro punto de vista, el fragment shader es un archivo
que contiene el código fuente que se ejecutará en el
procesador de fragmentos.
En este procesador se pueden hacer diversas transformaciones
como cambiar la profundidad o trabajar con texels así como
calcular efectos de iluminación con gran precisión. Todo lo
ejecutado debe determinar el color que debería aplicarse sobre
el píxel en caso de ser usado. También es útil para modificar la
profundidad.
VI. IMPLEMENTACIÓN DE SHADER
1) Ejecución
Esta función, en OpenGL, la realiza habitualmente lo que se
suele llamar la "fixed functionality". Son los shaders que se
usan internamente por OpenGL cuando no le decimos nada de
shaders.
A partir de ahora podremos modificar esa parte interna de
OpenGL. De hecho la tendencia es a usar cada vez más los
shaders y menos la "fixed functionality".
Las nuevas funciones que vamos a ver son estas:

•
•
•

Los datos de los vértices (posición, color,
coordenadas de textura) son interpolados para

luego formar los fragmentos.
Trabaja sobre cada fragmento generado

(aplicación de texturas, niebla, convoluciones,
etc.).

Cuando un conjunto de fragment shaders es
compilado, se genera un fragment shader
ejecutable que trabaja sobre el procesador de
fragmentos.

Los fragment Shaders se ejecutan en unidades de fragmentos y
estas operan con fragmentos. Las tareas habituales que se
hacen en esta etapa son:
• Operaciones en valores interpolados
• Generar textura de acceso
•
Generar textura de aplicación
• Niebla
• Suma de color
• Pixel zoom
• Escala y sesgo
• Convolución
• Color matrix
El fragment processor es una unidad programable que opera
sobre el fragmento de valores y sus datos asociados. La
compilación y el enlazado de unidades en el fragment
processor dan como resultado fragment shaders que son
ejecutados en el fragment processor. Un fragment shader no
puede cambiar su posición (x,y). El acceso a los fragments
vecinos no está permitido. Los valores usados para el
computado de los fragment shaders son, en última instancia
utilizados para actualizar el frame-buffer de la memoria.
glCreateProgram - Crea un programa al que luego tendremos
que asociar los shaders.
glCreateShader - Crea un shader (vertex o fragment) al que
luego tendremos que pasar el código.
glShaderSource - Pasa al shader el código.
glCompileShader - Compila el código que le hemos pasado al
shader.
glGetShaderInfoLog - Permite obtener la información de la
compilación del shader.
glAttachShader - Asocia un shader a un programa.
glLinkProgram - Enlaza el programa después de asociarle un
vertex y un fragment shader.
glGetProgramInfoLog - Permite obtener la información del
enlace del programa.
glUseProgram - Indica a OpenGL que use un programa para
renderizar (pintar).
En el caso de usar extensiones por ser una versión menor de la
2.0, habría que usar el sufijo ARB en las funciones
y _ARB en las definiciones. Aparte de eso cambian los
nombres de alguna función y los identificadores serán de un
tipo especial en vez de GLuint.
1) Tipos de Datos
Existen vectores de tipos de datos que nos permiten manipular
un conjunto (arreglo) del mismo tipo de dato.
vec2, vec3, vec4
Vectores de flotantes de dos, tres y cuatro entradas
respectivamente.
ivec2, ivec3, ivec4
Vectores de enteros de dos, tres y cuatro entradas
respectivamente.
bvec2, bvec3, bvec4
Vectores de booleanos de dos, tres y cuatro entradas
respectivamente.
mat2, mat3, mat4
4
Matriz de flotantes
respectivamente.
de
2×2,
3×3
y
4×4
2) Instalando y configurando GLSL
Antes de utilizar shaders en GLSL, se deben tener instaladas
algunas bibliotecas que facilitan su desarrollo. Tal es el caso
de GLUT y GLEW.
La instalación de GLUT se puede hacer desde cualquier
administrador de paquetes. Solo basta con instalar:
rendering. El objeto programa contiene tanto al objeto vertex
shader como al objeto fragment shader.
Por ejemplo, lo normal en un juego es cargar varios tipos de
shaders para usarlos en distintas ocasiones, según el objeto a
pintar o cuando pintarlo, o incluso algún shader para algún
efecto especial. A conclusion section is not required. Although
a conclusion may review the main points of the paper, do not
replicate the abstract as the conclusion. A conclusion might
elaborate on the importance of the work or suggest
applications and extensions.
REFERENCES
• freeglut3
• freeglut3-dev
• libglut3
• libglut3-dev
Adicionalmente se deben tener los paquetes virtuales:
•
•
•
•
freeglut-dev
libglut
libglut-dev
libhugs-glut
GLEW proporciona mecanismos eficientes que nos permiten
determinar cuáles extensiones de OpenGL son soportadas por
nuestra plataforma.
Existen pruebas de soporte para comprobar que nuestra
instalación de GLEW y de OpenGL ha sido correcta, así como
para verificar si nuestra plataforma y tarjeta gráfica soportan
los shaders de GLSL.
3) Uso de Shaders
Existen una serie de procesos que se deben hacer para utilizar
un shader:
•
•
•
•
•
•
•
Obtener del código fuente del shader a partir de un
archivo.
Crear los objetos shaders y el objeto programa.
Cargar los objetos shaders con el código leído del
archivo fuente.
Compilar los Objetos Shaders
Adjuntar los shaders al objeto programa.
Ligar el objeto programa con nuestra aplicación.
Indicar a nuestra aplicación que utilice nuestro objeto
programa en lugar de las funciones de OpenGL.
Un objeto shader representa el código fuente, un objeto
programa representa una parte usable del pipeline de
[1] http://unsitioweb.com/videojuegos/125-21-glsl-carga-deshaders
[2] http://www.ubicuos.com/2010/04/08/primeracercamiento-a-shaders-con-glsl/
[3] An Introduction to Shader‐Based OpenGL
Programming
Ed Angel - University of New Mexico
[email protected]
Dave Shreiner- ARM, Inc.
[email protected]
[4] OPENGL 2.0 GLSL SHADERS HOW TO
GNU/LINUX
Descargar