Computação Gráfica. GLSL - Programação de Shaders Iluminação



Documentos relacionados
Computação Gráfica. GLSL - Programação de Shaders Iluminação

Computação Gráfica. GLSL Programação de Shaders

GLSL Programação de Shaders

OpenGL Shading Language

Computação Gráfica. GLSL - Programação de Shaders Toon Mapping; Texturas

Animação e Visualização Tridimensional

Prof. Fernando V. Paulovich 16 de maio de SCC Computação Gráca

Modelos de Iluminação Métodos de surface-rendering

Iluminando o Cenário

Modelos de Iluminação Locais

Iluminação e sombreamento

Modelos de Iluminação e Reflexão

Cap. 7 Coloração (Shading) e Iluminação Global

Paulo Sérgio Rodrigues. Exercícios de Laboratório

Introdução à Programação. Armazenamento de Grande Quantidade de Informação Usando Vetores

1. Evolução do OpenGL

8. Síntese de Imagens: Cálculo de Cor

FCG2006 Prova sobre OpenGL e Rastreamento de Raios

Computação Gráfica. Iluminação

Computação Gráfica. Iluminação

INSTITUTO TECNOLÓGICO

Fundamentos de Computação Gráfica. Iluminação

Sistemas de Apoio à Decisão

Apontamentos de Computação Gráfica

Busca em Memória. Secundária

Programação Engenharia Informática (11543) 1º ano, 1º semestre Tecnologias e Sistemas de Informação (6619) 1º ano, 1º semestre

INTRODUÇÃO À LINGUAGEM C++

MATEMÁTICA GEOMETRIA ANALÍTICA I PROF. Diomedes. E2) Sabendo que a distância entre os pontos A e B é igual a 6, calcule a abscissa m do ponto B.

Universidade de Brasília Instituto de Ciências Exatas Departamento de Ciência da Computação. Shader Não Fotorrealístico para Desenho de Mangás

Tipo de Dados em Linguagem C

Equações Diferenciais Ordinárias

Computação Gráfica. Modelo de sombreamento Determina como o modelo de iluminação será aplicado e quais seus argumentos

Programação: Estruturas de seleção

Truques e Dicas. = 7 30 Para multiplicar fracções basta multiplicar os numeradores e os denominadores: 2 30 = 12 5

Modelos de Iluminação Métodos de surface-rendering. Beatriz Sousa Santos, J. Madeira

14.1 Vetor - Problemas

Computação Gráfica - 13

Computação Gráfica. GLSL - Introdução e Programação da Aplicação OpenGL

Instituto Superior Técnico Departamento de Matemática Última actualização: 11/Dez/2003 ÁLGEBRA LINEAR A

Computação Gráfica. Renderização em Tempo Real. Erivaldo Xavier de Lima Filho

Programação por Objectos. Java

Iluminação (lighting) e Sombreamento (shading)

Notas sobre a Fórmula de Taylor e o estudo de extremos

1. Fazer um programa em C que pergunta um valor em metros e imprime o correspondente em decímetros, centímetros e milímetros.

9 Comandos condicionais

7. Estrutura de Decisão

CG 2013/2014 Primeiro Teste LEIC Alameda/Taguspark

Problema. Conversão Matricial. Octantes do Sistema de Coordenadas Euclidiano. Sistema de Coordenadas do Dispositivo. Maria Cristina F.

Estrutura Condicional em Java

Algoritmos e Programação

Exercícios de Revisão Java Básico

Classificação da imagem (ou reconhecimento de padrões): objectivos Métodos de reconhecimento de padrões

Preenchimento de Áreas e de Polígonos. Antonio L. Bajuelos Departamento de Matemática Universidade de Aveiro

Projeções e Visualização

Luiz Gonzaga da Silveira Jr

Linguagens de Programação

Programação. MEAer. Bertinho Andrade da Costa. Instituto Superior Técnico. Introdução ao Pré-Processador. 2011/2012 1º Semestre

Exercícios 1. Determinar x de modo que a matriz

