Mapeamento de Textura

Projeto desenvolvido na disciplina IA725 - Computação Gráfica I - primeiro semestre de 2011.

O objetivo do nosso projeto é apresentarmos uma introdução ao tema de Texturização, expondo suas principais técnicas. Abordamos as técnicas de texturização específicas (algoritmo): bump mapping, environment mapping, shadow mapping, Perlin noise texture mapping, e multitexturing.

Esta página resume alguns pontos apresentados na monografia relacionando as técnicas com implementações em OpenGL. Detalhes do funcionamento de cada uma das técnicas podem ser encontrados na monografia.

No final da página você poderá visualizar a monografia completa, o arquivo da apresentação e código dos programas desenvolvidos em C/OpenGL.


Equipe:

Carla Florentino de Souza
Edson Leite Araújo
Jennifer Chuin Lee


Conteúdo

  1. Introdução
  2. Implementação em OpenGL
  3. MipMapping
  4. Bump mapping
  5. Environment mapping
  6. Shadow mapping
  7. Downloads
  8. Bibliografia

Introdução

Quando os detalhes se tornam refinados e mais intrincados, a modelagem a partir de polígonos ou outras primitivas geométricas torna-se impraticável. Uma alternativa é mapear uma imagem, que contenha os detalhes desejados, produzidos de forma sintética ou digital, e mapeá-la sobre a superfície que se deseja produzir o efeito.

Esta técnica, primeiro pensada e desenvolvida por Catmull [3] e em seguida refinada por Blinn e Newell[2], ficou conhecida como mapeamento de textura (texture mapping). A imagem utilizada é chamada de mapa de textura (texture map) e seus elementos individuais são frequentemente chamados de texels.

Texture Mapping tornou-se uma poderosa técnica na adição de realismo às cenas geradas por computador e tem sido usada com muita frequência, na industria de jogos, produzindo efeitos muito bons a um custo relativamente barato, tendo em vista que mapas de textura são amplamente suportados nos hardwares gráficos.

Com o passar do tempo, percebeu-se que os mapas de tetxura podem carregar quaisquer tipos de informações e atualmente estão sendo utilizadas de três formas básicas:

1. O mapa de textura pode conter cores, que são aplicadas para a superfície, agindo de maneira semelhante a um adesivo sobre a mesma. Atuando desta maneira, os cálculos de iluminação são desnecessários pois a cor de um determinado pixel será sobreposta pela cor do pixel correspondente a ele no mapa de textura.

2. Pode conter atributos tais como cor, brilho ou transparência que afetam a aparência da superfície após a aplicação do modelo de iluminação. Neste caso, os atributos contidos no mapa de textura serão combinados com os resultados obtidos após a iluminação.

3. Em último caso, o mapa de textura pode também conter coeficientes de reflexividade, deslocamentos das normais ou outros parâmetros que podem ser utilizados no modelo de iluminação. Neste caso, os valores do mapa de textura modificam as propriedades da superfície, uma vez que são usados como entrada para o modelo de iluminação. Um exemplo disto é a técnica conhecida como Bump Mapping.

A seguir encontra-se uma relação de algumas técnicas abordadas na monografia.

voltar

Implementação em OpenGL

A implementação deste trabalho foi desenvolvido utilizando uma Interface de Programação de Aplicações, ou API, chamada OpenGL. OpenGL (Open Graphics Library) basicamente é uma biblioteca de rotinas gráficas e de modelagem, bastante utilizada em Computação Gráfica e Animação. E com OpenGL é possível implementar texturização de objetos, portanto apresentaremos neste a seguir resumidamente como é feito essa texturização em OpenGL e como utilizamos nas implementações.

Texturização em OpenGL

No desenvolvimento de programas que utilizam texturização de objetos, estes devem ser bastante dinâmicos e que sejam padrões. Com OpenGL, é possível fazer isso, controlando a maneira pela qual a sua textura é armazenada internamente, como ela é filtrada e como está envolvido quando está sendo aplicada a um objeto. Para fazer isso, é preciso se preocupar inicialmente com a criação de alguns parâmetros de textura e do ambiente da sua cena.
Começamos precisando criar o objeto que nomeie a textura desejada, já que em OpenGL precisa indexar todas as texturas diferentes existentes. Para isso, chamamos a função glGenTextures para alocar a textura:

GLuint texture;
glGenTextures( 1, &texture );

Utilizando a função glBindTexture, esta especifica qual é a textura que será utilizada a seguir.

glBindTexture( GL_TEXTURE_2D, texture );

Já com a textura especificada, podemos atribuir seus parâmetros de estado de ambiente da cena. A função glTexEnvf atribui as variáveis de ambiente da textura com a sua cena. Já o atributo GL_MODULATE simplesmente faz com que os dados das cores e do alfa da textura sejam multiplicados com a cor que for atribuida pela função glColor ou pela iluminação.

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

