Shaders
Bruno José Dembogurski
Instituto de Computação - UFF
Agenda







Introdução
Shaders
Tipos de dados
Input/Output
Funções e Estruturas de controle
Exemplos e Códigos
Conclusões
Introdução
 Poder da computação gráfica hoje
 GPGPU
 Por que?
Introdução
 Crescimento absurdo no poder de
processamento
 O hardware é relativamente barato
 Flexibilidade
 Como?
Introdução
 JOGOS !
 Industria exige cada vez mais poder
de processamento
 Gera bilhões de dólares por ano
 Incentiva cada vez mais o
desenvolvimento do hardware
 E acaba por baixar o custo
Introdução
 Desde 2000 o poder aplicado ao
processamento de vértices e
fragmentos tem crescido a uma taxa
absurda
Introdução
 GPUs são rápidas...
 3.0 GHz Intel Core2 Duo (WoodCrest
Xeon 5160)
 Poder: 48 GFLOPS – pico
 Memory Bandwidth: 21GB/s – pico
 Preço: 874 dólares
 NVIDIA GeForce 8800GTX:
 Poder: 330 GFLOPS
 Memory Bandwidth: 55.2 GB/s
 Preço: 599 dólares
Introdução
 “NVIDIA Tesla Computing Solutions
now with the world's first teraflop
parallel processor “
Introdução
Introdução
Graphics State
GPU
Shade
Final Pixels (Color, Depth)
Rasterize
Fragments (pre-pixels)
Assemble
Primitives
Screenspace triangles (2D)
Transform
& Light
Xformed, Lit Vertices (2D)
CPU
Vertices (3D)
Application
Video
Memory
(Textures)
Render-to-texture
 Versão simplificada da pipeline
Introdução
Graphics State
 Processador de
Vértices
Programável
GPU
Fragment
Shade
Processor
Final Pixels (Color, Depth)
CPU
Rasterize
Fragments (pre-pixels)
Assemble
Primitives
Screenspace triangles (2D)
Vertex
Transform
Processor
& Light
Xformed, Lit Vertices (2D)
Vertices (3D)
Application
Video
Memory
(Textures)
Render-to-texture
 Processador de
fragmentos
Programável
Introdução
Graphics State
GPU
Fragment
Processor
Final Pixels (Color, Depth)
 Geração de
geometria
programável
Rasterize
Fragments (pre-pixels)
CPU
Geometry
Assemble
Processor
Primitives
Screenspace triangles (2D)
Vertex
Processor
Xformed, Lit Vertices (2D)
Vertices (3D)
Application
Video
Memory
(Textures)
Render-to-texture
 Acesso a
memória mais
flexivel
Shaders
 Shaders são programas que
executam em determinadas etapas
da pipeline
 Não são aplicações stand-alone
 Necessitam de uma aplicação que
utilize um API (OpenGL ou Direct3D)
Shaders
 No caso:
 Vertex shader – Vertex Processor
 Fragment shader – Fragment Processor
 Geometry shader – Geometry Processor
Shaders
 Vertex Processor
 Transforma do espaço de mundo para o
espaço de tela
 Calcula iluminação per-vertex
Shaders
 Geometry Processor
 Como os vértices se conectam para
formar a geometria
 Operações por primitiva
Shaders
 Fragment Processor
 Calcula a cor de cada pixel
 Obtém cores de texturas
Shaders
 Hoje temos que a programação de
shaders é feita em linguagens de alto
nível
 No estilo de c/c++
 As principais que temos hoje:
 GLSL – OpenGL Shader Language
 HLSL – High Level Shader Language
 Cg – C for Graphics
Shaders
 Temos algumas ferramentas que
servem tanto para criação e edição de
shaders:
 NVIDIA FX Composer 2.5
 RenderMonkey ATI
Shaders
Shaders
Shaders
Tipos de dados
 Estruturas bem intuitivas
 Vetores:
 vec2, vec3 e vec4 – floating point
 ivec2, ivec3 e ivec4 – interger
 bvec2, bvec3 e bvec4 – boolean
 Matrizes
 mat2, mat3 e mat4 – floating point
Tipos de dados
 Texturas
 Sampler1D, Sampler2D, Sampler3D texturas 1D, 2D e 3D
 SamplerCube – Cube map textures
 Sampler1Dshadow, Sampler2DShadow –
