Upload
lydia-mccoy
View
42
Download
3
Embed Size (px)
DESCRIPTION
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. - PowerPoint PPT Presentation
Citation preview
Shaders
Bruno José DembogurskiInstituto 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
Versão simplificada da pipelineGPUCPU
Application Transform& Light Rasterize Shade Video
Memory(Textures)
Xformed, Lit Vertices
(2D)
Graphics State
Render-to-texture
AssemblePrimitives
Vertices (3D)
Screenspace triangles (2D)
Fragments (pre-pixels)
Final Pixels (Color, Depth)
Introdução
Processador deVértices Programável
GPU
Transform& Light
CPU
Application Rasterize Shade VideoMemory
(Textures)
Xformed, Lit Vertices
(2D)
Graphics State
Render-to-texture
AssemblePrimitives
Vertices (3D)
Screenspace triangles (2D)
Fragments (pre-pixels)
Final Pixels (Color, Depth)
FragmentProcessor
VertexProcessor
Processador defragmentosProgramável
Introdução
Geração de geometria programável
GPUCPU
Application VertexProcessor Rasterize Fragment
ProcessorVideo
Memory(Textures)
Xformed, Lit Vertices
(2D)
Graphics State
Render-to-texture
Vertices (3D)
Screenspace triangles (2D)
Fragments (pre-pixels)
Final Pixels (Color, Depth)
AssemblePrimitives
GeometryProcessor
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ódigosvoid setShaders()
char *vs = NULL,*fs = NULL,*fs2 = NULL;
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);
free(vs);free(fs);
glCompileShader(v);glCompileShader(f);
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 shadervarying vec3 normal;
void main(){
normal = gl_Normal; gl_Position = ftransform();}
Exemplos e Códigos Toon shading
Fragment shaderuniform 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 = 0void 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 Uniformuniform 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 texturaglActivateTexture(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 vistasVertex shader
uniform mat4 view_matrix;uniform mat4 inv_view_matrix;uniform vec4 view_position;uniform vec4 light_position;uniform vec4 lightDir;
attribute vec3 rm_Tangent; attribute vec3 rm_Binormal;
varying vec2 vTexCoord;varying vec3 vLightVector;varying vec3 vHalfAngle; varying vec3 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 = temp_light_position.xyz - gl_Vertex.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
uniform samplerCubeenvironment_map;uniform sampler2D bump_map;uniform sampler2D base_map;varying vec2 vTexCoord;varying vec3 vLightVector;varying vec3 vHalfAngle;
Bump Mapping Fragment Shaderuniform 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;
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