Depois, precisamos setar alguns parâmetros. Esses parâmetros fazem com que a textura tenha efeitos de filtragem, e de Mipmap.
Neste exemplo de parâmetro abaixo, define que quando a área de textura é a menor (GL_TEXTURE_MIN_FILTER), seja usado filtragem bilinear com o Mipmap mais próximo (GL_LINEAR_MIPMAP_NEAREST):

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );

A filtragem bilinear é um parâmetro que suaviza as texturas quando ela for maior ou menor que seu tamanho original.
E Quando a área da textura for a maior (GL_TEXTURE_MAG_FILTER), com filtragem bilinear da textura normal (GL_LINEAR) setamos o parâmetro:

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

E esses últimos parâmetros definindo como a textura será envolvido mais nas bordas do objeto com este tipo de parâmetro repetindo (GL_REPEAT).

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

Já setados os parâmetros necessários, temos que armazenar a textura para a memória, para que possa ser usado no programa. Isso é importante, já que em OpenGL, a textura é apenas um objeto que contém os dados da imagem que é carregada.
Para chamar essa função usamos assim:

glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);

Se nos parâmetros da textura for usado o Mip map, a função glTexImage2D não precisa ser usada. A função gluBuild2DMipmaps() é usada, pois ao mesmo tempo gera o Mip map, e armazena na memória.

Agora que temos a textura armazenada, é preciso aplicar a textura na geometria do objeto. Primeiro temos que habilitar o uso da textura armazenada:

glEnable( GL_TEXTURE_2D );

E depois usamos novamente o glBindTexture, para indicar pelo índice do objeto a textura a ser usada a partir deste código:

glBindTexture (GL_TEXTURE_2D, 13);

Agora podemos utilizar a textura e aplicar no objeto desejado. Para isso, é preciso especificar as coordenadas da textura antes de cada vértice do seu objeto criado, para poder aplicar a textura na face onde contem esses vértices. Aplica-se as coordenadas da textura pela função glTexCoord2f(), e logo depois associa-se ao vértice do objeto que está sendo modelado, glVertex3f().
Abaixo, temos um exemplo de textura sendo aplicado em um plano (GL_QUADS).

glBegin(GL_QUADS);

glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);

glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 0.0);

glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);

glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);

glEnd();

Para entender como isso acontece, podemos visualizar a seguinte Figura 1, que mostra o sistema de coordenadas da textura.


Figura 1 - Diagrama de Sistema de Coordenadas da Textura.


A Figura 1, mostra como o OpenGL interpreta seu sistema de coordenadas da textura armazenada. Chamando a função glTexCoord2f(x,y), o OpenGL coloca as coordenadas da textura nos pontos que desejar. Como no exemplo acima, nos vértices do plano (GL_QUADS), que dará o seguinte resultado:


Figura 2 - Resultado renderizado de Mapeamento de Textura


Nas implementações, utilizamos a classe de carregar imagem de formato .BMP, que carrega as imagens em dados na memória.

A seguir, mostraremos as implementações de algumas técnicas de texturização específicas.


voltar

Mip Mapping

Como mencionamos acima, um dos parâmetros a ser setado tem a opção de usar Mipmap. Mip Mapping é uma abordagem para o mapeamento de textura em que um mapa de textura original de alta resolução é escalado e filtrada em múltiplas resoluções, ou níveis, antes de ser aplicado na superfície de um objeto. Isso faz com que o OpenGL possa aplicar o nível adequado de detalhe para uma textura na renderização, ao invés de deformar a textura original.

Cada nível de mipmap gerado, é a metade do tamanho do mipmap anterior. Para calcular o mipmaps e usar em OpenGL, é possível criar seu próprio algoritmo para calcular e gerar mipmap, mas existe uma função que já faz isso para você, chamada gluBuild2DMipmaps(). Essa função gera um conjunto de mipmaps para uma determinada textura também faz a filtragem e o upload do mipmaps para a memória. Para usar essa função, apenas especificamos a altura (height) e comprimento (width) em pixels, e o ponteiro que aponta para os dados da imagem na memória (pixels):

gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGB, width, height, GL_RGB,GL_UNSIGNED_BYTE, pixels);

OpenGL selecionará automaticamente o melhor nível de detalhe a ser usado para a textura, mas pode ser definido com a função glTexParameter() usando GL_LINEAR_MIPMAP_NEAREST, por exemplo. Obtemos os seguintes resultados com a implementação:

//Sem Mipmap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

//Com Mipmap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

Figura 3 - Resultado da implementação sem Mip mapping.

Figura 4 - Resultado da implementação com Mip mapping.


A desvantagem de usar Mipmaps é que eles vão exigir memória adicional e alguma computação extra para gerá-los.

Clique aqui para acessar a seção de Downloads e baixar o código OpenGL que gerou as imagens acima.


Referência:
http://www.videotutorialsrock.com/opengl_tutorial/mipmapping/text.php
http://www.flipcode.com/archives/Advanced_OpenGL_Texture_Mapping.shtml

voltar

Bump mapping

Exibe superfície com aspecto rugoso ou ondulado sem a necessidade de modelar estas ondulações geometricamente.