Técnicas de Computação Paralela Capítulo III Design de Algoritmos Paralelos

Cálculo em Computadores trajectórias 1. Trajectórias Planas. 1 Trajectórias. 4.3 exercícios Coordenadas polares 5

Estrutura de Dados Básica

Universidade da Beira Interior Cursos: Matemática /Informática e Ensino da Informática

Cálculo Numérico Faculdade de Engenharia, Arquiteturas e Urbanismo FEAU

Operações com números racionais decimais

Desmistificando Shaders em XNA 4.0

4. Tangentes e normais; orientabilidade

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

Coordenadas Polares Mauri C. Nascimento Dep. De Matemática FC Unesp/Bauru

Linguagem C Tipos de Dados. void; escalares; sizeof Vectores; strings em C Estruturas Introdução ao pré-processador

E/S CPU. Memória (Instruções e dados) 2 PARADIGMA IMPERATIVO. Instruções e dados. Resultados das operações. Unidade lógica e aritmética

Introdução ao MATLAB

Conversão de Tipos e Arrays

Nestas condições, determine a) as coordenadas dos vértices B, C, D, E e F e a área do hexágono ABCDEF. b) o valor do cosseno do ângulo AÔB.

Capítulo 8. Introdução UML

Potenciação no Conjunto dos Números Inteiros - Z

ESTUDO GRÁFICO DOS MOVIMENTOS. Gráfico posição x tempo (x x t)

Bruno Pereira Evangelista.

Evocar os conceitos do MRUV (movimento retilíneo uniformemente variado), do MRU (movimento retilíneo uniforme) e a decomposição de forças.

5 - Vetores e Matrizes Linguagem C CAPÍTULO 5 VETORES E MATRIZES

Linguagem C Funções definidas pelo usuário. Lógica de Programação

MA Sejam a e b esses números naturais: (a + b) 3 (a 3 + b 3 ) = a 3 + 3a 2 b + 3ab 2 + b 3 a 3 b 3 = = 3a 2 b + 3ab 2 = 3ab (a + b)

Universidade Federal de Rondônia Técnicas de Desenvolvimento de Programas Lista 4

Introdução ao OpenGL 2.1 e GLSL 1.2

Q1 Q2 Q3 Nota. Departamento de Informática - PUC-Rio INF 1005 Programação I P2 20/10/2010. Aluno: Exemplo (apenas um exemplo!):

Prof. Rossini Bezerra Faculdade Boa Viagem

UFPB PRG X ENCONTRO DE INICIAÇÃO À DOCÊNCIA

Utilização. de Shaders de efeitos realistas para jogos. Bruno Pereira Evangelista. Pontifícia Universidade Católica de Minas Gerais

Recursividade. Aula 9

Gráficos de funções em calculadoras e com lápis e papel (*)

UNESP DESENHO TÉCNICO: Fundamentos Teóricos e Introdução ao CAD. Parte 3/5: Prof. Víctor O. Gamarra Rosado

Programação Orientada a Objetos C++

Transcrição:

Computação Gráfica GLSL - Programação de Shaders Iluminação António Ramires Fernandes - Computação Gráfica 07/08

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 2

Tipos de Dados Escalares float float a,b=2.0; int int c,d=1; bool bool e,f= true; Vectores vec{2,3,4} vec3 v = vec3(1,2,3); ivec{2,3,4} vec3 a = v, b = vec3(4); bvec{2,3,4} Matrizes mat{2,3,4} mat3 m = mat3(1.0); // matriz identidade mat3 n = mat3(v,a,b); DI-UM Computação Gráfica 07/08 3

Tipos de Dados Selectores para Vectores x,y,z,w r,g,b,a s,t,p,q vec3 v = vec3(1.0,2.0,3.0); float f = v.x; // f = 1.0 float y = v[1]; // y = 2.0 vec3 u = v.zyx // u = (3.0,2.0,1.0) Selectores para Matrizes mat2 m = mat2(1.0); // m = matriz identidade vec2 v = m[0]; // v = (1.0,0.0) primeira coluna float f = m[0][0] // f = 1.0 DI-UM Computação Gráfica 07/08 4

