Computao Grfica MO 603MC 930 http www ic

  • Slides: 52
Download presentation
Computação Gráfica MO 603/MC 930 http: //www. ic. unicamp. br/~lmarcos/mc 603

Computação Gráfica MO 603/MC 930 http: //www. ic. unicamp. br/~lmarcos/mc 603

Iluminação, Sombras, Shading e Textura • • Iluminação Sombreamento Remoção de faces ocultas Textura

Iluminação, Sombras, Shading e Textura • • Iluminação Sombreamento Remoção de faces ocultas Textura

Shading • Dada uma equação para calcular a radiância da superfície, ainda é necessário

Shading • Dada uma equação para calcular a radiância da superfície, ainda é necessário aplicá-la ao modelo real – shading é geralmente executado durante a rasterização (conversão para raster) – basicamente, preenchimento de regiões – há modelos eficientes para fazer isso (Gouraud, Phong shading)

Gouraud Shading • Ajusta cor de preenchimento de um pixel a outro – Calcule

Gouraud Shading • Ajusta cor de preenchimento de um pixel a outro – Calcule iluminação para cada vértice da malha – Interpole linearmente as cores dos vértices para conseguir cor ao longo de cada aresta. – Interpole cores das arestas para conseguir cor de cada pixel, ao longo de cada linha de span • Muito mais rápido do que calcular iluminação para cada pixel • Um grande truque. Pronuncia-se Gurou’

Gouraud Shading • Especificar um valor de shading diferente para cada vértice de polígono

Gouraud Shading • Especificar um valor de shading diferente para cada vértice de polígono (polígonos adjacentes com o mesmo valor) • Interpolar na hora de fazer o rendering • Pode também ser usado para obscurecer regiões distantes do observador, fazendo a cena parecer mais real

Gouraud Shading • Calcule ou defina cores em cada vértice – Se tiver normal

Gouraud Shading • Calcule ou defina cores em cada vértice – Se tiver normal nos vértices, usaria modelo de iluminação de Phong para calcular a cor – Ou pode ter cores pré definidas de algum modo (manualmente) • Interpola linearmente cores nos vértices para obter cores nas arestas – Determinar cores Cymin e Cymax – d. C = (Cymin-Cymax )/(ymin-ymax) – Caminhando em passos unitários de yminaté ymax: • Cymin+1 = Cymin + d. C • Resta interpolar cores nas arestas para obter cores ao longo de cada linha:

Rasterizando • Calcular o gradiente de sombreamento ao longo da linha: – Gradient =

Rasterizando • Calcular o gradiente de sombreamento ao longo da linha: – Gradient = (Bs - As) / (Bx - Ax) – As, Bs = valor de sombreamento em A, B e Ax, Bx = valor da coordenada em X de A, B • Calcular o valor exato de sombreamento em C: – Cs = As + (1 -frac(Ax))*Gradient • • • Calcular o valor de cada pixel e pintar tela: Shade = Cs loop X from Cx to Dx plot pixel at (X, Y) with colour Shade = Shade + Gradient End of X loop

Ambiguidade • Apenas acontece para quadriláteros e outros • Quando um quadrado rotaciona numa

Ambiguidade • Apenas acontece para quadriláteros e outros • Quando um quadrado rotaciona numa tela, as linhas escaneiam-o de modo diferente • Isto é, interpolação me X conecta a dois pontos diferentes de interpolação em Y. Cor no ponto muda. . . • Melhor usar triângulos (ou coordenadas baricêntricas) C C is blue C C is red

Estilos de Shading mais comuns • Faceted shading (flat): sem interpolação – Cor constante

Estilos de Shading mais comuns • Faceted shading (flat): sem interpolação – Cor constante ao longo de cada polígono – menos caro • Gouraud shading (sombreado): interpola cores – calcula ou define o shading para cada vértice – interpola linearmente ao longo do polígono – custo: 3 adições de inteiros por pixel • Phong shading (sombreado): interpola normais – – calcula normais aos vértices Interpola linearmente normais ao longo de cada polígono usa normal interpolada para calcular o shading de cada pixel (caro? ) custo: dezenas ou centenas de operações em ponto flutuante por pixel • Mapeamento de textura: interpola coordenadas de textura – usa estas coordenadas para definir textura em cada pixel

Shading Stytes • Faceted Gouraud Phong

Shading Stytes • Faceted Gouraud Phong

Comparação entre estilos de shading • Gouraud e Phong são exemplos de shading suave

Comparação entre estilos de shading • Gouraud e Phong são exemplos de shading suave – um truque para visualizar uma malha poligonal de forma suave • Tenha em mente: não é fisicamente correto! – Por que? – 1. O quanto a cor deve variar num plano com iluminação disusa? – 2. Interpolação de normal não faz sentido para um polígono! • Mas isso funciona bem na prática

