Modelos de Iluminação e sombreamento - OpenGL. - Unisinos
Modelos de Iluminação e sombreamento - OpenGL. - Unisinos
Modelos de Iluminação e sombreamento - OpenGL. - Unisinos
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Iluminação em <strong>OpenGL</strong><br />
Iluminação em <strong>OpenGL</strong><br />
Dicas <strong>de</strong> Implementação<br />
Prof. Christian Hofsetz<br />
• Iluminação ambiente, difusa e especular são suportados<br />
pelo <strong>OpenGL</strong><br />
• Usuários <strong>de</strong>vem <strong>de</strong>finir pesos e valores<br />
– posição, tipo, cor<br />
• Usuários também <strong>de</strong>finem material<br />
– Po<strong>de</strong> ser diferente para a parte <strong>de</strong> trás do polígono<br />
Luzes em <strong>OpenGL</strong><br />
GLfloat lightA_position[ ] = {1.0, 1.0, 1.0, 0.0};<br />
GLfloat lightB_position[ ] = {1.0, 2.0, 3.0, 1.0};<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightA_position);<br />
glLightfv(GL_LIGHT1, GL_POSITION, lightB_position);<br />
Acima <strong>de</strong>finimos uma fonte <strong>de</strong> luz direcional vindo da<br />
direção (1, 1, 1), e uma fonte <strong>de</strong> luz posicional vindo do<br />
ponto (1, 2, 3) nas coor<strong>de</strong>nadas do universo.<br />
<strong>OpenGL</strong> Lights<br />
• Po<strong>de</strong>mos especificar até 8 luzes em <strong>OpenGL</strong><br />
GL_LIGHT0 .. GL_LIGHT7<br />
• Para verificar o número máximo <strong>de</strong> luzes que po<strong>de</strong>mos usar em uma<br />
implementação específica:<br />
glGetIntegerv(GL_MAX_LIGHTS, GLint *num_lights);<br />
• Devemos habilitar cada luz que quisermos usar *E* habilitar<br />
iluminação em <strong>OpenGL</strong> (disabled by <strong>de</strong>fault):<br />
glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); …<br />
glEnable(GL_LIGHTING);<br />
glLight*()<br />
Spotlight<br />
• glLight{if}(GLenum light, GLenum pname, TYPE param)<br />
glLight{if}v(GLenum light, GLenum pname, TYPE *param)<br />
• light po<strong>de</strong> ser GL_LIGHT0 .. GL_LIGHT7<br />
• pname po<strong>de</strong> ser:<br />
– GL_POSITION: posição da luz<br />
– GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR : cor da luz<br />
– GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL_SPOT_CUTOFF:<br />
parâmetros da luz do tipo “spot” (spotlight)<br />
– GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION,<br />
GL_QUADRATIC_ATTENUATION: parâmetros para atenuação<br />
Cutoff<br />
Direction<br />
1
glLight*()<br />
GLfloat light0_ambient[ ] = {0.0, 0.1, 0.0, 1.0};<br />
GLfloat light0_diffuse[ ] = {0.0, 0.0, 1.0, 1.0};<br />
GLfloat light0_specular[ ] = {1.0, 1.0, 1.0, 1.0};<br />
GLfloat light0_position[ ] = {1.0, 2.0, 3.0, 1.0};<br />
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);<br />
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);<br />
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);<br />
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);<br />
glEnable(GL_LIGHT0);<br />
glEnable(GL_LIGHTING);<br />
Materiais<br />
• Cores dos objetos iluminados são calculados pela multiplicação da<br />
cor das luz com a cor do material (por canal R, G e B)<br />
• Assim como <strong>de</strong>finimos as cores das luzes em ambiente, difusa e<br />
especular, as cores dos materiais também são <strong>de</strong>finidas da mesma<br />
forma.<br />
• Po<strong>de</strong>mos <strong>de</strong>finir cores <strong>de</strong> materiais que emitem luz:<br />
– Neste caso, as luzes não influenciam a cor final do material<br />
– As luzes emitidas por objetos que emitem luz não são computadas pelo<br />
<strong>OpenGL</strong> nos outros objetos<br />
glMaterial*()<br />
• glMaterial{if}(GLenum face, GLenum pname, TYPE param)<br />
glMaterial{if}v(GLenum face, GLenum pname, TYPE *param)<br />
• face po<strong>de</strong> ser: GL_FRONT, GL_BACK, GL_FRONT_AND_BACK<br />
• pname po<strong>de</strong> ser:<br />
– GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION: cores<br />
do material<br />
– GL_SHININESS: expoente <strong>de</strong> iluminação do mo<strong>de</strong>lo Phong<br />
glMaterial*()<br />
GLfloat mat0_ambient[ ] = {0.2, 0.2, 0.2, 1.0};<br />
GLfloat mat0_diffuse[ ] = {0.7, 0.0, 0.0, 1.0};<br />
GLfloat mat0_specular[ ] = {1.0, 1.0, 1.0, 1.0};<br />
GLfloat mat0_shininess[ ] = {5.0};<br />
glMaterialfv(GL_FRONT, GL_AMBIENT, mat0_ambient);<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat0_diffuse);<br />
glMaterialfv(GL_FRONT, GL_SPECULAR, mat0_specular);<br />
glMaterialfv(GL_FRONT, GL_SHININESS, mat0_shininess);<br />
glColorMaterial()<br />
• Se vamos apenas modificar uma propriedad do material, é<br />
mais eficiente utilizarmos glColorMaterial( )<br />
• glColorMaterial( ) especifica qual cor modificar<br />
glEnable(GL_COLOR_MATERIAL);<br />
glColorMaterial(GL_FRONT, GL_DIFFUSE);<br />
glColor3f(0.2, 0.5, 0.8); // altera a cor difusa do material<br />
Desenhar objetos aqui<br />
glColorMaterial(GL_FRONT, GL_SPECULAR);<br />
glColor3f(0.9, 0.0, 0.2); // altera a cor especular do material<br />
Desenhar objetos aqui<br />
glDisable(GL_COLOR_MATERIAL);<br />
Ren<strong>de</strong>rizando Polígonos<br />
• Flat Ren<strong>de</strong>ring<br />
• Goraud Shading<br />
– Uses Phong Reflectance<br />
• Phong Shading<br />
2
Flat Ren<strong>de</strong>ring<br />
• Uma normal por triângulo<br />
• Cor constante no triângulo<br />
– Calculada <strong>de</strong> acordo com o mo<strong>de</strong>lo <strong>de</strong> reflexão<br />
• Melhor para superfícies realmente planas<br />
• Simples e rápido<br />
Gouraud Shading<br />
• Uma normal por vértice<br />
• Calcula a cor por vértice<br />
• Cores por pixels são interpoladas<br />
– para cada canal R, G, B<br />
• Resultados aceitáveis para superfícies curvas<br />
Phong Shading<br />
• Uma normal por vértice<br />
• Normal é interpolada por pixel<br />
– Interpola-se cada componente da normal e, <strong>de</strong>pois, normaliza-se<br />
Como interpolamos normais? Uma normal é um vetor<br />
unitário. Não po<strong>de</strong>mos apenas interpolar os valores x,y,z da<br />
normal – o vetor resultante não será unitário. Veja este<br />
exemplo:<br />
N1 = (0, .436, -.9). N2 = (0, -.436,.9)<br />
Se fizermos a média <strong>de</strong>stes vetores, obteremos (0,0,.9),<br />
cujo tamanho obviamente não é unitário. Ele <strong>de</strong>ve ser<br />
normalizado para obtermos (0,0,1).<br />
• Calcula a equação <strong>de</strong> iluminação por pixel<br />
• Bons resultados para superfícies curvas e<br />
• Não disponível ainda em <strong>OpenGL</strong><br />
Gouraud vs. Phong<br />
• Gouraud é mais rápido<br />
– Apenas um valor a ser interpolado<br />
– Não precisamos normalizar<br />
– Não é necessário calcular a equação <strong>de</strong> iluminação para cada<br />
ponto<br />
• Phong produz resultados melhores<br />
– Especialmente quando os efeitos <strong>de</strong> iluminação mudam<br />
rapidamente com a normal da superfície (e.g., pontos <strong>de</strong> alta<br />
reflexão especular)<br />
– É o melhor para objetos brilhantes<br />
– É o melhor para cálculo <strong>de</strong> sombras<br />
3
<strong>OpenGL</strong> Shading<br />
• <strong>OpenGL</strong> suporta flat shading e Gouraud shading.<br />
Não há suporte ainda para Phong shading.<br />
• glSha<strong>de</strong>Mo<strong>de</strong>l(GL_FLAT)<br />
– Flat shading<br />
• glSha<strong>de</strong>Mo<strong>de</strong>l(GL_SMOOTH)<br />
– Gouraud shading<br />
• Lembre-se <strong>de</strong> fornecer as normais corretamente, caso contrário a<br />
iluminação não irá funcionar.<br />
Discussão<br />
• Fonte <strong>de</strong> luz e/ou observador no infinito simplificam os<br />
cálculos, mas o resultado é menos realista<br />
Referências<br />
• http://www.cs.umd.edu/~djacobs/CMSC427/Shadi<br />
ng_web.ppt<br />
• Algumas vezes precisamos normalizar ou truncar as cores<br />
para evitar estouro (R = R/(R + G + B) , .... )<br />
4