Tipos de Dados Estruturas Definição struct luz { vec3 pos; vec3 cor; }; Declaração e inicialização Utilização luz luz1; luz luz2 = luz(vec3(1.0,2.0,3.0),vec3(1.0,0.0,0.0)); luz1.pos = vec3(1.0,2.0,3.0); DI-UM Computação Gráfica 07/08 5

Tipos de Dados Arrays vec3 pontos[5]; vec4 vertices[]; No caso de um array não definir a sua dimensão, o compilador procura o índice mais elevado no shader. Neste caso, os índices têm de ser constantes. DI-UM Computação Gráfica 07/08 6

Tipos de Dados Casting Realizado através de construtores float a = 3.0; int b = int(a); Constantes const int texturas = 10; DI-UM Computação Gráfica 07/08 7

Funções Semelhante ao C vec3 f() {... } Tipos dos parâmetros in out inout vec3 f(in vec3 a, out vec3 b) {... } DI-UM Computação Gráfica 07/08 8

Controle de fluxo Instruções iguais a C if else for while do while DI-UM Computação Gráfica 07/08 9

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 10

GLSL - Minimal - Vértices A funcionalidade fixa, ff, determina que um vértice deve ser transformado através da seguinte operação: Vres = Matriz PROJECTION * Matriz MODELVIEW * vertex O vertex shader recebe os vértices através da variável: attribute vec4 gl_vertex: O vertex shader deve transformar o vértice recebido e escrever o resultado em: vec4 gl_position; Variáveis de estado do OpenGL acessiveis: uniform mat4 gl_modelviewmatrix; uniform mat4 gl_projectionmatrix; uniform mat4 gl_modelviewprojectionmatrix; DI-UM Computação Gráfica 07/08 11

GLSL - Minimal - Vértices Para obter uma funcionalidade semelhante à ff, o vertex shader deverá então calcular gl_position utilizando uma das seguintes opções: gl_position = gl_projectionmatrix * (gl_modelviewmatrix * gl_vertex); gl_position = gl_modelviewprojectionmatrix * gl_vertex; gl_position = ftransform(); Esta última alternativa garante a funcionalidade exacta da ff. DI-UM Computação Gráfica 07/08 12

GLSL - Minimal - Vértices Vertex Shader void main (void) { } gl_position = ftransform(); DI-UM Computação Gráfica 07/08 13

GLSL - Minimal - Cor Constante O Fragment shader é responsável por escrever a variável gl_fragcolor. void main(void) { } gl_fragcolor = vec4(1,0,0,1); DI-UM Computação Gráfica 07/08 14

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 15

GLSL - Cores Um vertex shader calcula valores por vértice. Dentro de um Fragment shader precisamos de ter acesso aos valores interpolados para realizar os cálculos para cada fragmento. O pipeline gráfico utiliza os valores processados para cada vértice no vertex shader, e interpola-os de acordo com a construção de primitivas (utilizando a informação de conectividade). Estas variáveis interpoladas têm o qualificador varying. DI-UM Computação Gráfica 07/08 16

GLSL - Cores Código OpenGL glbegin(gl_quads); glcolor3f(1,0,0); glvertex3f(-1,-1,0); glcolor3f(0,1,0); glvertex3f(1,-1,0); glcolor3f(0,0,1); glvertex3f(1,1,0); glcolor3f(1,1,0); glvertex3f(-1,1,0); glend(); DI-UM Computação Gráfica 07/08 17

GLSL - Cores Variáveis de estado acessíveis nos shaders: attribute vec4 gl_color; // só vertex shader struct gl_materialparameters { vec4 emission; // Ecm vec4 ambient; // Acm vec4 diffuse; // Dcm vec4 specular; // Scm float shininess; // Srm }; uniform gl_materialparameters gl_frontmaterial; uniform gl_materialparameters gl_backmaterial; DI-UM Computação Gráfica 07/08 18