Gouraud e Phong • Quais as vantagens de Phong sobre Gouraud? – Iluminação forte

Gouraud e Phong • Quais as vantagens de Phong sobre Gouraud? – Iluminação forte especular fica muito melhor • Lembre-se: Modelo de shading de Phong não é o mesmo que modelo de iluminação de Phong! – Modelo de iluminação de Phong diz como calcular a radiância, dada uma normal e uma fonte de luz – Shading de Phong é um truque par ainterpolar normais no espaço-imagem • Open. GL faz Gouraud shading (ou flat shading)

Comentários • Definir vetores normais para todos vértices: glut. Solid. Sphere() faz isso. •

Comentários • Definir vetores normais para todos vértices: glut. Solid. Sphere() faz isso. • Criar, posicionar e habilitar uma (ou mais) fontes de luz: gl. Lightfv(), gl. Enable(), gl. Light*() • Ex: GLfloat light_position[] = { 1. 0, 0. 0 }; • gl. Lightfv(GL_LIGHT 0, GL_POSITION, light_position); • default: GL_POSITION é (0, 0, 1, 0), eixo-Z negativo • Selecionar um modelo de iluminação: gl. Light. Model*() • Definir propriedades materiais para os objetos na cena

Lembre-se • Voce pode usar valores defaults para alguns parâmetros, de iluminação; outros devem

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

Usando textura • Mapeamento de textura melhora tudo: – calcula radiância baseado numa imagem

Usando textura • Mapeamento de textura melhora tudo: – calcula radiância baseado numa imagem (paramétrica) • 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

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); – pintá-las manualmente; – mapear 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, olhar no píxel correspondente na imagem de textura e usar isto para afetar a cor final

Especificando função de textura • Parametrização 2 D: – – alguns objetos têm parametrização

Especificando função de textura • Parametrização 2 D: – – alguns objetos têm parametrização natural esferas: usam coordenadas esféricas cilindro: usar coordenadas cilíndricas superfícies paramétricas (B-splines, Bézier): (u, v) • 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 3 D (textura sólida): – crie um mapa 3 D 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

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:

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: usando um “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 • Quais objetos são convexos e quais são côncavos? •

Bump mapping: um truque • Quais objetos são convexos e quais são côncavos? • Resposta: nenhum, estas imagens são todas planas. • Sistema visual humano está acostumado com a iluminação de cima para baixo • 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 • x_gradient = pixel(x-1, y) - pixel(x+1, y) • y_gradient = pixel(x,

Bump Mapping • x_gradient = pixel(x-1, y) - pixel(x+1, y) • y_gradient = pixel(x, y-1) - pixel(x, y+1)

Perturbando a normal

Perturbando a normal

Bump mapping • Mapeamento básico de textura pinta numa superfície suave • Tornando a

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

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 dizer a quantidade de perturbação que tipo de anomalia pode ser produzida? Esfera com mapa de texturas difuso Bump map Esfera com mapa de texturas difuso + bump map

Exemplo de “Bump mapping” Cilindro c/ mapa de texturas difuso + bump map

Exemplo de “Bump mapping” 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

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

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 textura sólida • Um array 3 D de valores de textura (algo

Mapa de textura sólida • Um array 3 D 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 3 D – definir uma função para gerar cor para cada ponto 3 D • 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) • Coloque sua cena dentro de um cubo •

Mapa ambiente (ou de reflexão) • Coloque sua cena dentro de um cubo • Pinte imagens nas faces internas do cubo para criar uma imagem de fundo que envolva o objeto (nuvens, montanhas, uma sala, etc. . . ). • Use o cubo para iluminar a cena dentro dele • Durante o cálculo de sombreamento: – jogue um raio vindo do observador para fora do objeto num ponto P – Intercepte o raio com o mapa do ambiente (o cubo) num ponto E – tome a cor do mapa do 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

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. 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 Open. GL • Construa sua imagem de textura – Dimensões da imagem

Texturas em Open. GL • Construa sua imagem de textura – Dimensões da imagem devem ser 2 n por 2 m – Este código assume imagens coloridas usando RGB • • • Pic *in; Gluint texname; in = tiff_read(filename, NULL); gl. Gen. Texture(1, &texname); gl. Bind. Texture(GL_TEXTURE_2 D, texname); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_WRAP_S, GL_REPEAT); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_WRAP_T, GL_REPEAT); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl. Tex. Image 2 D(GL_TEXTURE, 0, GL_RGB, in->nx, in->ny, 0, GL_RGB, GL_UNSIGNED_BYTE, in->pix);

