Computação Gráfica www.dca.ufrn.br/~lmarcos/courses/compgraf Modelos de Iluninação • • • • • Luz real Como seres humanos percebem a luz Enganando seres humanos no computador Luzes e superfícies Tudo em openGL Entendendo a luz Intervalos aproximados • • • • • • Violeta 380-440 m (mili-micron) Azul 440-490 Verde 490-565 Amarelo 565-590 Laranja 590-630 Vermelho 630-700 RGB • 1=700 m (Red) • 2=546 m (Green) • 3=435.8 m (Blue) • () = (R(), G(), B()) XYZ X 0.49 0.17 0.00 R Y 0.31 0.81 0.01 G Z 0.20 0.01 0.99 B Sistemas complementares (CMY) • • • • • Ideal para impressoras Subtrai do branco (processo subtrativo) Ciano = verde+azul=> elimina vermelho Magenta=azul+vermelho=> elimina verde Amarelo=vermelho+verde=> elimina azul Tom, Saturação, Luminância Por que diferentes modelos? Iluminação • Fontes de luz emitem luz: – Espectro eletro-magnético – Posição e direção • Superfícies refletem luz – Reflectância – Geometria (posição, orientação, micro-estrutura) – Absorção – Transmissão – Iluminação é determinada pela interação entre fontes de luzes e superfícies Tipos de fontes de luz • Ambiente: luz igual em todas as direções – um “hack” para modelar interrelações • Direcional: raios todos na mesma direção – fontes de luz distantes (sol) • Pontual: raios divergem de um ponto – aproxima uma lâmpada Mais fontes de luzes • Spotlight: feixe de luz pontual direcionada – intensidade é máxima numa certa direção – parâmetros: cor, ponto, direção, espalhamento • Fonte área: superfície 2D luminosa – radia luz de todos os pontos de sua sueprfície – gera sombras suavizadas Reflexão difusa • Modelo mais simples de reflexão (lambertiano) • Modela superfície opaca rugosa a nível microscópico • Refletor difuso ideal – luz recebida é refletida igualmente em todas as direções – o brilho visto não depende da direção de visualização – brilho não depende da direção de visualização Lei de Lambert I diffuse kd Ilight cos kd Ilight ( N L) Ilight = intensidade da fonte de luz kd = coeficiente de reflexão [0.0,1.0] = ângulo entre a direção da luz e a normal Exemplos de iluminação difusa • A mesma esfera com iluminação difusa com luz em diferentes ângulos Reflexão ambiente + difusa • Modelo Lambertiano não é suficiente para CG. I d a ka I a kd I light ( N L) Ia ka = luz ambiente (global) = reflectância ambiente (local) [0,1] Iluminação difusa mais termo ambiente. Um truque para contar a luz de background causada por reflexão múltipla de todos os objetos na cena Outros efeitos simples • Atenuação da luz – intensidade da luz diminui com o quadrado da distância da fonte I d a ka I a f att kd Ilight ( N L) , com f att 1 2 d • Luzes coloridas e superfícies – 3 equações separadas para RBG (ou XYZ, ou YIQ, etc). • Atenuação atmosférica – usar a distância observador-superfície para dar efeitos extras – tornar a radiância do objeto mais turva ou menos definida com um fator de cinza. Reflexão especular • Superfícies brilhantes mudam a aparência de acôrdo com a posição de visualização – reflexão especular depende da posição de visualização – causada por superfícies lisas (smooth) ao nível microscópico • Em superfícies brilhantes, grande parte da luz incidente reflete coerentemente – um raio é refletido numa direção única (ou quase) – direção é definida pela direção de incidência e pela normal • Um espelho é um refletor especular perfeito • Refletores especular aproximados dão espalham pouco Modelo de Phong • Aproxima reflexão especular I specular ks I light (cos ) nsh in y = ângulo entre raio refletido e observador k s = reflectância especular [0,1] nshiny = taxa de decaimento da reflexão (espalhamento) Calculando o raio refletido Curvas de iluminação de Phong • O expoente especular é quase sempre muito maior que 1. Valores = 100 são encontrados I specular ks I light (cos ) nsh in y Exemplos de iluminação Phong Combinando tudo • Combinando ambiente, difusa e especular I d a ka I a f att I light kd cos ks (cos ) nsh in y • Para multiplas fontes: – repita cálculos para difusa e especular – some as componentes de todas as fontes – termo ambiente contribui apenas uma vez • Coeficientes de reflectância podem diferir – metal simples: ka e kd compartilham cor, ks é branco – plástico simples: ks inclui também a cor do material Alguns exemplos Outros modelos de reflectância • Phong/Blinn – Diffuse using Lambertian – Specular using a hack • Cook-Torrance – Specular – Useful for metals, sheens • Seeliger – Diffuse – Skin, softer than Lambertian • Hair – Anisotropic – Uses grain direction Vectors H N – Normal L – Source Refl. R V – View R – Reflection V H – Halfway Obs R = 2(NL)N – L H = (V+L)/||V+L|| N (R) (L) Fonte L x Phong e Blinn • Phong L(V) = ka La + kd Li (NL) + ks Li (VR)n • Blinn L(V) = ka La + kd Li (NL) + ks Li (NH)n • In general ignore ambient term and assume a diffuse/specular decomposition Cook-Torrance • Models specular BRDF component 1 FDG fs ( N L)(N V ) • F – Fresnel term • D – Roughness term • G – Geometry term Fresnel Term 1 sin 2 ( r t ) tan2 ( r t ) F 2 2 2 sin ( r t ) tan ( r t ) • Derived from Maxwells equations • Coefficients 1 ( g c) 2 (c( g c) 1) 2 1 2 2 2 ( g c) (c( g c) 1) r – angle of reflection w.r.t. H t – angle of transmission w.r.t. H c = cos r = LH = VH g2 = 2 + c2 – 1 1 F0 1 • Index of refraction actually complex! 1 F0 1 F0 2 Efeito de Fresnel • Luz incidente normal reflete cor da superfície • Luz incidente tangencial reflete cor da luz • Reflexão aumenta à medida que a incidência se torna tangencial Roughness Term • Statistical model of light reflectance • Centered around reflection direction R • Blinn model ( a 2 / m2 ) D ce • Beckman function ( tan2 a 2 / m 2 ) a = NH) e D 2 m cos4 a m Geometry Term • Shadowing (sombreando) – Luz incidente não alcança o material Gs = 2(NH)(NV)/(VH) • Masking (mascarando) – Luz refletida não alcança o observador Gm = 2(NH)(NL)/(VH) • Use minimum Gm = min Gs, Gm Seeliger • • • • • fr = NL/(NL + NV) Modelo para reflexão difusa da pele Aparência mais suave que o lambertiano Derivada de princípios primários Usada como base para shading em multicamada See Hanrahan & Krueger SIGGRAPH 93 L L Hair T • Anisotropic • Uses tangent vector T • Diffuse anisotropic fd = sin(T,L) • Specular anisotropic fs = (TL) (TV) + sin(T,L) sin(T,V) Definindo coeficientes em OpenGL Iluminando em OpenGL Considerando refração • Refração: inclinação que a luz sofre para diferentes velocidades em diferentes materiais • Índice de refração – – – – luz viaja à velocidade c/n em um material com índice n c é a velocidade da luz no vácuo (n=1) varia de acordo com o comprimento de onda prismas e arco-iris (luz branca quebrada em várias) Transmissão com refração • A luz inclina pelo princípio físico do tempo mínimo (princípio de Huygens) – luz viaja de A a B pelo caminho mais rápido – se passar de um material de índice n1 para outro de índice n2, a lei de Snell define o ângulo de refração: n1sin1 n2 sin 2 – Quando entra em materiais mais densos (n maior), a inclinação é mais perpendicular (ar para a água) e vice-versa – se os índices são os mesmos, a luz não inclina • Quando entra num material menos denso, reflexão total pode ocorrer se 1 n2 1 sin n1 Sombras • Sombras ocorrem quando objetos são protegidos da luz – objeto não influi na iluminação da cena (não reflexão) • Calcular o que está oculto é um problema de visibilidade – a luz consegue ver o objeto? – use um algoritmo z-buffer para sombreamento • rode o alguritmo do ponto de vista da luz • salve o z-buffer como shadow-buffer • rode o algoritmo z-buffer real, mapeando cada ponto nas coordenadas da fonte de luz e comparando o valor contra o shadow-buffer • (OK, ainda não estudamos z-buffer:-)... Shadow-buffer Shading • Dada uma equação para calcular a radiância da superfície, ainda é necessário aplicá-la ao modelo real – geralmente executado durante “scan conversion” (rasterização) – há modelos eficientes para fazer isso (Gouraud, Phong shading) • Mapeamento de textura melhora tudo isso – coloca radiância baseado numa imagem • Ainda melhor: uso de “procedural shaders” para especificar funções gerais para a radiância – gera radiância on-line, durante o “shading” – Pixar Renderman: usado em Toy Story, Bug´s Life, etc Mapeando texturas (paramétrica) • Superfícies coloridas ou sombreadas uniformemente ainda são irreais • Objetos reais possuem superfícies com textura (features) • Opção: ter uma grande quantidade de polígonos com características de cor e reflectância; ou • Usar imagens de textura para produzir superfícies reais – pegar texturas da natureza (nuvens, madeira, terra); – pinte-as você mesmo; – mapeie a imagem na superfície usando uma função paramétrica que mapeia pontos (u,v) em coordenadas de imagem (x,y) – quando visualizando um ponto, olhe no píxel correspondente na imagem de textura e use isto para afetar a cor final Especificando função de textura • Parametrização 2D: – – – – alguns objetos têm parametrização natural esferas: usam coordenadas esféricas cilindro:usar coordenadas cilíndricas ( , ) (2u, v) superfícies paramétricas (B-splines, Bézier): (u, ) (u,v) (u,2v) • Parametrização menos óbvia: – polígonos precisam de correspondência entre triângulos – superfícies implícitas: difícil de parametrizar (use textura sólida) • Parametrização 3D (textura sólida): – crie um mapa 3D de textura: volume parametrizado por (u,v,w) – crie texturas sólidas de imagens, projetando-a em profundidades diferentes (efeito do projetor de slides). Para cada triângulo no modelo, estabeleça uma região correspondente na foto-textura Durante rasterização, interpole os índices das coordenadas no mapa de texturas Uso de mapeamento de textura • Você pode afetar uma série de parâmetros como: – – – – – – cor da superfície: cor (radiância) de cada ponto na superfície reflectância: coeficientes de reflectância (kd, ks, nshiny) vetor normal: “bump mapping” geometria: mapa de deslocamentos transparência: mapa de transparência radiância considerando fonte de luz: mapeamento ambiente (ka) Bump mapping: um truque sujo • Quais objetos são convexos e quais são côncavos? • Resposta: nenhum, estas imagens são todas planas. • Sistema visual humano é treinado para esperar luz de cima • Em CG, pode-se perturbar o vetor normal sem ter que fazer nenhuma mudança real na forma (apenas usando um mapa de texturas). Bump mapping • Mapeamento básico de textura pinta numa superfície suave • Tornando a superfície rugosa: – Opção 1: modelar a superfície com muitos polígonos pequenos – Opção 2: perturbar o vetor normal antes de calcular sombreamento Esfera com mapa de texturas difuso Bump map Esfera com mapa de texturas difuso + bump map Bump mapping • Mapeamento básico de textura pinta numa superfície suave • Tornando a superfície rugosa: – Opção 1: modelar a superfície com muitos polígonos pequenos – Opção 2: perturbar o vetor normal antes de calcular sombreamento • A superfície não muda realmente, sombreamento faz parecer mudada • bump map causa deslocamentos acima e abaixo da superfície • pode-se usar mapas de textura para isso: – imagem de textura diz quantidade de perturbação na normal • que tipo de anomalia pode ser produzida? Esfera com mapa de texturas difuso Bump map Esfera com mapa de texturas difuso + bump map “Bump mapping”, outro exemplo Cilindro c/ mapa de texturas difuso Cilindro c/ mapa de texturas difuso + bump map Radiância x reflectância Textura especifica a radiância (isotrópica) para cada ponto na superfície Textura especifica a cor (difusa, coeficiente kd) para cada ponto na superfície: 3 coef, um para cada canal de radiância (R, G, B). Mapa de deslocamentos • Uso do mapa de texturas para deslocar cada ponto na superfície – valor de textura diz quanto mover na direção normal à superfície • Qual a diferença do “bump mapping”? Mapa de texturas sólidas • Um array 3D de valores de textura (algo como um bloco de mármore) – usa uma função (x,y,z)->(R,G,B) para mapear cores em pontos do espaço • Na prática, o mapa é definido de forma procedimental (funcional) – não precisa armazenar array de cores 3D – definir uma função para gerar cor para cada ponto 3D • As texturas sólidas mais interessantes são as aleatórias • Avalia coordenadas de textura em coordenadas de objeto - caso contrário movendo o objeto, muda a textura Mapa ambiente (ou de reflexão) Mapa ambiente (ou de reflexão) • Coloque sua cena dentro de um cubo • Pinte imagens nas faces do cubo para criar uma imagem de fundo que envolva o objeto. Podem ser nuvens, montanhas, uma sala, etc... • Use o cubo para iluminar a cena dentro dele Pintando o objeto • Durante o cálculo do shading (sombreamento): – jogue um raio do observador fora para o objeto num ponto P – Intercepte o raio com o mapa do ambiente (o cubo) no ponto E – tome a cor do mapa ambiente em E e ilumine P como se houvesse uma luz virtual na posição E – obtém-se uma imagem do ambiente refletida em superfícies brilhantes • Modelo alternativo ao ray-tracing real. Mais truques: mapeamento de luz • Um efeito “quake” pode usar um mapa de luz em adição a um mapa de texturas (radiância) Mapas de textura são usados para adicionar detalhes a superfícies, e mapas de luz são usados para armazenar iluminação pré-calculadas. Os dois são multiplicados juntos, em tempo de execução, e colocados num “cache” para maior eficiência. Texturas em OpenGL • Construa sua imagem de textura – Dimensões da imagem devem ser 2n por 2m – Este código assume imagens coloridas usando RGB • • • • • • • • • • • Pic *in; Gluint texname; in = tiff_read(filename,NULL); glGenTexture(1,&texname); glBindTexture(GL_TEXTURE_2D,texname); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE,0,GL_RGB,in->nx,in->ny,0,GL_RGB, GL_UNSIGNED_BYTE,in->pix); Texturas em OpenGL • Colocando em modo textura 2D: – glEnable(GL_TEXTURE_2D); – glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENVMODE, – GL_MODULATE); – gl_BindTexture(GL_TEXTURE_2D,texname); • Para cada vértice: – glTexCoor2f(vert.s,vert.t); • Retira modo textura após terminar de desenhar: – glDisable(GL_TEXTURE_2D); Uma rosquinha Uma rosquinha com textura Removendo superfícies ocultas • while (1) { • get_viewing_point_from_mouse_position(); • glClear(GL_COLOR_BUFFER_BIT); • draw_3d_object_A(); • draw_3d_object_B(); • } Usando o buffer de profundidade • • • • • • • • • • glutInitDisplayMode (GLUT_DEPTH | .... ); glEnable(GL_DEPTH_TEST); ... while (1) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); get_viewing_point_from_mouse_position(); draw_3d_object_A(); draw_3d_object_B(); } Programa exemplo (esfera) • #include <GL/gl.h> • #include <GL/glu.h> • #include <GL/glut.h> Programa exemplo (esfera) • • • • • • • • • • • • • void init(void) { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); } Programa exemplo (esfera) • • • • • • void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere (1.0, 20, 16); glFlush (); } Programa exemplo (esfera) • • • • • • • • • • • • • • void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); else glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Programa exemplo (esfera) • • • • • • • • • • • • • int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; } Comentários • Definir vetores normais para todos vértices: glutSolidSphere() faz isso. • Criar, posicionar e habilitar uma (ou mais) fontes de luz: glLightfv(), glEnable(), glLight*() • Ex: GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; • glLightfv(GL_LIGHT0, GL_POSITION, light_position); • default: GL_POSITION é (0, 0, 1, 0), eixo-Z negativo • Selecionar um modelo de iluminação: glLightModel*() • Definir propriedades materiais para os objetos na cena Lembre-se • Voce pode usar valores defaults para alguns parâmetros, de iluminação; outros devem ser modificados • Não se esqueça de habilitar todas as luzes que pretende usar e também habilitar o cálculo de iluminação • Voce pode usar “display lists” para maximizar eficiência quando é necessário mudar as condições de iluminação