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

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

Modelos de Iluminação e Reflexão

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

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

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

1. Evolução do OpenGL

FCG2006 Prova sobre OpenGL e Rastreamento de Raios

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

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

Apontamentos de Computação Gráfica

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

INSTITUTO TECNOLÓGICO

INTRODUÇÃO À LINGUAGEM C++

Sistemas de Apoio à Decisão

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

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

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

Programação por Objectos. Java

14.1 Vetor - Problemas

Computação Gráfica - 13

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

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

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

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

CG 2013/2014 Primeiro Teste LEIC Alameda/Taguspark

Estrutura Condicional em Java

Introdução ao MATLAB

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

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

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

Desmistificando Shaders em XNA 4.0

Recursividade. Aula 9

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

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

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

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

Bruno Pereira Evangelista.

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!):

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

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

4. Tangentes e normais; orientabilidade

Programação Orientada a Objetos C++

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

Aula 3 Desvio Condicional

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

Prova de Admissão para o Mestrado em Matemática IME-USP

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

CAPÍTULO 6 TRANSFORMAÇÃO LINEAR

ESCOLA SECUNDÁRIA DE CASQUILHOS

Operações com números racionais decimais

Implementação do algoritmo Marching Cubes usando shaders. Luiz Fernando Oliveira Corte Real

Transcrição:

Computação Gráfica GLSL - Programação de Shaders Iluminação António nio Ramires Fernandes - Multimédia

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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 8

Controle de fluxo Instruções iguais a C if else for while do while DI-UM Multimédia 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 Multimédia 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 Multimédia 11

GLSL - Minimal - Vértices Para obter uma funcionalidade semelhante à ff, o vertex shader 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 Multimédia 12

GLSL - Minimal - Vértices Vertex Shader void main (void) { } gl_position = ftransform(); DI-UM Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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; Nota: A definição de materiais é através de variáveis uniformes, logo, caso se pretenda escrever shaders, não deverá ser utilizado dentro de Begin/End. DI-UM Multimédia 18

GLSL - Cores Vertex Shader lê 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 Multimédia 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) { } // Fragment Shader gl_frontcolor = gl_color; gl_position = ftransform(); void main() { gl_fragcolor = gl_color; } DI-UM Multimédia 20

GLSL - Cores Exemplo // Vertex Shader void main(void) { // 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(); } gl_frontcolor = gl_frontmaterial.ambient; gl_position = ftransform(); // Fragment Shader void main() { gl_fragcolor = gl_color; } DI-UM Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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_frontcolor = gl_color; Usa-se gl_frontmaterial Porque não normalizar a normal somente no Fragment Shader? } gl_position = ftransform(); 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 45

GLSL - Iluminação Posicional Equação OpenGL cor = m 1 fatt = c + c d + c d Amb = m Diff + lm = max( L N,0)* m Spec = max(0, H N) * ms * ls) 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 e a l * l a a + m q a 2 + f att d *( Amb + Diff * l shininess d + Spec) DI-UM Multimédia 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_frontcolor = gl_color; } 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 53

GLSL - Iluminação Spot Light Equação OpenGL cor = m f att Amb = m Diff e + lm 1 = c + c d + c d a l * l + m = max( L N,0)* m Spec = max(0, H N) a a q a 2 spoteffect = max(0, L spotdirection) + f att d * spoteffect *( Amb + Diff * l shininess d * ms* ls) spotexponent + Spec) DI-UM Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 58

GLSL - Iluminação Spot Light Ooops! DI-UM Multimédia 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 Multimédia 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 Multimédia 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 Multimédia 62

Referências OpenGL 2.0 Specification, www.opengl.org GLSL Specification, www.opengl.org "OpenGL Shading Language", Randi Rost, Addison Wesley DI-UM Multimédia 63