800 likes | 920 Views
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.
E N D
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 • Versão simplificada da pipeline CPU GPU Graphics State Xformed, Lit Vertices (2D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth) Application Transform& Light AssemblePrimitives Rasterize Shade Vertices (3D) VideoMemory(Textures) Render-to-texture
Introdução • Processador de Vértices Programável CPU GPU Graphics State VertexProcessor FragmentProcessor Xformed, Lit Vertices (2D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth) Application Transform& Light AssemblePrimitives Rasterize Shade Vertices (3D) VideoMemory(Textures) Render-to-texture • Processador de fragmentos Programável
Introdução • Geração de geometria programável CPU GPU Graphics State GeometryProcessor Xformed, Lit Vertices (2D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth) Application VertexProcessor AssemblePrimitives Rasterize FragmentProcessor Vertices (3D) VideoMemory(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 deuma 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
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() 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 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; }