GLSL - Cores Vertex Shader obtem cor especificada na aplicação (glcolor) em: attribute vec4 gl_color; Vertex Shader escreve em: varying vec4 gl_frontcolor; varying vec4 gl_backcolor; Fragment Shader lê cor interpolada em: varying vec4 gl_color; Nota: não é a mesma variável que está acessível no vertex shader. Esta variável é interpolada pelo OpenGL a partir das variáveis gl_frontcolor e gl_backcolor. Fragment Shader escreve em: vec4 gl_fragcolor DI-UM Computação Gráfica 07/08 19

GLSL - Cores Exemplo // Aplicação OpenGL glbegin(gl_quads); glcolor3f(1,0,0); glvertex3f(-1,-1,0); glcolor3f(0,1,0); glvertex3f(1,-1,0); glcolor3f(0,0,1); glvertex3f(1,1,0); glcolor3f(1,1,0); glvertex3f(-1,1,0); glend(); // Vertex Shader void main(void) { } gl_frontcolor = gl_color; gl_position = ftransform(); // Fragment Shader void main() { gl_fragcolor = gl_color; } DI-UM Computação Gráfica 07/08 20

GLSL - Cores Exemplo // Aplicação OpenGL glmaterialfv(gl_front, GL_AMBIENT, bluematerial); glbegin(gl_quads); glcolor3f(1,0,0); glvertex3f(-1,-1,0); glcolor3f(0,1,0); glvertex3f(1,-1,0); glcolor3f(0,0,1); glvertex3f(1,1,0); glcolor3f(1,1,0); glvertex3f(-1,1,0); glend(); // Vertex Shader void main(void) { } gl_frontcolor = gl_frontmaterial.ambient; gl_position = ftransform(); // Fragment Shader void main() { gl_fragcolor = gl_color; } DI-UM Computação Gráfica 07/08 21

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 22

GLSL - Iluminação Reflexão difusa (Lambert) A intensidade de um objecto é proporcional ao ângulo entre a direcção da luz e a normal do objecto. Intensidade da luz I = I p * K d * cos (θ) N θ L coeficiente de reflexão difusa DI-UM Computação Gráfica 07/08 23

GLSL - Iluminação Adicionando a componente ambiente: I = I a * K a + I p * K d * cos (θ) Caso ambos os vectores estejam normalizados pode-se substituir o coseno pelo produto interno, I = I a * K a + I p * K d * (N. L) Produto Interno N.L = n x * l x + n y * l y + n z * l z Nota: só se consideram valores positivos do produto interno ou coseno DI-UM Computação Gráfica 07/08 24

GLSL - Iluminação Código OpenGL: glloadidentity(); glulookat(0.0, 0.0, 5.0, 0.0,0.0,0.0, 0.0,1.0,0.0); gllightfv(gl_light0, GL_POSITION, lightposition); glutsolidteapot(1); A especificação do OpenGL diz que a posição da luz é transformada pela matriz ModelView na altura da sua especificação, ou seja quando um shader acede à posição da luz, está a aceder à posição da luz no espaço da câmara. É necessário transformar as normais para o espaço câmara para poder calcular o coseno do ângulo entre a normal e a direcção da luz. DI-UM Computação Gráfica 07/08 25

GLSL - Iluminação Transformação da Normal Caso a matriz ModelView não seja ortogonal, a normal pode ser incorrectamente transformada. T' N' T N N' = MN T' = MT Precisamos de encontrar uma matriz G que transforme N de forma a que N'.T' = 0 (prod. interno) DI-UM Computação Gráfica 07/08 26

GLSL - Iluminação Transformação da Normal N'.T' = (GN).(MT) = 0 (GN).(MT) = (GN) T (MT) = N T G T MT Sabemos que N T T = 0, logo a equação é satisfeita quando G T M = I, ou seja G = (M -1 ) T Se M for ortogonal M -1 = M T, logo G = M DI-UM Computação Gráfica 07/08 27