mapa de profundidade 1D e 2D
Input/Output
 Existem 3 tipos de input em um
shader:
 Uniforms
 Varyings
 Attributes
Input/Output
 Uniforms
 Não mudam durante o rendering
 Ex: Posição da luz ou cor da luz
 Esta presente em todos os tipos de
shader
 Varyings
 Usando para passar dados do vertex
shader para o fragment shader ou
geometry shader
Input/Output
 Varyings
 São read-only no fragment e geometry
shader mas read/write no vertex shader
 Para usar deve-se declarar a mesma
varying em todos os programas
 Attributes
 Estão presentes apenas nos Vertex
shaders
 São valores de input mudam em cada
vertice
Input/Output
 Attributes
 Ex: Posição do vértice ou normais
 São apenas read-only
Input/Output
 Exemplos de Input Attibutes no
vertex shader




gl_Vertex – vetor 4D, posição do vértice
gl_Normal – vetor 3D, Normal do vértice
gl_Color – vetor 4D, cor do vértice
gl_MultiTexCoordX – vetor 4D,
coordenada de textura na unit X
 Existem vários outros atributos
Input/Output
 Exemplos de Uniforms
 gl_ModelViewMatrix
 gl_ModelViewProjectionMatrix
 gl_NormalMatrix
Input/Output
 Exemplos de Varyings
 gl_FrontColor - vetor 4D com a cor
frontal das primitivas
 gl_BackColor – vetor 4D com a cor de
trás das primitivas
 gl_TexCoord[N] – vetor 4D
representando a n-ésima coordenada de
textura
Input/Output
 Exemplos de output:
 gl_Position – vetor 4D representando a
posição final do vértice
 gl_FragColor – vetor 4D representando a
cor final que será escrita no frame buffer
 gl_FragDepth – float representando o
depth que será escrito do depth buffer
Input/Output
 Também é possível definir attributes,
Uniforms e varyings
 Ex: Passar um vetor tangente 3D por
todos os vértices da sua aplicação
 É possível especificar o atributo
“tangente”
 attribute vec3 tangente;
Input/Output
 Alguns outros exemplos:




uniform sampler2D my_color_texture;
varying vec3 vertex_to_light_vector;
varying vec3 vertex_to_eye_vector;
attribute vec3 binormal;
Funções e Estruturas de Controle
 Similar a linguagem C
 Suporta estruturas de loop e decisão





If/else
For
Do/while
Break
Continue
Funções e Estruturas de Controle
 Possui funções como:







Seno (sin)
Cosseno (cos)
Tangente (tan)
Potencia (pow)
Logaritmo (log)
Logaritmo (log2)
Raiz (sqrt)
Exemplos e Códigos
 Antes de criar os shaders mesmo
temo que definir uma função (no caso
de GLSL) para carregar e enviar os
shaders para o hardware
 Esta função já é bem difundida e fácil
de encontrar e manipular
Exemplos e Códigos
void setShaders()
free(vs);free(fs);
char *vs = NULL,*fs = NULL,*fs2 = NULL;
glCompileShader(v);
glCompileShader(f);
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("minimal.vert");
fs = textFileRead("minimal.frag");
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
glUseProgram(p);
Exemplos e Códigos
 O código shader mais simples (Estilo
Hello World)
 Vertex Shader
void main()
{
gl_Position = ftransform();
}
Exemplos e Códigos
 O código shader mais simples (Estilo
Hello World)
 Fragment Shader
void main()
{
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}
Exemplos e Códigos
 Resultado:
Exemplos e Códigos
 Toon shading
 Vertex shader
varying vec3 normal;
void main()
{
normal = gl_Normal; gl_Position = ftransform();
}
Exemplos e Códigos
 Toon shading
 Fragment shader
uniform vec3 lightDir;
varying vec3 normal;
void main()
{
float intensity;
vec4 color; intensity = dot(lightDir,normalize(normal));
if (intensity > 0.95)
color = vec4(1.0,0.5,0.5,1.0);
else if (intensity > 0.5)
color = vec4(0.6,0.3,0.3,1.0);
else if (intensity > 0.25)
color = vec4(0.4,0.2,0.2,1.0);
else
color = vec4(0.2,0.1,0.1,1.0);
}
gl_FragColor = color;
Exemplos e Códigos
 Toon shading
Exemplos e Códigos
 Mexendo na geometria
 Shader achatar o modelo 3D, ou seja,