Figura 5 - Resultado da implementação com Bump mapping.

A figura acima apresenta uma laranja(1) onde foi aplicada a técnica de Bump Mapping, e outra laranja(2) sem a técnica de Bump Mapping. Podemos perceber como a laranja(1) aparenta uma superfície rugosa ao contrário da laranja(2).


Implementação de Bump mapping

Implementação da imagem acima foi desenvolvida a partir da referência do tutorial do site Paul's Project sobre Bump mapping ( http://www.paulsprojects.net/tutorials/simplebump/simplebump.html ).

Nesta implementação além da utilização da técnica de Bump mapping, foi usado a técnica de Multitexturing, onde usou-se duas imagens como textura para o mesmo objeto.
Para usar a técnica de Multitexturing e da técnica de Cube map, usamos as extensões do OpenGL:

ARB_multitexture
ARB_texture_cube_map
ARB_texture_env_combine
ARB_texture_env_dot3

Figura 6 - Textura para colorir a laranja.



Figura 7 - Normal Map da laranja.

Clique aqui para acessar a seção de Downloads e baixar o código OpenGL que gerou a imagem acima.


Desvantagem de Bump mapping

Um problema encontrado com o uso da técnica Bump mapping pode ser verificado quando trabalhamos com sombras ou observamos a silhueta do objeto: repare que na figura abaixo à esquerda o contorno da sombra e da silhueta do objeto não está condizente com o aspecto rugoso do objeto. Isto ocorre por que, de fato a superfície do objeto não sofre alteração nenhuma em sua geometria.

Utilizando a técnica Displacement mapping pode-se evitar esse problema já que essa técnica altera a geometria do objeto usando o mapa de textura.


voltar

Environment mapping

Também conhecida como "reflection mapping", o objetivo deste mapeamento é renderizar objetos reluzentes exibindo em sua superfície o ambiente ao seu redor. Podemos encontrar várias técnicas onde a principal diferença está no formato do mapa de textura utilizado.

Cubic mapping

Técnica que utiliza um cubo como mapa de textura, ou seja, teremos seis sub-mapas que juntos compõem as faces de um cubo.

Sphere mapping

Técnica que utiliza como mapa de textura uma esfera. A figura abaixo foi gerada utilizando essa técnica.


Clique aqui para acessar a seção de Downloads e baixar o código OpenGL que gerou a imagem acima.

voltar

Shadow mapping

Utiliza o algoritmo de renderização de uma cena usando a localização da fonte de luz como posição do observador para computar os pontos de sombra: as superfícies visíveis apareceriam iluminadas e, as superfícies não visíveis apareceriam escurecidas.


Clique aqui para acessar a seção de Downloads e baixar o código OpenGL que gerou a imagem acima.

voltar
voltar

Bibliografia

[1] Blinn, J. F., Simulation of Wrinkled Surfaces, Computer Graphics, (Proc. Siggraph), Vol. 12, No. 3, August 1978, pp. 286-292.

[2] Blinn, J. F. and Newell, M. E., Texture and Reflection in Computer Generated Images. Comm. ACM, 19 (10), 1976, pp. 362-367.

[3] Catmull, E, Subdivision Algorithm for the Display of Curved Surfaces, PhD Thesis, University of Utah, 1974.

[4] Watt and Watt, Advanced Animation and Rendering Techniques, Addison-Wesley, 1992, pp. 199-201;

[5] P. S. Heckbert, Survey of Texture Mapping, IEEE Computer Graphics and Applications, Nov. pp. 56-67. 1986

[6] Cook, R. L., Carpenter, L., and Catmull, E., The Reyes Image Rendering Architecture, Comput Graph, Vol. 21, pp. 95-102, 1987 (SIGGRAPH 87).

[7] Miller G. S. and Ho man, C. R., Illumination and Reflection Maps: Simulated Objects in Simulaed and Real Environments. SIGGRAPH'84, Course Notes, July, 1984.

[8] Williams L., Casting Curved Shadows on Curved Surfaces. Computer Graphics, 12(3), pp. 270-274, 1978.

[9] Perlin, K., An Image Synthesizer. Computer Graphics, 19(3), pp. 287-296, 1985.

[10] Peachey, D. R., Solid Texturing of Complex Surfaces. Computer Graphics, 19(3), pp. 279-286, 1985.

[11] Lewis, J. P., Algorithms for Solid Noise Synthesis. Computer Graphics, 23(3), pp. 263-270. 1989.

[12] Bier, E. A. and Sloan, K. R., Two-part Texture Mapping, IEEE Computer Graphics and Applications, 6(9), 40-53, 1986.

[13] Feibush, E. A., Levoy, M. and Cock, R. L., Synthetic Texturing Using Digital Filters. Comput. Graph., SIGGRAPH'80 ,Vol. 14, pp. 294-301, 1980.

[14] Williams, L., Pyramidal Parametrics. Comput. Graph, SIGGRAPH'83, Vol. 17, pp. 1-11, 1983.

voltar