GLSL - Iluminação GLSL fornece a matriz G: gl_normalmatrix Sendo assim o cálculo da normal dentro de um vertex shader é realizado através da seguinte operação: vec3 n; n = normalize(gl_normalmatrix * gl_normal); Sendo gl_normal a normal especificada para o vértice na aplicação OpenGL através da função glnormal. A normalização da normal num vertex shader pode ser dispensada caso haja garantia de que ambas as condições se verifiquem: a normal especificada na aplicação OpenGL está normalizada a matriz ModelView é ortogonal, i.e., que só foram aplicadas rotações e translações, mas não escalas. DI-UM Computação Gráfica 07/08 28

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direccional Direccional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 29

GLSL - Iluminação Direcional Variáveis de estado relevantes struct gl_lightsourceparameters { vec4 ambient; // Acli vec4 diffuse; // Dcli vec4 specular; // Scli vec4 position; // Ppli vec4 halfvector; // Derived: Hi... }; uniform gl_lightsourceparameters gl_lightsource[gl_maxlights]; struct gl_lightmodelparameters { vec4 ambient; // Acs }; uniform gl_lightmodelparameters gl_lightmodel; DI-UM Computação Gráfica 07/08 30

GLSL - Iluminação Direcional I = I a * K a + I p * K d * (N. L) void main(){ vec3 normal,lightdir; vec4 diffuse,ambient; float intensity; Vertex Shader } lightdir = normalize(vec3(gl_lightsource[0].position)); normal = normalize(gl_normalmatrix * gl_normal); intensity = max(dot(lightdir,normal),0.0); diffuse = gl_lightsource[0].diffuse * gl_frontmaterial.diffuse; ambient = gl_lightsource[0].ambient * gl_frontmaterial.ambient; gl_frontcolor = ambient + diffuse*intensity; gl_position = ftransform(); Fragment Shader void main(){ } gl_fragcolor = gl_color; DI-UM Computação Gráfica 07/08 31

GLSL - Iluminação Direcional Incorporar o termo ambiente global e emissivo I = I a * K a + I p * K d * (N. L) + K e + G a * K void main(){ }... gl_frontcolor = ambient + diffuse*intensity; gl_frontcolor += gl_frontmaterial.ambient * gl_lightmodel.ambient; gl_frontcolor += gl_frontmaterial.emissive; gl_position = ftransform(); DI-UM Computação Gráfica 07/08 32

GLSL - Iluminação Direcional Incorporar o termo especular Especular = I s * K s * (R.Câmara) s Especular = I s * K s * (H.N) s R N L H N L Câmara α θ θ Câmara θ θ DI-UM Computação Gráfica 07/08 33

GLSL - Iluminação Direcional Termo Especular no Vertex Shader Especular = I s * K s * (H.N) s if (intensity > 0) { aux = max(dot(vec3(gl_lightsource[0].halfvector),normal),0.0); shininess = pow(aux,gl_frontmaterial.shininess); specular = gl_lightsource[0].specular * gl_frontmaterial.specular; specular *= shininess; gl_frontcolor += specular; } DI-UM Computação Gráfica 07/08 34

GLSL - Iluminação Direcional void main(){ vec3 normal,lightdir; vec4 diffuse,ambient,specular; float intensity, shininess,aux; Vertex Shader lightdir = normalize(vec3(gl_lightsource[0].position)); normal = normalize(gl_normalmatrix * gl_normal); intensity = max(dot(lightdir,normal),0.0); diffuse = gl_lightsource[0].diffuse * gl_frontmaterial.diffuse; ambient = gl_lightsource[0].ambient * gl_frontmaterial.ambient; gl_frontcolor = ambient + diffuse*intensity; gl_frontcolor += gl_frontmaterial.ambient * gl_lightmodel.ambient; gl_frontcolor += gl_frontmaterial.emission; } if (intensity > 0.0) { aux = max(dot(vec3(gl_lightsource[0].halfvector),normal),0.0); shininess = pow(aux,gl_frontmaterial.shininess); specular = gl_lightsource[0].specular * gl_frontmaterial.specular; specular *= shininess; gl_frontcolor += specular; } gl_position = ftransform(); DI-UM Computação Gráfica 07/08 35

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 36

GLSL - Iluminação Direcional Shaders Apresentados: Vertex Shader calcula cores baseado na iluminação por vértice Fragment Shader utiliza os valores interpolados das cores para cada vértice Passo Seguinte: Cor calculada por pixel DI-UM Computação Gráfica 07/08 37

GLSL - Iluminação Direcional Para calcular a cor da superfície iluminada por pixel precisamos para cada ponto da superfície (não só para os vértices) : Normal Vector com direcção do "olhar" Direcção da luz Estes valores podem ser calculados por vértice e passados ao fragment shader que acederá à interpolação dos valores para cada primitiva. DI-UM Computação Gráfica 07/08 38

GLSL - Iluminação Direcional A comunicação entre o vertex shader e o fragment shader realiza-se através de duas formas: variáveis pré-definidas (caso das cores); variáveis definidas nos shaders pelo programador e declaradas como varying. DI-UM Computação Gráfica 07/08 39

GLSL - Iluminação Direcional Vertex Shader varying vec3 normal, lightdir, ecpos; Variáveis para interpolação void main() { lightdir = normalize(vec3(gl_lightsource[0].position)); normal = normalize(gl_normalmatrix * gl_normal); ecpos = vec3(gl_modelviewmatrix * gl_vertex) ; } gl_position = ftransform(); Porque não normalizar a normal somente no Fragment Shader? O vector com a direcção do olhar é calculado transformando o vértice para o espaço câmara. Neste espaço a câmara encontra-se na origem, e portanto o vector é gl_vertex - campos = gl_vertex. DI-UM Computação Gráfica 07/08 40

GLSL - Iluminação Direcional Fragment Shader varying vec3 normal, lightdir, ecpos; void main() { vec4 diffuse,ambient,specular,color; float intensity,shininess; vec3 n,hv,ec; Porquê normalizar novamente? Porque não normalizar a direcção da luz? n = normalize(normal); intensity = max(dot(lightdir,n),0.0);... DI-UM Computação Gráfica 07/08 41

GLSL - Iluminação Direcional Fragment Shader (2)... diffuse = gl_lightsource[0].diffuse * gl_frontmaterial.diffuse; ambient = gl_lightsource[0].ambient * gl_frontmaterial.ambient; color = ambient + diffuse*intensity; color += gl_frontmaterial.ambient * gl_lightmodel.ambient; color += gl_frontmaterial.emission;... Aqui realiza-se o cálculo da cor com as componentes difusa, ambiente e emissiva. DI-UM Computação Gráfica 07/08 42

GLSL - Iluminação Direcional Fragment Shader (3)... if (intensity > 0.0) { ec = normalize(-ecpos); hv = normalize(ec+lightdir); shininess = pow(max(dot(hv,n),0.0),gl_frontmaterial.shininess); specular = shininess * gl_lightsource[0].specular * gl_frontmaterial.specular; color += specular; } } gl_fragcolor = color; É necessário normalizar o vector com a direcção do olhar pela mesma razão que se normalizou o vector normal. DI-UM Computação Gráfica 07/08 43

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 44

GLSL - Iluminação Posicional A diferença entre a luz direcional e a luz posicional reduz-se aos seguintes termos: Existência de um factor de atenuação Direcção da luz varia por vértice ( e por pixel) DI-UM Computação Gráfica 07/08 45

GLSL - Iluminação Posicional Equação OpenGL cor = m 1 fatt = c + c d + c d Amb = m Diff Spec = e + lm a l * l a a + m = max( L N,0)* m max( 0, q a 2 + H N) f att d *( Amb + Diff * l shininess d * ms * ls) + Spec) onde: m representa o material l representa as propriedades da luz f att é o factor de atenuação relativamente à distância da luz ao objecto lm indica as propriedades do modelo de luz (ambiente) L é o vector unitário que aponta do ponto do objecto à posição da luz N é a normal do ponto do objecto H representa o half-vector DI-UM Computação Gráfica 07/08 46