Texturas em Open. GL • Colocando em modo textura 2 D: – gl. Enable(GL_TEXTURE_2

Texturas em Open. GL • Colocando em modo textura 2 D: – gl. Enable(GL_TEXTURE_2 D); – gl. Tex. Envf(GL_TEXTURE_ENV, GL_TEXTURE_ENVMODE, – GL_MODULATE); – gl_Bind. Texture(GL_TEXTURE_2 D, texname); • Para cada vértice: – gl. Tex. Coor 2 f(vert. s, vert. t); • Retira modo textura após terminar de desenhar: – gl. Disable(GL_TEXTURE_2 D);

Passos para mapeamento de textura • Criar um objeto com textura e especificar uma

Passos para mapeamento de textura • Criar um objeto com textura e especificar uma textura para o objeto. • Indicar como a textura deve ser aplicada a cada pixel • Habilitar mapeamento de textura • Desenhar a cena, suprindo ambos textura e coordenadas geométricas

Exemplo: tabuleiro • • • #include <GL/gl. h> #include <GL/glut. h> #include <stdlib. h>

Exemplo: tabuleiro • • • #include <GL/gl. h> #include <GL/glut. h> #include <stdlib. h> #include <stdio. h> • • • /* Create checkerboard texture */ #define check. Image. Width 64 #define check. Image. Height 64 static GLubyte check. Image[check. Image. Height][check. Image. Width][4]; static GLuint tex. Name;

Cria textura para o tabuleiro • • • • void make. Check. Image(void) {

Cria textura para o tabuleiro • • • • void make. Check. Image(void) { int i, j, c; for (i = 0; i < check. Image. Height; i++) { for (j = 0; j < check. Image. Width; j++) { c = ((((i&0 x 8)==0)^((j&0 x 8))==0))*255; check. Image[i][j][0] = (GLubyte) c; check. Image[i][j][1] = (GLubyte) c; check. Image[i][j][2] = (GLubyte) c; check. Image[i][j][3] = (GLubyte) 255; } } }

Inicializa parâmetros de textura • • • • void init(void) { gl. Clear. Color

Inicializa parâmetros de textura • • • • void init(void) { gl. Clear. Color (0. 0, 0. 0); gl. Shade. Model(GL_FLAT); gl. Enable(GL_DEPTH_TEST); make. Check. Image(); gl. Pixel. Storei(GL_UNPACK_ALIGNMENT, 1); gl. Gen. Textures(1, &tex. Name); gl. Bind. Texture(GL_TEXTURE_2 D, tex. Name); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_WRAP_S, GL_REPEAT); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_WRAP_T, GL_REPEAT); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl. Tex. Parameteri(GL_TEXTURE_2 D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl. Tex. Image 2 D(GL_TEXTURE_2 D, 0, GL_RGBA, check. Image. Width, check. Image. Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, check. Image); }

Mostra o tabuleiro • • • • • void display(void) { gl. Clear(GL_COLOR_BUFFER_BIT |

Mostra o tabuleiro • • • • • void display(void) { gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl. Enable(GL_TEXTURE_2 D); gl. Tex. Envf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); gl. Bind. Texture(GL_TEXTURE_2 D, tex. Name); gl. Begin(GL_QUADS); gl. Tex. Coord 2 f(0. 0, 0. 0); gl. Vertex 3 f(-2. 0, -1. 0, 0. 0); gl. Tex. Coord 2 f(0. 0, 1. 0); gl. Vertex 3 f(-2. 0, 1. 0, 0. 0); gl. Tex. Coord 2 f(1. 0, 1. 0); gl. Vertex 3 f(0. 0, 1. 0, 0. 0); gl. Tex. Coord 2 f(1. 0, 0. 0); gl. Vertex 3 f(0. 0, -1. 0, 0. 0); gl. Tex. Coord 2 f(0. 0, 0. 0); gl. Vertex 3 f(1. 0, -1. 0, 0. 0); gl. Tex. Coord 2 f(0. 0, 1. 0); gl. Vertex 3 f(1. 0, 0. 0); gl. Tex. Coord 2 f(1. 0, 1. 0); gl. Vertex 3 f(2. 41421, 1. 0, -1. 41421); gl. Tex. Coord 2 f(1. 0, 0. 0); gl. Vertex 3 f(2. 41421, -1. 0, -1. 41421); gl. End(); gl. Flush(); gl. Disable(GL_TEXTURE_2 D); }

Muda a forma caso necessário • • • void reshape(int w, int h) {

Muda a forma caso necessário • • • void reshape(int w, int h) { gl. Viewport(0, 0, (GLsizei) w, (GLsizei) h); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); glu. Perspective(60. 0, (GLfloat) w/(GLfloat) h, 1. 0, 30. 0); gl. Matrix. Mode(GL_MODELVIEW); gl. Load. Identity(); gl. Translatef(0. 0, -3. 6); }

Trata evento de teclado • • • void keyboard (unsigned char key, int x,

Trata evento de teclado • • • void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; default: break; } }

Rotina principal • • • • int main(int argc, char** argv) { glut. Init(&argc,

Rotina principal • • • • int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glut. Init. Window. Size(250, 250); glut. Init. Window. Position(100, 100); glut. Create. Window(argv[0]); init(); glut. Display. Func(display); glut. Reshape. Func(reshape); glut. Keyboard. Func(keyboard); glut. Main. Loop(); return 0; }

Resultado

Resultado

Entendendo melhor • Rotina make. Check. Image() gera a textura do tabuleiro; • init()

Entendendo melhor • Rotina make. Check. Image() gera a textura do tabuleiro; • init() inicializa mapemento de textura: – gl. Gen. Textures() e gl. Bind. Texture() nomeia e cria um objeto texturado para a imagem de textura. – gl. Tex. Image 2 D() especifica o mapa de textura em resolução completa • tamanho da imagem, tipo de imagem, localização e outras propriedades – 4 chamadas a gl. Tex. Parameter*() especificam como a textura será embrulhada e como as cores serão filtradas se não ocorrer um casamento exato entre pixels na textura e pixels na tela

Entendendo melhor • Em display(): – gl. Enable() habilita uso de textura. – gl.

Entendendo melhor • Em display(): – gl. Enable() habilita uso de textura. – gl. Tex. Env*() coloca o modo de desenho em GL_DECAL (polígonos são desenhados usando cores do mapa de textura, ao invés de considerar qual a cor que os polígonos deveriam ser desenhados sem a textura). – Dois polígonos são desenhados (note que as coordenadas de textura são especificadas com as coordenadas de vértices). – gl. Tex. Coord*() é similar a gl. Normal() (determina normais). – gl. Tex. Coord*() acerta as coordenadas de textura correntes; qualquer vértice sibsequente terá aquelas coordenadas de textura associadas com ele até que gl. Tex. Coord*() seja chamada novamente.

Uma rosquinha

Uma rosquinha

Uma rosquinha com textura

Uma rosquinha com textura

Programa exemplo (esfera) • #include <GL/gl. h> • #include <GL/glut. h>

Programa exemplo (esfera) • #include <GL/gl. h> • #include <GL/glut. h>

Programa exemplo (esfera) • • • • void init(void) { GLfloat mat_specular[] = {

Programa exemplo (esfera) • • • • void init(void) { GLfloat mat_specular[] = { 1. 0, 1. 0 }; GLfloat mat_shininess[] = { 50. 0 }; GLfloat light_position[] = { 1. 0, 0. 0 }; gl. Clear. Color (0. 0, 0. 0); gl. Shade. Model (GL_SMOOTH); gl. Materialfv(GL_FRONT, GL_SPECULAR, mat_specular); gl. Materialfv(GL_FRONT, GL_SHININESS, mat_shininess); gl. Lightfv(GL_LIGHT 0, GL_POSITION, light_position); gl. Enable(GL_LIGHTING); gl. Enable(GL_LIGHT 0); gl. Enable(GL_DEPTH_TEST); }

Programa exemplo (esfera) • • • void display(void) { gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Programa exemplo (esfera) • • • void display(void) { gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glut. Solid. Sphere (1. 0, 20, 16); gl. Flush (); }

Programa exemplo (esfera) • • • • void reshape (int w, int h) {

Programa exemplo (esfera) • • • • void reshape (int w, int h) { gl. Viewport (0, 0, (GLsizei) w, (GLsizei) h); gl. Matrix. Mode (GL_PROJECTION); gl. Load. Identity(); if (w <= h) gl. Ortho (-1. 5, -1. 5*(GLfloat)h/(GLfloat)w, -10. 0, 10. 0); else gl. Ortho (-1. 5*(GLfloat)w/(GLfloat)h, -1. 5, -10. 0, 10. 0); gl. Matrix. Mode(GL_MODELVIEW); gl. Load. Identity(); }

Programa exemplo (esfera) • • • • int main(int argc, char** argv) { glut.

Programa exemplo (esfera) • • • • int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glut. Init. Window. Size (500, 500); glut. Init. Window. Position (100, 100); glut. Create. Window (argv[0]); init (); glut. Display. Func(display); glut. Reshape. Func(reshape); glut. Main. Loop(); return 0; }

Resultado

Resultado