Upload
dinhcong
View
220
Download
0
Embed Size (px)
Citation preview
04/12/2011 Leandro Tonietto
Mapeamento de Texturas
Leandro ToniettoComputação GráficaJogos [email protected]://professor.unisinos.brltonietto/jed/cgr/textura.pdfAbr-2012
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 2
Sumário
IntroduçãoConceitosProcessoOpenGL e exemplosMipmappingObjetos de texturasPróximos passos.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 3
Introdução
Modelos de iluminação e sombreamento são adequados para a modelagem de objetos monocromáticos e para simular diferentes efeitos produzidos pelas combinações das componentes de materiais.Entretanto, superfícies com detalhamento interno não são trivialmente simuladas com estes modelos. Imagine, por exemplo, a textura de uma madeira.Uma solução primária seria a simulação desses detalhes com polígonos.
Sobre um polígono base, cria-se outros polígonos que tomam como valores iniciais as informações de materiais do polígono base e embutem a variação necessária para simular o efeito mais realístico possível. A renderização dos polígonos de detalhe é feita sobre a do polígono base.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 4
Introdução
Entretanto, o trabalho é árduo, computacionalmente oneroso e o efeito pode não ficar realístico.Solução: utilização de texturas para melhorar o realismo das cenas renderizadas.O processo chama-se mapeamento de textura.Iniciou com Catmull em 1974, que utilizou preenchimento de polígonos com imagem para simular detalhamento e realismo visual.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 5
Conceitos
Texture mapping (mapeamento de textura)A informação de detalhe para o mapeamento pode ser uma imagem (tal como uma foto) ou uma gerada computacionalmente por uma função, chamada textura procedural.A imagem ou textura é chamada de texture map.Os elementos do mapa de textura são chamados de texels.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 7
Processo
Uma mapa de textura está num sistema de referência da própria textura e é normalizado (0 a 1).A idéia básica é que, para cada pixel [x,y] a ser renderizado, existe um texel [u,v] no espaço do mapa com a informação a ser utilizada na renderização.O valor mapeado é utilizado para substituir, ou para se somar, aos valores calculados nos modelos de iluminação e sombreamento.Um pixel pode estar relacionado a mais de um texel. Neste caso, os texels são somados e ponderados para determinar o melhor valor para o pixel.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 8
Processo
Problema: Mapas são 2D e objetos, em geral, 3D.Para obter informação de textura:
Pontos são parametrizados para 2 coordenadas (s,t)
Para encontramos a cor da textura, pegamos um ponto (x,y,z) da superfície e mapeamos no espaço de texturaUsamos (s,t) como índices na imagem da textura
Polígonos:As coordenadas (s,t) são especificadas nos vértices(s,t) são interpolados para outros pontos
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 9
Processo
0,0
32,32
0,0
1,1
Map(0,1)
Map(1,0)
Map(0,0)
Textura (0,0,32,32)
Mapa (0,0,1,1)
Polígono mapeado
Polígono diferente com mesmo mapeamento
Map(1,1)
Map(0,1)
Map(1,0)Map(0,0)
Map(1,1)
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 10
Interpolação de textura
Especificar onde os vértices no sistema de referência do universo (SRU) são mapeados para o espaço de textura.Interpolar linearmente o mapeamento dos outros pontos diretamente no espaço de textura
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 12
Mapeamento de texturas
O mapeamento de texturas é feito no espaço de imagem quando o polígono é rasterizado Quando descrevemos uma cena, imaginamos que a textura será interpolada no espaço do universoProblema: distâncias iguais no espaço do universo não significam distâncias iguais em uma imagem projetada em perspectiva!Perspective correct texture mapping resolve o problema, mas é menos eficiente
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 13
Texturas no OpenGL
O processo de texturização de objetos no OpenGL envolve alguns passos básicos (e muitos outros para se chegar ao resultado desejado):
Primeiro passo: carregar a textura de um arquivo num formato de imagem: jpg, tga, gif, pnm, png, bmp e etc. Isto é de responsabilidade do programador.Um passo alternativo é computar alterações de tratamento de imagem para melhorar algum aspecto visual da textura (blur, sharpen, sépia, tons-de-cinza, negativo, saturação, troca de cores e etc.)
Ver especificação do formato PNM no site da disciplina de Processamento Gráfico
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 14
Texturas no OpenGL
Depois, carregar os bytes da imagem para o estado de textura do OpenGL. Pode-se usar:
void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border,GLenum format, GLenum type, void *data);void glTexImage2D(target, level, internalformat, width, height, border, format, type, data);void glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, data);
Estes métodos indicam ao OpenGL como tratar os dados recebidos
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 15
Texturas no OpenGL
Argumentos das funções:Target: GL_TEXTURE_1D, GL_TEXTURE_2D ou GL_TEXTURE_3D. Usado conforme a função.Level: nível de mipmapping, zero para não usar (veremos mais sobre mipmapping)InternalFormat: representação interna da cor. Como ela será armazenada: GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB e GL_RGBA.Width, height e depth: são as dimensões da textura, conforme o caso. Em geral são potencias de 2 (1, 2, 4, 8, 16, 32, ...), por questões de otimização de performance em hardware. Não precisam ser quadrados.Border: estabelece uma borda na textura; padrão é zero.Format: formato em que o texel aparece (ver tabela 8.2 em [3])Type: tipo de dado em que pixel está gravado.Data: são os bytes da imagem carregada do disco.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 16
Texturas no OpenGL
Tabela dos formatos (retirado de [3]):
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 17
Texturas em OpenGL
Próximo passo é habilitar/desabilitar estado de textura no OpenGL:
glEnable(GL_TEXTURE_2D) e glDisable(GL_TEXTURE_2D)
Apenas um estado por vez pode estar habilitado.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 18
Texturas em OpenGL
Por fim, fazer o mapeamento propriamente dito:
Para cada vértice do polígono, especifica-se uma coordenada de textura.As coordenadas são valores de ponto flutuante, normalizados: 0.0 a 1.0
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 19
Texturas em OpenGL
Comando para enviar o mapeamento:glTexCoord1f(s), glTexCoord2f(s,t) ou glTexCoord3f(s,t,r)
Usar sempre o par coordenada e vértice:glTexCoord2f(0, 1);
glVertex2f(0, 1);
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 20
Texturas em OpenGL
Exemplo do livro [3], pirâmide texturizada:
Ver executável e código fonte do exemplo.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 21
Texturas em OpenGL
Ambiente de textura (texture environment):Modo do ambiente de textura indica ao OpenGL como misturar cores com texels:
glTexEnvi(GLenum target, GLenum pname, GLint param);Variações: f, iv e fvNo exemplo da pirâmide:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 22
Texturas em OpenGL
Modos de ambiente de textura (texture environment modes):
Modulate (GL_MODULATE): multiplica a cor do texel pela cor da geometria (após cálculos de iluminação)
Permite que o resultado final tenha os detalhes da textura com as características de iluminação do sombreamento.
Replace (GL_REPLACE): substitui a informação de sombreamento pela cor da textura. Pode ser combinado com canal alpha para produzir efeitos de degradê.Decal (GL_DECAL): faz o efeito de um adesivo. A textura é plotada sobre as informação de sombreamento e, aonde, tiver alpha < 1.0, aparece alguma porção do sombreamento.Blend (GL_BLEND): mistura uma cor com a textura:
glTexEnvi(GL_TEXTURE_ENV, TEXTURE_ENV_MODE, GL_BLEND);glTexEnvfv(GL_TEXTURE_ENV, TEXTURE_ENV_COLOR, umaCor);
Add (GL_ADD): adiciona as cores da textura e de sombreamento. Valores acima de 1, reduzidos a 1.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 23
Texturas em OpenGL
Um pouco além do básico...Na “vida real”, os programadores precisam mais do que simplesmente mapear pontos da imagem para vértices.Muitos parâmetros podem ser informados para favorecer a qualidade visual do mapeamento.Embora, ainda seja possível prever alguns problemas de mapeamento e embutir na textura as deformações necessárias para realizar um mapeamento ideal. É uma solução difícil e ainda assim pode necessitar de ajustes.OpenGL permite definir parâmetros de mapeamento, que influenciam a forma a textura será tratada após o mapeamento.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 24
Texturas em OpenGL
Parâmetros em OpenGL:glTexParameterf(GLenum target, GLenum pname, GLfloat param);
Variantes: i, fv ou ivTarget: GL_TEXTURE_1D, _2D ou _3DPname é o nome do parâmetro.Param são os dados do parâmetro.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 25
Texturas em OpenGL
Basic Filtering:Para um resultado interessante ou pelo menos bom, além do mapeamento, devemos fazer uso de alguns artefatos para melhor o resultado.Um problema comum é o que acontece quando a textura é esticada ou comprimida.Algum procedimento deve ser feito quando falta alguma informação ou quando há uma redução de pixels.O processo que trata deste problema é chamado de filtering. Ele é executado na magnificação e na minificação dos texels (magnification e minification). As constantes associadas são, respectivamente: GL_TEXTURE_MAG_FILTER e GL_TEXTURE_MIN_FILTER.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 26
Texturas em OpenGL
Nearest Neighbor Filtering:Mais rápido e mais simplesQuanto falta algum cor, a cor do vizinho mais próximo é utilizada.Resultado é uma imagem “pixelized”
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 27
Texturas em OpenGL
Linear Filtering:Mais complexo, melhor resultado e mais lento
Este é um problema considerado superado, pois o custo computacional se tornou desprezível com implementação em hardware.
A cor de um texel faltante é calculada pela média ponderada (interpolação linear) dos seus vizinhos.Resultado é caracterizado com “fuzzy” graphics; um resultado mais suavizado.
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 28
Texturas em OpenGL
X
NEAREST LINEAR
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 29
Texturas em OpenGL
Textura com cartoons (cell-shading)Uso de textura 1D para desenhos animados.Preenchimento é feito com cor sólida e usando GL_NEAREST.A idéia básica é usar as normais da superfície e o vetor da luz para indicar qual é a cor de preenchimento dos pixels. Calculando o produto escalar.
Exemplo TOON do livro [3].
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 30
Texturas em OpenGL
Texture WrapO que fazer nas fronteiras da textura? Especialmente quando for necessário acessar um valor que estaria “fora” da textura? Pode-se repetir a textura ou simplesmente “cortar” nas bordas (repeat ou clamp).Deve ser indicado por dimensão da textura o procedimento a ser executado:
GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T e GL_TEXTURE_WRAP_R.
O modo GL_REPEAT, simplesmente repete a textura nas dimensões escolhidas. Bom para imagens tileble.
Influencia no filtering GL_LINEAR.O modo GL_CLAMP os pixels faltantes são obtidos da cor definida para a borda: GL_TEXTURE_BORDER_COLOR em glTexParameterfv(...).GL_CLAMP_TO_EDGE, obtém pixels faltantes repetindo os pixels das bordas.GL_CLAMP_TO_BORDER, pixels da última linha e última coluna são carregados como borda e valores são cortados até aquele ponto.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 31
Texturas em OpenGL
Texture WrapRepeat: Textura é repetida
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
Clamp: os valores são truncados (mantidos entre 0 e 1)glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP)
Podemos especificar uma cor de borda glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, R,G,B,A)
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 33
Texturas em OpenGL
Exemplo imagem tileble:
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 34
Texturas em OpenGL
Algoritmos de síntese de texturas conseguem gerar texturas a partir de amostras de imagem.
Objetivo: gerar uma nova textura que contenha o mesmo padrão visual da amostra. Idealmente, a nova textura não deve parecer uma composição de tiles regulares.
Veremos mais sobre síntese de texturas
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 35
Mipmap
Problemas:Diferentes resoluções objeto podem parecer distorcidas por causa do tamanho da textura. Problema com a perspectivaTextura com informações prontas para o mapeamento em perspectiva consomem muita memória.
Solução:Mipmap – “multum in parvo” (Muitas coisas num mesmo lugar).A idéia é carregar muitas texturas de resoluções diferentes para atender cada a cada tamanho visualizado.Quando o objeto está próximo o maior nível é utilizado, quando o objeto está longe um nível menor (adequado) é calculado e utilizado para o mapeamento.
Suponha uma textura a ser mapeada e que seja deseja gerar todos os mipmappings possíveis de menor resolução (dividindo ao meio), qual é a quantidade de memória necessária para armazenar todos os mipmappings?
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 37
Mipmap
Os níveis de Mipmap são carregados com glTexImageAgora deve-se usar o parâmetro level.
Onde: primeiro nível é o zero, depois 1, 2, ...Parâmetros associados:
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0)glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 3)
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 38
Mipmap
Filtering com mipmapNearest ou LinearDuas etapas: primeiro o filtro de nível e depois o seletor de nível.
GL_FILTRO_MIPMAP_SELETORGL_NEAREST – executa nearest filtering sobre o primeiro nível do mipmap.
GL_LINEAR – executa filtering sobre primeiro nível do mipmap.GL_NEAREST_MIPMAP_NEAREST – executa nearest para o nível e entre vizinhos.GL_NEAREST_MIPMAP_LINEAR – executa nearest para o nível e linear entre vizinhosGL_LINEAR_MIPMAP_NEAREST – seleciona nearest nível e executa interpolação linear.GL_LINEAR_MIPMAP_LINEAR – seleciona e executa interpolação linear. Trilinear interpolation.
Mais indicado para jogos: GL_LINEAR_MIPMAP_NEARESTQualidade de filtragem da interpolação e agilidade na escolha do nível.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 39
Mipmap
Geração “automática” de níveisAo invés de carregar todas as imagens de todos os nível é possível utilizar-se de duas soluções:
gluScaleImage() – gera uma versão escalada da imagemglBuild2DMipmaps() – cria versões escaladas de uma imagem e associa com o nível mipmap adequado:
int gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLint width, GLint height, GLenum format, GLenum type, const void *data);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE) – gera uma versão escalada da imagem em hardware. A partir da versão 1.4 da OpenGL. A cada chamda a glTexImage() para o nível 0, os demais são computados automaticamente.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 40
Mipmap
LOD BIASglTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.5)
Interfere no cálculo de escolha do nível de mipmap.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 41
Objetos de textura
Até este ponto, vimos como definir uma textura e seus parâmetros no estado de textura do OpenGL.Algumas aplicações (jogos) requerem diversas texturas.Troca de estados com as funções glTexImage e glBuildMipmap a todo instante tornam o processo muito oneroso. No caso de jogos, proibitivo.Neste sentido, utiliza-se objetos de textura.
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 42
Objetos de textura
Primeiro passo consiste indicar uma quantidade de objetos de textura:glGenTexture(GLsizei n, GLuint *textures);n – é o tamanho do array de texturas*textures – é o array de identificadores.
Para trocar o estado de textura atual:glBindTexture(Glenum target, GLuint texture)target – GL_TEXTURE_1D, GL_TEXTURE_2D ou GL_TEXTURE_3Dtexture – é o identificador do objeto de textura.
Para remover objetos de textura:glDeleteTextures(GLsizei n, GLuint *textures);
Os dados relativos aos objetos de textura devem ser carregados na inicialização do programa e, cada etapa de redesenho, deve-se fazer a troca de estados entre os objetos, conforme a necessidade.
Ver exemplo TUNNEL do livro [3]. O exemplo demonstra o uso de mipmaps e mútiplas texturas
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 43
Objetos de texturaExemplo considerando várias texturas no modelo do OBJGeração de ids de texturas para todas as imagens lidas (uma para cada material):int *ids; Mesh *mesh = new Mesh;vector<Material> mats;int main(int argc, char **argv){ OBJReader reader; reader.open(“algumo.obj”, mesh, &mats); // descobrir quantos materiais tem textura (texCount)... ids = new int[texCount]; glGenTexture(texCount, ids); for pelos materiais if(mats[i].hasTexture()){ Image *img = mats[i].getTexture(); // associando id com textura mats[i]->setTextureId(ids[k++]); glBindTexture(GL_TEXTURE_2D, img->getId()); glTexImage2D(GL_TEXTURE_2D, GL_RGB, img->getWidth(), img->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, img->getPixels()); free(img->getPixels()); // liberar memória! }
junto ao glBindTexture passar também outros parâmetros relacionados a textura.
Modificar de acordo com o tipo de dados do vetor de pixels da classe Image
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 44
Objetos de textura
Resolvendo o mapeamento na hora do desenho:for dos grupos GLuint tid = grupos[i]->getMaterial()->getTextureId(); glBindTexture(GL_TEXTURE_2D, textures[tid]); glBegin(GL_TRIANGLES); // ou a primitiva mais adequada for das faces do grupo Face *f = grupo->getFace(j); float *vt = mesh->getTextCoord(f->getTextCoord()); Vertex *v = mesh->getVertex(f->getVertex()); glTexCoord2f(vt[0], vt[1]); glVertex3f(v[0], v[1], v[2]); glEnd();
Ver exemplo TUNNEL do livro [3]. O exemplo demonstra o uso de mipmaps e mútiplas texturas
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 45
Textura Residentes
As texturas utilizadas no mapeamento são carregadas para uma área de memória de alta performance de textura, no hardware gráfico.OpenGL faz uso desta área de memória sempre que uma textura tem que ser renderizada.Entretanto, esta é uma área de memória com limite de tamanho. O OpenGL substitui as texturas conforme a necessidade.É possível, contudo, determinar quais texturas devem ficar residentes:
GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences);Aquelas texturas que estão definidas como GL_TRUE, ficarão nesta área de memória.
O OpenGL utiliza algoritmo MFU (most frequently used) para definir quem permanece residente na área de textura. Também é possível definir prioridades para as texturas e, desta forma, interferir no algoritmo e deixar alguma textura específica:
void glPrioritizeTextures(GLsizei n, const GLunit *textures, const GLclampf *priorities);
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 46
Texturas em OpenGL
Outros aspectos a serem estudados:Uso do color bufferAtualização de partes da textura, com glTexSubImageMatriz de texturas, que permite transformações sobre a textura (translação, escala e rotação), e que inclusive são aplicadas a parte do mapeamento.Filtragem de textura anisotrópica prove qualidade superior na filtragem.Adicionar efeitos de especularCompressão de texturas
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 47
Texturas em OpenGL
Mapeamento de texturas mais avançado:Síntese de texturas procedurais e baseado em imagemEnvironment mapping – iluminação armazenada em um mapa de texturas
Simula reflexão de superfícies brilhantes/metálicasBump-mapping altera a normal da superfície
Geometria fica mais simples, mas o contorno do objeto pode parecer estranho
Displacement mapping adiciona um deslocamento a cada ponto da superficie
Gemoetria também fica mais simplesNormal mapping
Similar ao bump-mapping, mas neste caso temos uma “textura” de normais
quarta-feira, 26 de setembro de 12
04/12/2011 Leandro Tonietto 48
Referências bibliográficas
1. Slides sobre CG dos professores: Christian Hofsetz, Cristiano Franco, Marcelo Walter e Soraia Musse.
2. FOLEY!!3. WRIGHT Jr., Richard S; LIPCHAK,
Benjamin; HAEMEL, Nicholas. OpenGL Superbible: Comprehenive Tutorial and Reference. 4 ed. Addison-Wesley, 2007.
quarta-feira, 26 de setembro de 12