GLSL - Iluminação Posicional Vertex Shader (iluminação por pixel) varying vec3 normal, ecpos; void main() { normal = normalize(gl_normalmatrix * gl_normal); ecpos = vec3(gl_modelviewmatrix * gl_vertex) ; } gl_position = ftransform(); O cálculo da direcção da luz passa para o fragment shader pois esta depende da localização do fragmento DI-UM Computação Gráfica 07/08 47

GLSL - Iluminação Posicional Fragment Shader Cálculo do factor de atenuação att = 1 c + c d l + c q d 2 Variáveis de estado relevantes struct gl_lightsourceparameters {... float constantattenuation; float linearattenuation; float quadraticattenuation; }; lightdir = vec3(gl_lightsource[0].position)-ecpos; d = length(lightdir); att = 1 / (gl_lightsource[0].constantattenuation + gl_lightsource[0].linearattenuation * d + gl_lightsource[0].quadraticattenuation * d * d); DI-UM Computação Gráfica 07/08 48

GLSL - Iluminação Posicional Fragment Shader varying vec3 normal, ecpos; void main() { vec4 diffuse,ambient,specular,color; float intensity,shininess,d,att; vec3 n,hv,ec, lightdir; lightdir = vec3(gl_lightsource[0].position)-ecpos; n = normalize(normal);... DI-UM Computação Gráfica 07/08 49

GLSL - Iluminação Posicional Fragment Shader (2) d = length(lightdir); att = max(1.0,1.0 / (gl_lightsource[0].constantattenuation + gl_lightsource[0].linearattenuation * d + gl_lightsource[0].quadraticattenuation * d * d)); diffuse = gl_lightsource[0].diffuse * FrontMaterial.diffuse; ambient = gl_lightsource[0].ambient * gl_frontmaterial.ambient; lightdir = normalize(lightdir) intensity = max(dot(lightdir,n),0.0); color = (ambient + diffuse*intensity) * att; color += gl_frontmaterial.ambient * gl_lightmodel.ambient; color += gl_frontmaterial.emission;... Aqui realiza-se o cálculo da cor com as componentes difusa, ambiente e emissiva, agora com a atenuação a influenciar a componente difusa e ambiente. DI-UM Computação Gráfica 07/08 50

GLSL - Iluminação Posicional Fragment Shader (3)... if (intensity > 0.0) { ec = normalize(-ecpos); hv = normalize(ec+lightdir); shininess = pow(max(dot(hv,n),0.0),gl_frontmaterial.shininess); specular = shininess * gl_lightsource[0].specular * gl_frontmaterial.specular; color += specular * att; } } gl_fragcolor = color; O cálculo da cor especular também é influenciado pela atenuação. DI-UM Computação Gráfica 07/08 51