z=0
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = 0.0;
gl_Position =
gl_ModelViewProjectionMatrix * v;
}
Exemplos e Códigos
 Resultados
Exemplos e Códigos
 Distorcendo ainda mais a geometria
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = sin(5.0*v.x )*0.25;
gl_Position =
gl_ModelViewProjectionMatrix * v;
}
Exemplos e Códigos
 Resultados
Exemplos e Códigos
 É possível fazer uma animação com
os vértices
 Para isso precisamos de uma variável
que mantenha a passagem do tempo
ou dos frames
 Não temos como fazer isso no vertex
shader, logo temos que definir essa
variável na aplicação OpenGL
Exemplos e Códigos
 E passar para o shader na forma de
uma variável Uniform
uniform float time;
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = sin(5.0*v.x + time*0.01)*0.25;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
Exemplos e Códigos

No caso a função de render ficaria:
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0, 0.0,0.0,0.0, 0.0f,1.0f,0.0f);
glUniform1fARB(loc, time);
glutSolidTeapot(1);
time+=0.01;
}
glutSwapBuffers();
Exemplos e Códigos
 Vídeo
Exemplos e Códigos
 Texturing
 GLSL tem que ter acesso as coordenadas
de textura por vértice
 GLSL provê variáveis do tipo Attribute,
para cada unidade de textura (max 8)
 attribute vec4 gl_MultiTexCoord0..8
Exemplos e Códigos
 Texturing
 Precisa calcular a coordenada de textura
 Armazenar em uma variável varying
gl_TexCoord[i] onde i é a unidade de
textura utilizada
 gl_TexCoord[0] = gl_MultiTexCoord0;
Exemplos e Códigos
 Texturing
 Um simples código para definir
coordenadas de textura para uma
textura utilizando a unit 0
 Vertex Shader
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
Exemplos e Códigos
 Texturing
 gl_TexCoord é uma variável varying
 Será utilizada no fragment shader para
acessar as coordenadas de textura
interpoladas
 Para acessar os valores de textura temos
que declarar uma variável do tipo
uniform no fragment shader
 Para uma textura 2D temos:
 uniform sampler2D tex;
Exemplos e Códigos
 Texturing
 A função que nos retorna um textel é a
texture2D
 Os valores retornados levam em
consideração todos as definições de
textura feitos no OpenGL (filtering,
mipmap, clamp, etc)
Exemplos e Códigos
 Texturing
 O fragment shader ficaria assim:
uniform sampler2D tex;
Void main()
{
vec4 color =
texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color;
}
Exemplos e Códigos
 Texturing
 São necessárias algumas inicializações na aplicação
para que o shader possa utilizar a textura
glActivateTexture(GL_TEXTUREi) onde i = 0..8
glGenTextures(1, &Textura);
glBindTexture(GL_TEXTURE_2D, Textura);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, level, format, Width, Height, 0,
GL_RGB,GL_UNSIGNED_BYTE, TexureInfo);
Exemplos e Códigos
 Texturing
glEnable (GL_TEXTURE_2D);
glBegin(GLenum Mode);
.
.
.
glEnd();
glDisable (GL_TEXTURE_2D);
Exemplos e Códigos
 Bump Mapping

Segue as mesmas idéias vistas
Vertex shader
uniform
uniform
uniform
uniform
uniform
mat4 view_matrix;
mat4 inv_view_matrix;
vec4 view_position;
vec4 light_position;
vec4 lightDir;
attribute vec3 rm_Tangent;
attribute vec3 rm_Binormal;
varying
varying
varying
varying
vec2
vec3
vec3
vec3
vTexCoord;
vLightVector;
vHalfAngle;
vNormal;
Exemplos e Códigos
 Bump Mapping
void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec4 eye_position = gl_ModelViewMatrix * gl_Vertex;
//**---------------------------------------------//** Passa as coordenadas de textura
//**---------------------------------------------vTexCoord = vec2(gl_MultiTexCoord0);
Exemplos e Códigos
 Bump Mapping
//**---------------------------------------------//** Espaço tangente
//**---------------------------------------------vec3 tangent = vec3( rm_Tangent.x, rm_Tangent.y,
rm_Tangent.z);
vec3 normal = vec3( gl_Normal.x, gl_Normal.y,
gl_Normal.z);
vec3 binormal = vec3(rm_Binormal.x, rm_Binormal.y,
rm_Binormal.z);
Exemplos e Códigos
 Bump Mapping
