Universidade Federal do Vale do São Francisco Curso de Engenharia da Computação Computação Gráfica - 13 Prof. Jorge Cavalcanti jorge.cavalcanti@univasf.edu.br www.univasf.edu.br/~jorge.cavalcanti www.twitter.com/jorgecav
Uso de Texturas Os modelos de iluminação não são sempre apropriados para descrever todas as propriedades da superfície e um objeto, por exemplo, rugosidade e padronagem. Em princípio,é possível modelar esses detalhes com o acréscimo de componentes na geometria da superfície ou usando materiais de propriedades óticas distintas. Essa forma torna o processamento muito complexo, de modo que, na prática esses efeitos são modelados com o uso de mapas de textura. A textura é uma técnica que quando aplicada junto à iluminação, procura dar às superfícies dos objetos características que os façam parecer mais reais, quando comparados a simples técnicas de iluminação e sombreamento. Página 2
Uso de Texturas A idéia básica é reproduzir sobre a superfície do objeto as propriedades de alguma função ou mapeamento bidimensional. Para trabalhar com mapas de texturas é fundamental e ter um bom programa de composição e tratamento de imagens. Imagens podem ser obtidas em bibliotecas de texturas disponíveis na Internet. Mapa de textura Modelo Modelo texturizado Página 3
Uso de Texturas Mapas procedurais Um bitmap é uma imagem produzida por uma matriz fixa de pixels coloridos. Os mapas procedurais, por exemplo, um tabuleiro de xadrez, podem ser gerados por um algoritmo. Esses mapas dispensam a utilização de imagens e, podem ser inclusive tridimensionais: São muito usados para a síntese de cenas complexas ou aplicações em real-time (mármore, revestimentos, repetição de polígonos). Eles também são boas fontes para mapeamento de textura sintéticas. Página 4
Uso de Texturas As texturas podem ser de três tipos: Unidimensionais: Uma linha contendo um único pixel de altura. Útil para fazer dégradé em superfícies; Bidimensionais: Uma imagem tradicional, com largura e altura. De longe, o tipo mais usado. Tridimensionais: Consiste numa imagem tridimensional de modo que, dado a coordenada x, y e z de uma figura, a mesma coordenada x, y e z na imagem corresponderá a cor naquele ponto. Geralmente não é usada pois consome muita memória e porque o interior dos objetos dificilmente é visto. Uma vez mapeadas a um polígono, as texturas estão sujeitas a todas as transformações que ocorrem naquele polígono. Ou seja, elas irão rotacionar, mover ou escalar juntamente do polígono. Assim, podemos encarar a textura como se fosse efetivamente a pele de nossa geometria. Página 5
Uso de Texturas Texturas Unidimensionais: É apenas uma sequência de cores ou intensidades em um espaço linear de textura. Assim como as demais imagens criadas pela OpenGl, as texturas podem ser criadas de várias formas: como intensidades (níveis de cinza), como cores RGB, níveis de transparência, etc. No exemplo a seguir, a textura é definida por um vetor de bytes, onde cada posição representa uma intensidade (nível de cinza). http://migre.me/hgjsk GLubyte textura[] = { 0,0,0,0,64,64,64,64,128,128,128,128,192,192,192,192 }; Página 6
Uso de Texturas Texturas Unidimensionais: Cada textura deve uma identificação única (inteiro). void glgentextures(glsizei n, Gluint *textures) O n indica quantos id s devem ser gerados e textures deve apontar para um vetor de inteiros (ou único inteiro). Cada id gerado é armazenado na variável apontada por *textures. A seguir a textura corrente é especificada pela função glbindtexture (Glenum target, Gluint texture). target indica o tipo de textura (GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, ente outros. texture é um id válido de textura, gerado com o glgentextures. Página 7 02/02/2014
Uso de Texturas Texturas Unidimensionais: O próximo passo é enviar a textura para OpenGl (upload), usando a função: void glteximage1d (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) target: tipo de textura (GL_TEXTURE_1D) level: deve ser sempre 0, a menos que se use mipmap (cap 16.4 do livro). internalformat: como a textura será armazenada internamente. width: tamanho da textura (potência de 2). border: define a presença ou não de borda na textura (0 ou 1). format: forma como a textura está definida originalmente. type: tipo de dados armazenados na textura. *pixels: aponta para o vetor contendo a textura. Página 8 02/02/2014
Uso de Texturas Texturas Unidimensionais: O parâmetro internalformat geralmente contém GL_LUMINANCE (intensidade), GL_INTENSITY, GL_RGB ou GL_RGBA. O format usualmente é GL_RGB, GL_RGBA ou GL_LUMINANCE (intensidade apenas). O type geralmente é GL_UNSIGNED_BYTE, indicando que os dados estão armazenados como bytes sem sinal. Mas também podem ser GL_SHORT, GL_INT, GL_FLOAT com ou sem sinal. No exemplo a seguir, define-se uma textura a partir de níveis de cinza (GL_LUMINANCE), especificados em bytes sem sinal (GL_UNSIGNED_ BYTE), também armazenando internamente como níveis de cinza. http://migre.me/hglln Página 9 02/02/2014
Uso de Texturas Texturas Unidimensionais: O mapeamento é realizado pela associação das coordenadas de textura a cada vértice de uma superfície. A figura abaixo (livro-texto), mostra como o processo é realizado. A coordenada da textura é denominada s, recebendo o valo 0.0 nos vértices da esquerda e 1.0 nos da direita, fazendo com que a textura seja aplicada uniformemente sobre a superfície. Página 10 O mapeamento é realizado durante a especificação dos vértices da primitiva, pela função gltexcoord1f (GL float s). O parâmetro s é a coordenada a ser associada com o vértice corrente. glbegin(gl_quads); gltexcoord1f(0); glvertex3f(-1,-1,0); gltexcoord1f(1.0); glvertex3f( 1,-1,0); gltexcoord1f(1.0); glvertex3f( 1, 1,0); gltexcoord1f(0); glvertex3f(-1, 1,0); glend(); 02/02/2014
Mapeamento de Texturas Funções ou imagens que são mapeadas sobre uma superfície. Tal função ou imagem é chamada de mapa de textura. Analogia com colagem de decalque sobre um objeto. Página 11
Mapeamento de Texturas Arranjos de texturas Armazenar um arranjo de cores (3D ou 2D) e associá-los a uma posição espacial. Assume-se, para o caso 2D, que as dimensões nas quais a textura será mapeada são as dimensões u e v. O mapa de texturas (imagem) tem dimensões n x e n y. n y n x v u Página 12
Mapeamento de textura Em um arranjo 2D, a textura é uma imagem de tamanho n x, n y. Cada pixel dessa imagem é chamado de texel (texture element). Dependendo do mapeamento, cada texel pode ocupar vários pixels da imagem final, ou vice-versa. n y n x Página 13
Mapeamento de textura Principais tipos de mapeamento: Esférico: coordenadas uv são mapeadas segundo coordenadas polares esféricas. Planar: coordenadas uv mapeadas ortogonalmente. Cilíndrico: coordenadas uv são mapeadas segundo coordenadas polares cilíndricas. Cúbico: coordenadas uv mapeadas ortogonalmente nos seis planos de um cubo. Página 14
Mapeamento esférico Exemplo: Página 15
Mapeamento planar Exemplo: Página 16
Mapeamento cilíndrico Exemplo: Página 17
Mapeamento cúbico Exemplo: Página 18
Outros mapeamentos de texturas Mapeamento de superfícies paramétricas: Ao renderizar uma superfície paramétrica, dispensamos o tipo de forma de mapeamento (esférico, cilíndrico, cúbico) e tratamos os parâmetro uv da superfície como parâmetros uv normalizados do mapa de textura. Página 19
Mapeamento de Reflexão O mapeamento de reflexão (Environment mapping) é o tipo do mapeamento que reflete na superfície dos objetos os elementos que compõem a cena. Pode ser feita a partir de duas formas: A primeira é envolver a figura com um cubo, onde em cada face com uma textura que se deseja projetar. Para cada vértice do objeto, um vetor de reflexão é calculado, e indica uma das seis imagens para aquela face/superfície. Página 20
Mapeamento de Reflexão Mapeamento de reflexão: Uma segunda forma é gerar uma única imagem de uma superfície esférica refletindo o ambiente. Página 21
Bump Map Quando utilizamos uma fotografia de uma superfície áspera como mapa de textura, a superfície renderizada não fica muito correta. A direção da fonte de luz utilizada para criar o mapeamento é diferente da direção da iluminação do sólido. Uma técnica para amenizar esse efeito, dando uma perturbação na normal à superfície antes de aplicar o modelo de iluminação. Essa perturbação produz um deslocamento virtual na posição dos pontos da superfície. Página 22
Bump Map Bump Map é uma técnica usada para adicionar realismo sem modificar a geometria ao objeto. Essa técnica adiciona um sombreamento nos pixels, produzindo uma ilusão de relevo no objeto renderizado. A cor de uma superfície está relacionada com ângulo entre o vetor normal da superfície e a direção da luz. Em uma superfície plana, o vetor normal é o mesmo para toda a superfície, logo a cor da superfície será sempre a mesma. No bump map, as propriedades de refração da luz são usadas para indicar quais partes são mais escuras ou mais claras Página 23
Bump Map Textura Bump Map Parede sem Bump Map Parede com Bump Map Página 24
Texturas 2D em OpenGl A utilização de mapeamento de texturas 2D no OpenGl é um procedimento complexo, pois existem variações e diversas funções de manipulação. O uso de texturas requer a execução de dois passos distintos: a CARGA e a APLICAÇÃO da textura. O mapeamento de textura 2D em OpenGL consiste em carregar uma imagem de um arquivo e "colar" esta imagem na superfície do(s) objeto(s). É importante salientar que a largura e a altura desta imagem devem ser potências de 2. Página 25
Texturas 2D em OpenGl Os passos para o mapeamento de textura em Opengl são: - Ler uma imagem e armazenar num objeto adequado; - Criar um identificador para a textura; - Definir a textura em OpenGL; - Especificar como a textura será aplicada em cada pixel (filtros); - Habilitar o mapeamento de textura; - Desenhar os objetos fornecendo uma coordenada de textura para cada coordenada geométrica. Obs: Mapeamento de textura funciona apenas no modo RGBA. glutinitdisplaymode ( GLUT_DEPTH GLUT_DOUBLE GLUT_RGBA ) Página 26 02/02/2014
Texturas 2D em OpenGl Função para definir uma textura 2d: void glteximage2d (GLenum target, GLint level, GLint components, GLsizei width, GLint height, GLenum format, GLenum type, const GLvoid *pixels) target: GL_TEXTURE_2D level: nível de detalhe da imagem de textura components:número de valores de cor para cada pixel (RGB=3, RGBA=4) width e height: tamanho da imagem de textura (devem ser potências de 2, isto é, a imagem de textura deve ter dimensões múltiplas de 2). format: tipo de valor de cor esperado (GL_ALPHA, GL_COLOR_INDEX, GL_RED, GL_RGB, GL_RGBA,...) type: indica o formato e tipo de dado (GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_BITMAP,...) pixels: textura Página 27
Texturas 2D em OpenGl OpenGL tem três modos de aplicação da textura: GL_MODULATE Ajusta valores de cor e iluminação com a imagem de textura (mais usado) GL_DECAL Usa apenas a imagem de textura (cor e iluminação não alteram a aparência da textura) GL_BLEND Usado com um ou dois componentes de textura (imagem de textura é misturada com a cor de textura e com as informações de cor e iluminação). void gltexenvi(glenum target, GLenum pname, TYPE param) target deve ser GL_TEXTURE_ENV pname é GL_TEXTURE_ENV_MODE param pode ser GL_DECAL, GL_MODULATE,GL_BLEND Página 28 02/02/2014
Texturas 2D em OpenGl Filtros de textura: Após especificarmos a imagem precisamos especificar como ela será tratada, pois as imagens são retangulares e podem ser aplicadas a objetos não retangulares. Existem 2 classes de filtros para texturas: Filtro de Magnificação, caso a porção da imagem mapeada seja maior que a porção definida e Filtro de Minimificação, caso a porção da imagem mapeada seja menor que a porção definida. Página 29 02/02/2014
Texturas 2D em OpenGl Filtros de textura: Filtros são usados para interpolar pixels de textura. A função para a especificação dos filtros é: gltexparameteri(gl_texture2d,filtro,procedimento), onde filtro é: GL_TEXTURE_MIN_FILTER para polígonos que são menores que a imagem de textura; GL_TEXTURE_MAG_FILTER para polígonos que são maiores que a imagem de textura. Procedimentos: GL_NEAREST: Utiliza o texel cujas coordenadas se aproxima do centro do Pixel, pode causar aliasing; GL_LINEAR: Utiliza uma função linear para combinar os texels envolvidos no processo, produz resultados visivelmente melhores; Página 30 02/02/2014
Texturas 2D em OpenGl Carga da Textura - Para a aplicação da textura é preciso criar uma relação entre os vértices da textura e os vértices dos polígonos sobre os quais se desenha mapear a textura escolhida. Na figura a seguir as letras A, B, C e D definem os vértices da textura e os vértices A1, B1, C1 e D1 os vértices de polígono 3D onde deve ser mapeada esta textura. O processo de mapeamento de texturas em OpenGL consiste em "aplicar" a imagem 2D sobre o polígono 3D de forma que os pontos A, B, C e D sejam encaixados sobre os pontos A1, B1, C1 e D1. Página 31 02/02/2014
Texturas 2D em OpenGl Para permitir a construção desta correspondência entre a imagem 2D e o polígono 3D usa-se a função gltexcoord2f antes da definição do ponto 3D. Por exemplo: gltexcoord2f(0.0f,0.0f); glvertex3f(1.0f,-1.0f,1.0f); define que o ponto (0.0, 0.0) da textura 2D corresponde ao ponto (1.0, -1.0, 1.0) do polígono 3D. O sistema de coordenadas da textura tem como (0,0) o ponto inferior esquerdo da imagem e como (1,1) o ponto superior direito. Ou seja, na imagem acima temos as seguintes coordenadas para os pontos A, B, C e D. Página 32 02/02/2014
Texturas 2D em OpenGl O sistema de coordenadas da textura tem como (0,0) o ponto inferior esquerdo da imagem e como (1,1) o ponto superior direito. Ou seja, na imagem abaixo temos as seguintes coordenadas para os pontos A, B, C e D. Vértice da Textura Coordenada A (0,1) B (1,1) C (1,0) D (0,0) Supondo que o polígono 3D é a face lateral direita de um cubo de aresta 2 com o centro no ponto (0,0,0) teremos as seguintes coordenadas: Vértice do Polígono 3D Coordenada Página 33 A1 1.0, 1.0, 1.0 B1 1.0, 1.0, -1.0 C1 1.0, -1.0, -1.0 D1 1.0, -1.0, 1.0 02/02/2014
Texturas 2D em OpenGl O mapeamento da textura sobre o polígono se dá através do seguinte trecho de código: // Define a textura corrente glbindtexture ( GL_TEXTURE_2D, texture_id[0] ); // GL_TEXTURE_2D ==> define que será usada uma textura 2D (bitmaps) // texture_id[cube_texture] ==> define o número da textura // associa cada vértice do polígono a um ponto da textura gltexcoord2f(1.0f, 0.0f); glvertex3f( 1.0f, -1.0f, -1.0f); gltexcoord2f(1.0f, 1.0f); glvertex3f( 1.0f, 1.0f, -1.0f); gltexcoord2f(0.0f, 1.0f); glvertex3f( 1.0f, 1.0f, 1.0f); gltexcoord2f(0.0f, 0.0f); glvertex3f( 1.0f, -1.0f, 1.0f); Códigos Exemplos: http://migre.me/23oif - arquivo TGA http://migre.me/23rnb - arquivo JPG Página 34 02/02/2014