Resumo Tipos de Dados, Funções e Controle de Fluxo GLSL - Minimal GLSL - Cores GLSL - Iluminação Direcional Direcional por pixel Posicional por pixel Spot Light por pixel DI-UM Computação Gráfica 07/08 52

GLSL - Iluminação Spot Light A iluminação com spot lights traz as seguintes novidades: A luz tem uma direcção (para alem da posição) Existe um ângulo que define o cone de luz O vertex shader é igual ao caso da luz posicional! DI-UM Computação Gráfica 07/08 53

GLSL - Iluminação Spot Light Equação OpenGL cor = m + lm + m + f * spoteffect *( Amb + Diff Spec) f att Amb = m Diff e a a att + 1 = c + c d + c d a l * l = max( L N,0)* m Spec = max(0, H N) a q 2 spoteffect = max(0, L spotdirection) d * l shininess d * ms * ls) spotexponent DI-UM Computação Gráfica 07/08 54

GLSL - Iluminação Spot Light Fragment Shader Cálculo de spoteffect s = max(0, -lightdir. spotdirection) Se (acos(s) > cutoff) spoteffect = 0 senão spoteffect = s exponent Variáveis de estado relevantes struct gl_lightsourceparameters {... vec3 spotdirection; // Sdli float spotexponent; // Srli }; float spotcutoff; // Crli // (range: [0.0,90.0], 180.0) float spotcoscutoff; // Derived: cos(crli) // (range: [1.0,0.0],-1.0)... spotdot = max(0.0,dot(-lightdir,gl_lightsource[0].spotdirection)); if (spotdot < gl_lightsource[0].spotcoscutoff) spotatt = 0.0; else spotatt = pow(spotdot,gl_lightsource[0].spotexponent); DI-UM Computação Gráfica 07/08 55

GLSL - Iluminação Spot Light Fragment Shader varying vec3 normal, ecpos; void main() { vec4 diffuse,ambient,specular,color; float intensity,shininess,d,att,spotatt,spotdot; vec3 n,hv,ec,lightdir; lightdir = vec3(gl_lightsource[0].position)-ecpos; n = normalize(normal);... A primeira parte do fragment shader é igual ao caso anterior das luzes posicionais. DI-UM Computação Gráfica 07/08 56

GLSL - Iluminação Spot Light Fragment Shader (2) d = length(lightdir); att = max(1.0,1.0 / (gl_lightsource[0].constantattenuation + gl_lightsource[0].linearattenuation * d + gl_lightsource[0].quadraticattenuation * d * d)); lightdir = normalize(lightdir); spotdot = max(0.0,dot(-lightdir,gl_lightsource[0].spotdirection)); if (spotdot < gl_lightsource[0].spotcoscutoff) spotatt = 0.0; else spotatt = pow(spotdot,gl_lightsource[0].spotexponent); att *= spotatt; diffuse = gl_lightsource[0].diffuse * gl_frontmaterial.diffuse; ambient = gl_lightsource[0].ambient * gl_frontmaterial.ambient;... Aqui realiza-se o cálculo da cor com as componentes difusa, ambiente e emissiva, agora com a atenuação a influenciar a componente difusa e ambiente. DI-UM Computação Gráfica 07/08 57

GLSL - Iluminação Spot Light Fragment Shader (3)... intensity = max(dot(lightdir,n),0.0); color = (ambient + diffuse*intensity) * att; color += gl_frontmaterial.ambient * gl_lightmodel.ambient; color += gl_frontmaterial.emission; if (intensity > 0.0) { } ec = normalize(-ecpos); hv = normalize(ec+lightdir); shininess = pow(max(dot(hv,n),0.0),gl_frontmaterial.shininess); specular = shininess * gl_lightsource[0].specular * gl_frontmaterial.specular; color += specular * att; } gl_fragcolor = color; O cálculo da cor é idêntico ao caso das points lights, tendo em atenção que o factor de atenuação agora também considera o efeito da spotlight. DI-UM Computação Gráfica 07/08 58

GLSL - Iluminação Spot Light Ooops! DI-UM Computação Gráfica 07/08 59

GLSL - Iluminação Spot Light Análise das contribuições de luz difusa + ambiente + ambiente global + especular ambiente + ambiente global ambiente global DI-UM Computação Gráfica 07/08 60

GLSL - Iluminação Spot Light O problema deve-se à forma como a luz ambiente é aplicada. intensity = max(dot(lightdir,n),0.0); color = (ambient + diffuse*intensity) * att; O valor de att depende de: factor de atenuação relativo à distância da luz ao ponto o ponto estar dentro do cone de luz Pelo código acima vemos que a cor ambiente está a ser aplicada sempre que att não seja zero. Os pontos da parte de trás do teapot estão dentro do cone de luz logo têm uma contribuição da luz ambiente, para alem da luz ambiente global. DI-UM Computação Gráfica 07/08 61

GLSL - Iluminação Spot Light Código para eliminar o problema: color = (diffuse*intensity)*att; if ((intensity > 0.0) && (spotatt!= 0)) color += ambient; DI-UM Computação Gráfica 07/08 62

Referências OpenGL 2.0 Specification, www.opengl.org GLSL Specification, www.opengl.org "OpenGL Shading Language", Randi Rost, Addison Wesley DI-UM Computação Gráfica 07/08 63