//**-------------------------------------------//** Calcula o vetor de iluminação no espaço de câmera,
//** transforma para o espaço tangente.
//**-------------------------------------------vec3 temp_light_position = vec3( vec4(light_position.x,
light_position.y, -light_position.z, light_position.w) *
inv_view_matrix);
vec3 temp_light_vector
gl_Vertex.xyz;
= temp_light_position.xyz -
vLightVector.x = dot( temp_light_vector, tangent );
vLightVector.y = dot( temp_light_vector, binormal );
vLightVector.z = dot( temp_light_vector, normal );
Exemplos e Códigos
 Bump Mapping
//**------------------------------------------//**Mesma coisa para o view vector
//**------------------------------------------vec4 oglEyePos = eye_position;
oglEyePos.z = -oglEyePos.z;
vec3 temp_eye_position = vec3( oglEyePos * inv_view_matrix) ;
vec3 temp_view_vector = temp_eye_position - gl_Vertex.xyz;
vec3 temp_view_vector2;
temp_view_vector2.x = dot( temp_view_vector, tangent );
temp_view_vector2.y = dot( temp_view_vector, binormal );
temp_view_vector2.z = dot( temp_view_vector, normal );
Exemplos e Códigos
 Bump Mapping
 Fragment Shader
uniform float Kd;
uniform float Ka;
uniform vec4 diffuse;
uniform vec4 ambient;
uniform float Ks;
uniform vec4 specular;
uniform float
specular_power;
uniform float reflectance;
uniform float bumpiness;
uniform mat4 view_matrix;
uniform samplerCube
environment_map;
uniform sampler2D bump_map;
uniform sampler2D base_map;
varying vec2 vTexCoord;
varying vec3 vLightVector;
varying vec3 vHalfAngle;
Exemplos e Códigos
 Bump Mapping
void main(void)
{
//**-----------------------------------------------------//** Pega os componente de cor e bump das texturas
//** baseadas nas coordenadas passadas
//**-----------------------------------------------------vec3 base = texture2D( base_map, vTexCoord ).xyz;
vec3 bump = texture2D( bump_map, vTexCoord ).xyz;
Exemplos e Códigos
 Bump Mapping
//**---------------------------------------------------//** Normaliza os vetores passados pelo vertex shader
//**---------------------------------------------------vec3 normalized_light_vector = normalize( vLightVector );
vec3 normalized_half_angle = normalize( vHalfAngle );
//**---------------------------------------------------//** Suaviza os niveis de bump
//**---------------------------------------------------vec3 smooth = vec3(0.5, 0.5, 1.0);
bump = mix( smooth, bump, bumpiness );
bump = normalize( ( bump * 2.0 ) - 1.0 );
Exemplos e Códigos
 Bump Mapping
//**-------------------------------------------------------//** Modelo de iluminação
//** NxL – Normal x vetor da luz
//** NxH – Normal x Half Vector
//**-------------------------------------------------------vec3 n_dot_l = vec3(dot( bump, normalized_light_vector ));
vec3 n_dot_h = vec3(dot( bump, normalized_half_angle ));
Exemplos e Códigos
 Bump Mapping
//**-------------------------------------//** Calcula a cor resultante,
//** baseado no modelo de iluminação.
//** Ambient + Diffuse + Specular
//**-------------------------------------vec3 color0 = ( base * ambient.xyz * Ka ) +
( base * diffuse.xyz * Kd * max( vec3(0.0), n_dot_l ) ) +
( specular.xyz * Ks * pow( max( vec3(0.0), n_dot_h ),
vec3(specular_power) ));
Exemplos e Códigos
 Bump Mapping
float color0_a = 1.0; //** Define o alfa
gl_FragColor = vec4(color0.xyz, color0_a); //** retorna a cor
Exemplos e Códigos
 Bump Mapping
Conclusões
 Apenas um introdução
 Existem muitas outras utilidades para
os shaders
 Muitos outros efeitos que podem ser
criados
Conclusões
Conclusões
Conclusões
Conclusões
Conclusões
Conclusões
 Gears of War Video
 GRID Video
Referencias




GLSL Quick Guide
NeHe Produtions
Wiki GLSL
LightHouse
Download

Bump Mapping