Baixe o app para aproveitar ainda mais
Prévia do material em texto
DESCRIÇÃO Conceitos do sistema de coordenadas e transformações, das projeções geométricas e da câmera virtual, e formas de implementação dessas funcionalidades na biblioteca OpenGL a partir do uso da linguagem de programação Java. PROPÓSITO Compreender os conceitos e as funções da biblioteca OpenGL para aplicações de computação gráfica. PREPARAÇÃO Para executar os exemplos apresentados neste conteúdo, é necessário instalar em seu dispositivo a linguagem de programação Java e o pacote JOGL – implementação da biblioteca OpenGL para Java. OBJETIVOS MÓDULO 1 Descrever as etapas necessárias para a realização do sistema de coordenadas e transformações MÓDULO 2 Reconhecer as características das projeções geométricas e da câmera virtual MÓDULO 3 Esquematizar o estudo de caso em OpenGL e Java INTRODUÇÃO A computação gráfica está presente em muitas aplicações práticas: desde jogos eletrônicos e filmes até simulações ambientais. Esses avanços relacionam-se às necessidades da sociedade de simular interações realísticas em ambientes controlados. Não dá para comparar a qualidade das aplicações atuais com aquela dos primórdios do desenvolvimento de jogos, pois, além da evolução das tecnologias de hardware, houve avanços significativos em termos de software que implicaram a criação de ambientes mais produtivos e eficientes para trabalhar. Entre essas tecnologias de software, destacou-se a OpenGL: uma biblioteca de código aberto que disponibiliza definições de funções implementadas em diversas linguagens de programa, como C, C++, Java e Python. Para cada uma dessas linguagens, pode haver, e normalmente há, diferenças de implementação das funções, mas suas assinaturas são semelhantes, o que facilita a migração de um projeto de uma linguagem de programação para outra. Apesar de a OpenGL facilitar bastante o processo de desenvolvimento de um projeto de computação gráfica, é importante entender o fundamento matemático das funções. Trata-se de operações de álgebra linear que manipulam vetores e matrizes. POR QUE ESSE CONHECIMENTO É TÃO IMPORTANTE? Um dos motivos da relevância desse entendimento é melhorar o desempenho das aplicações, uma vez que a OpenGL já realiza essas operações, deixando que o desenvolvedor concentre sua atenção nos detalhes e no desempenho da aplicação em si. Ao longo deste conteúdo, vamos apresentar conceitos relacionados aos sistemas de coordenadas e transformações, às projeções geométricas e à câmera virtual, que nos auxiliam a entender como funciona o mundo virtual gráfico. Além disso, vamos apresentar noções da OpenGL desenvolvidas em Java. MÓDULO 1 Descrever as etapas necessárias para a realização do sistema de coordenadas e transformações SISTEMA DE COORDENADAS Um sistema de coordenadas é uma forma de associar números a pontos. Em duas dimensões, precisamos de um par ordenado de números para especificar um ponto. No caso da representação tridimensional, precisamos de três números para especificar um ponto. Normalmente, nós nos referimos às coordenadas de um ponto tridimensional como x, y e z — embora esses nomes sejam apenas uma convenção — e nos referimos a um ponto como a tripla (x, y, z). Pontos e objetos são reais, mas as coordenadas são apenas números que associamos a eles, para que possamos manipulá-los por meio de operações matemáticas. Para realizarmos essas operações, utilizaremos a biblioteca OpenGL. Entre os sistemas de coordenadas, temos (BUSS, 2003): SISTEMA DE COORDENADAS DO MUNDO Também conhecido como sistema de coordenadas do usuário ou mundial, é um sistema linear de coordenadas cartesianas (x, y) ao longo de ambos os eixos. As coordenadas são medidas em unidades de comprimento — por exemplo, metros — e são expressas como números reais. SISTEMA DE COORDENADAS DO OBJETO Quando criamos um objeto em um programa de modelagem, é uma atribuição do sistema escolher algum ponto para ser a origem daquele objeto específico e a orientação dele em relação a um conjunto de eixos do modelo. Por exemplo, quando modelamos um carro, o sistema de modelagem pode escolher um ponto no centro dele para ser a origem. Quando esse objeto é movido para um ponto no sistema de coordenadas do mundo, a origem do objeto (no sistema de coordenadas do objeto) é movida para as novas coordenadas mundiais, e todos os outros pontos no modelo são movidos igualmente. SISTEMA DE COORDENADAS NORMALIZADO Os valores de suas coordenadas são normalizados. Isso significa que estão entre 0 e 1. Por exemplo, para um ponto (x, y) no espaço bidimensional, sabemos que os valores de x e y são tais que: 0 ≤ x ≤ 1 e 0 ≤ y ≤ 1. Além disso, ambos os valores das coordenadas são expressos em números reais. SISTEMA DE COORDENADAS DO DISPOSITIVO São as coordenadas da tela onde os objetos devem ser exibidos, com os limites mínimos e máximos para cada eixo. Por exemplo, denominando os eixos de uma tela de x e y, os limites para o eixo x são dados por Xmin e Xmax e, para delimitar os valores do eixo y, temos Ymin e Ymax. Alguns exemplos práticos de sistema de coordenadas de dispositivos são configurações de resolução, tais como 1024x512, 640x480 e 800x600. Há, ainda, o sistema de coordenadas de dispositivo normalizadas, que descrevem as posições em um dispositivo. Esse sistema pode ser usado quando queremos posicionar textos, linhas, marcadores ou polígonos em qualquer lugar do dispositivo de plotagem. O canto esquerdo inferior corresponde a (0, 0), e o canto superior direito corresponde a (1, 1). Na figura a seguir, apresentamos um exemplo desse sistema de coordenadas: Imagem: Sérgio Assunção Monteiro Exemplo de um sistema de coordenadas de dispositivo normalizadas. Por meio da OpenGL, podemos manipular os vértices de um objeto a partir de matrizes de transformação. A OpenGL espera que todos os vértices que desejamos tornar visíveis estejam em coordenadas de dispositivo normalizadas, ou seja, que os valores das coordenadas estejam entre 0 e 1. SAIBA MAIS A OpenGL é uma especificação desenvolvida e mantida pelo Grupo Khronos, que descreve exatamente qual deve ser o resultado de cada função e como ela deve ser executada. Na prática, são os fabricantes de placas de vídeo que desenvolvem as bibliotecas baseadas em OpenGL. Para o programador que vai usar as funções, basta conhecer quais são os parâmetros que devem ser passados para uma função, sem ter de se preocupar com os detalhes da implementação das bibliotecas. TRANSFORMAÇÕES EM PONTOS E OBJETOS Um dos motivos de trabalharmos com sistemas de computação gráfica é oferecer facilidade para que os usuários possam visualizar os objetos de diferentes ângulos, ampliando ou reduzindo a escala, ou, ainda, a forma do objeto por meio de transformações. Há várias transformações dentro de determinado sistema de coordenadas ou entre sistemas de coordenadas. Para deixar esse conceito mais claro, comparamos, a seguir, os dois tipos de transformação: TRANSFORMAÇÕES Manipulações de um objeto gráfico mediante a aplicação de regras, de modo que o resultado seja outra forma de visualização do objeto original. Transformação geométrica O próprio objeto é transformado em relação ao sistema de coordenadas ou plano de fundo. Um exemplo desse tipo de transformação ocorre quando um automóvel se movimenta em relação a um plano de fundo fixo. Transformação de coordenadas O objeto é mantido estacionário, enquanto o sistema de coordenadas é transformado em relação ao objeto. Tal efeito é obtido por meio da aplicação de transformações de coordenadas. javascript:void(0) Um exemplo desse tipo de transformação ocorre quando um automóvel é mantido fixo, enquanto movemos o cenário de fundo. TIPOS DE TRANSFORMAÇÃO GEOMÉTRICA Vamos explicar, agora, os tipos de transformação geométrica, ou seja, aqueles aplicados apenas para pontos, a partir dos quais os objetos também são transformados. São eles: Translação Rotação Escalonamento Reflexão TRANSLAÇÃO A translação é o tipo mais simplesde transformação. Basicamente, significa alterar a localização de um objeto, ou seja, movê-lo de um lugar para outro. Ela pode ser combinada com outros tipos de transformação. Além disso, a translação é considerada uma transformação rígida, pois o tamanho e a forma do objeto permanecem os mesmos. Cada ponto que define o objeto é movido na mesma direção e pela mesma distância. Sua fórmula é dada por: X = X + TX Y = Y + TY Atenção! Para visualização completa da equação utilize a rolagem horizontal Onde: X E Y Valores das coordenadas originais. TX E TY Coordenadas de translação. X E Y Coordenadas transladadas. Na próxima figura, apresentamos um exemplo de translação de um ponto: Imagem: Sérgio Assunção Monteiro Transformação de translação. ATENÇÃO A função da OpenGL responsável pela translação de um ponto tridimensional é dada por: glTranslatef ( tx , ty , tz ) ; ROTAÇÃO Semelhante ao que ocorre com a transformação de translação, a rotação é uma transformação rígida, na qual um objeto é girado em um ângulo de rotação em torno de um ponto, no caso de um objeto bidimensional, ou de um eixo de rotação, no caso de um objeto tridimensional. A fórmula para girar o ponto em torno da origem é dada por: X = XCOSΘ – YSENΘ Y = XSENΘ + YCOSΘ Atenção! Para visualização completa da equação utilize a rolagem horizontal Observe que θ é o ângulo de rotação. A figura a seguir apresenta um exemplo de rotação de um ponto (x, y) em relação à origem do plano cartesiano: Imagem: Sérgio Assunção Monteiro Rotação em relação a origem. Para girar em torno de um ponto diferente, usamos as seguintes fórmulas: X = CX + ( X - CX ) * COSΘ - ( Y - CY ) * SENΘ Y = CX + ( X - CX ) * SENΘ + ( Y - CY ) * COSΘ Atenção! Para visualização completa da equação utilize a rolagem horizontal Onde: CX , CY COORDENADAS DO CENTRO. Θ ÂNGULO DE ROTAÇÃO. Atenção! Para visualização completa da equação utilize a rolagem horizontal A figura a seguir ilustra a rotação em torno de um ponto diferente: Imagem: Sérgio Assunção Monteiro Rotação em torno de um ponto diferente da origem. ATENÇÃO A função da OpenGL responsável pela rotação de um ponto tridimensional é dada por: glRotatef (θ, x, y, z). ESCALONAMENTO Transformação de escala (ampliação ou redução), escalonamento ou redimensionamento é uma transformação linear que, geralmente, aumenta ou reduz o tamanho de um objeto em diferentes escalas nos eixos, mantendo sua forma original. Como as dimensões do objeto redimensionado são diferentes das dimensões do original, aquele não é congruente com este, mas sim similar, uma vez que todas as dimensões (redimensionadas) são proporcionais às dimensões do objeto original. Todos os ângulos internos e externos de um polígono redimensionado permanecerão os mesmos. A escala que não altera a forma do objeto original é chamada de escala uniforme ou isotrópica. A fórmula do escalonamento é dada por: X = X * SX Y = Y * SY Atenção! Para visualização completa da equação utilize a rolagem horizontal Onde Sx e Sy são fatores de escala. Na figura a seguir, apresentamos um exemplo de transformação de escala de um retângulo: Imagem: Sérgio Assunção Monteiro Transformação de escalonamento. ATENÇÃO A função da OpenGL responsável pela transformação de escala de um ponto tridimensional é dada por: glScalef (float x, float y, float z); REFLEXÃO A transformação de reflexão ou espelhamento implica que um objeto seja reproduzido em uma linha como uma imagem espelhada de si mesmo. No caso do espaço bidimensional, essa linha é chamada de eixo de reflexão ou de simetria, e a imagem espelhada pode ser sobre os eixos x ou y. O objeto é girado em 180°. Trata-se de um caso especial de transformação de escala, em que os fatores de escala Sx e Sy são dados por: SX , SY Ε { - 1 , + 1 } Atenção! Para visualização completa da equação utilize a rolagem horizontal Na figura a seguir, apresentamos um exemplo de transformação de reflexão de um triângulo retângulo: Imagem: Sérgio Assunção Monteiro Transformação de reflexão em espaço bidimensional. Já no caso de espaço tridimensional, os objetos são refletidos em relação a um plano. Na figura a seguir, apresentamos um exemplo de transformação de reflexão de um triângulo retângulo em um espaço tridimensional:” Imagem: Sérgio Assunção Monteiro Transformação de reflexão em espaço tridimensional. SISTEMA DE COORDENADAS HOMOGÊNEAS Para realizar uma sequência de transformação, como translação seguida de rotação e dimensionamento, precisamos cumprir um processo linear, que inclui: 1 Aplicar a transformação de translação das coordenadas. Rotacionar as coordenadas transladadas. 2 3 Aplicar a transformação de escala das coordenadas rotacionadas para completar a transformação composta. Essas transformações podem ser descritas por meio da notação de matrizes. Para isso, trabalhamos com coordenadas homogêneas. Basicamente, atribuímos para cada ponto uma coordenada adicional h fictícia. MATRIZES DE TRANSFORMAÇÃO 2D No caso bidimensional, com pontos dados por pares ordenados (x, y), a conversão para coordenadas 2D é feita dividindo as coordenadas x e y por h. Usualmente, o valor aplicado para h é 1, ou seja, h = 1. Para um ponto (x, y), agora, temos (x, y, 1). As matrizes de transformação são estendidas por uma linha e coluna adicionais com valores de identidade. A seguir, mostraremos cada uma dessas matrizes de transformação nas coordenadas homogêneas: MATRIZ DE TRANSFORMAÇÃO DE ROTAÇÃO 2D XR YR 1 = COS Θ SEN Θ 0 - SEN Θ COS Θ 0 0 0 1 . X Y 1 Onde: xR e yR = coordenadas rotacionadas; θ = ângulo de rotação. MATRIZ DE TRANSFORMAÇÃO DE ESCALA 2D XE YE 1 = SX 0 0 0 SY 0 0 0 1 . X Y 1 Onde: xE e yE = coordenadas escalonadas; sx e sy = fatores de escala das coordenadas x e y, respectivamente. MATRIZ DE TRANSFORMAÇÃO DE TRANSLAÇÃO 2D [ ] [ ] [ ] [ ] [ ] [ ] XT YT 1 = 1 0 0 0 1 0 TX TY 1 . X Y 1 Onde: xT e yT = coordenadas de translação; tx e ty = deslocamentos de translação das coordenadas x e y, respectivamente. Todos os conceitos aplicados ao espaço bidimensional podem ser estendidos para o espaço tridimensional. MATRIZES DE TRANSFORMAÇÃO 3D Agora, vamos trabalhar com matrizes 4 x 4. Para isso, precisamos de um componente homogêneo. A seguir, listamos as transformações 3D mais importantes: MATRIZ DE TRANSFORMAÇÃO DE TRANSLAÇÃO 3D XT YT ZT 1 = 1 0 0 0 0 1 0 0 0 0 1 0 TX TY TZ 1 X Y Z 1 MATRIZ DE TRANSFORMAÇÃO DE ESCALA 3D [ ] [ ] [ ] [ ] [ ] [ ] XE YE ZE 1 = SX 0 0 0 0 SX 0 0 0 0 SX 0 0 0 0 1 X Y Z 1 MATRIZES DE TRANSFORMAÇÃO DE REFLEXÃO 3D SOBRE OS PLANOS YZ, XZ E XY Matriz YZ XR YR ZR 1 = - 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 X Y Z 1 Matriz XZ XR YR ZR 1 = 1 0 0 0 0 - 1 0 0 0 0 1 0 0 0 0 1 X Y Z 1 Matriz XY [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] XR YR ZR 1 = 1 0 0 0 0 1 0 0 0 0 - 1 0 0 0 0 1 X Y Z 1 Atenção! Para visualizaçãocompleta da tabela utilize a rolagem horizontal Matrizes de reflexão 3D. Elaborada por Sérgio Assunção Monteiro. MATRIZ DE TRANSFORMAÇÃO DE ROTAÇÃO 3D SOBRE OS EIXOS X, Y E Z Rotação sobre o eixo x XR YR ZR 1 = 1 0 0 0 0 COS Θ SEN Θ 0 0 - SEN Θ COS Θ 0 0 0 0 1 X Y Z 1 Rotação sobre o eixo y XR YR ZR 1 = COS Θ 0 - SEN Θ 0 0 1 0 0 SEN Θ 0 COS Θ 0 0 0 0 1 X Y Z 1 Rotação sobre o [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] eixo z XR YR ZR 1 = COS Θ SEN Θ 0 0 - SEN Θ COS Θ 0 0 0 0 1 0 0 0 0 1 X Y Z 1 Atenção! Para visualizaçãocompleta da tabela utilize a rolagem horizontal Matrizes de rotação 3D. Elaborada por Sérgio Assunção Monteiro. A notação matricial é bastante vantajosa do ponto de vista de eficiência computacional, pois, na maioria dos casos, as transformações são aplicadas a objetos com muitos pontos. Isso significa que a mesma sequênciade transformações é aplicada a cada ponto desses objetos. Em outras palavras, em vez de aplicarmos uma sequência de multiplicações matriciais para cada um dos pontos, podemos multiplicar as matrizes de transformações, obtendo, assim, uma matriz de transformação resultante. Depois, basta multiplicar os pontos do objeto apenas por essa matriz. [ ] [ ] [ ] SISTEMA DE COORDENADAS E TRANSFORMAÇÕES Neste vídeo, você verá mais detalhes sobre o sistema de coordenadas e as transformações em pontos e objetos. VERIFICANDO O APRENDIZADO 1. AS TRANSFORMAÇÕES GEOMÉTRICAS SÃO UM ASPECTO ESSENCIAL DA COMPUTAÇÃO GRÁFICA. POR MEIO DELAS, PODEMOS APLICAR ROTAÇÕES, MUDANÇAS DE ESCALA E DESLOCAMENTOS NOS OBJETOS DIGITAIS. A RESPEITO DAS TRANSFORMAÇÕES GEOMÉTRICAS, ASSINALE A ALTERNATIVA CORRETA: A) A transformação de escala tem como característica preservar a forma original dos objetos. B) A transformação de escala pode afetar a forma dos objetos resultantes em relação à figura geométrica original. C) A transformação de rotação é um exemplo de transformação rígida, uma vez que mantém os ângulos internos do objeto original a cada rotação, embora ocorram alterações no perímetro dele. D) A transformação de escala é um exemplo de transformação rígida, pois altera os ângulos internos de uma figura geométrica. E) A translação é a transformação mais complexa de ser feita, uma vez que é necessário garantir a coerência entre a figura geométrica original e a resultante. 2. A COMPUTAÇÃO GRÁFICA ESTÁ PRESENTE EM NOSSAS VIDAS. TALVEZ UMA DAS FORMAS MAIS SIMPLES DE VERIFICAR ISSO SEJA OBSERVAR OS FILMES MODERNOS: OS EFEITOS DE CÂMERA E ILUMINAÇÃO E UMA SÉRIE DE TRANSFORMAÇÕES DOS OBJETOS E PERSONAGENS NOS PROPORCIONAM EXPERIÊNCIAS MAIS REALISTAS. UM TIPO DE CENA BEM COMUM É A DE PERSONAGENS CONVERSANDO DENTRO DE UM CARRO QUE SIMULA O MOVIMENTO POR MEIO DA MUDANÇA DE CENÁRIO AO FUNDO. EM RELAÇÃO A ESSA SITUAÇÃO ESPECÍFICA, ASSINALE A ALTERNATIVA CORRETA: A) Trata-se de uma transformação de coordenadas, pois são as coordenadas que se movimentam em relação ao carro. B) Trata-se de uma transformação de escala, pois o efeito do movimento é obtido pela mudança dos elementos da paisagem, simulando que o carro se distancia deles. C) A transformação de rotação é a que melhor se encaixa nesse caso, pois dá a impressão de que o carro está em movimento. D) A transformação geométrica se enquadra nesse caso, pois transformações como a de translação e de escala auxiliam na simulação do movimento do carro. E) A translação é a transformação que se enquadra nesse caso, pois não ocorre nem rotação nem mudança de escala. GABARITO 1. As transformações geométricas são um aspecto essencial da computação gráfica. Por meio delas, podemos aplicar rotações, mudanças de escala e deslocamentos nos objetos digitais. A respeito das transformações geométricas, assinale a alternativa correta: A alternativa "A " está correta. Quando aplicamos uma transformação de escala em um polígono, não ocorre alteração dos ângulos internos e externos dele. 2. A computação gráfica está presente em nossas vidas. Talvez uma das formas mais simples de verificar isso seja observar os filmes modernos: os efeitos de câmera e iluminação e uma série de transformações dos objetos e personagens nos proporcionam experiências mais realistas. Um tipo de cena bem comum é a de personagens conversando dentro de um carro que simula o movimento por meio da mudança de cenário ao fundo. Em relação a essa situação específica, assinale a alternativa correta: A alternativa "A " está correta. Quando um objeto permanece parado em relação às suas coordenadas, trata-se de um caso de transformação de coordenadas. No exemplo apresentado, o que de fato está em movimento é o fundo do cenário em relação ao carro, simulando, assim, o deslocamento do carro. MÓDULO 2 Reconhecer as características das projeções geométricas e da câmera virtual PROJEÇÕES NA COMPUTAÇÃO GRÁFICA: PIPELINE DE RENDERIZAÇÃO As projeções transformam pontos de um sistema de coordenadas espaço n-dimensional para um espaço com menos dimensões, normalmente, n - 1 dimensões. No caso do espaço tridimensional, as projeções farão transformações para o espaço de duas dimensões. O uso mais importante das projeções na computação gráfica é no pipeline de renderização de sistemas de exibição de gráficos e bibliotecas, em que ocorre a projeção de objetos tridimensionais em um plano antes que sejam rasterizados e exibidos em uma tela para a visualização. PIPELINE DE RENDERIZAÇÃO Sequência de etapas que a OpenGL executa para renderizar objetos. O atributo de vértice do objeto que vamos renderizar e outros dados passam por uma sequência de etapas para, finalmente, obter a imagem final na tela. O pipeline possui nove etapas das quais algumas são opcionais. Vejamos essa sequência executada pela OpenGL para gerar uma imagem: 1 ESPECIFICAÇÃO DE VÉRTICES É uma lista ordenada de vértices que são usados para definir os limites da figura. Além disso, também podem ser definidos outros atributos do vértice, tais como cor, coordenadas de textura etc. Esses dados serão trabalhados pelo pipeline nas etapas seguintes. SOMBREAMENTO DE VÉRTICE (VERTEX SHADER) Recebe como entrada a lista de vértices que foram especificados e tem como objetivo calcular a posição final de cada vértice na cena. Os sombreadores de vértice são executados uma vez para cada vértice. Por exemplo, no caso de um quadrilátero, como um retângulo, o sombreador será executado quatro vezes. javascript:void(0) 2 3 TESSELAÇÃO Nesta etapa, que é opcional, os objetos são divididos (tesselados) em uma malha mais lisa de triângulos. SOMBREAMENTO DE GEOMETRIA A etapa de sombreamento também é opcional. Trata-se de receber uma primitiva de entrada e, por meio de um processo de combinação, produzir primitivas de saída. Rchoetzlein / Wikimedia Commons / CC BY-SA 3.0 adaptada por Sérgio Assunção Monteiro Sombreamento de geometria 4 5 javascript:void(0) PÓS-PROCESSAMENTO DE VÉRTICE Nesta etapa, o controle do usuário é limitado. A parte mais importante aqui é o recorte (clipping), que descarta a área dos primitivos que ficam fora da região de visualização. MONTAGEM PRIMITIVA Esta etapa coleta os dados do vértice em uma sequência ordenada de primitivas simples, tais como linhas, pontos ou triângulos. 6 7 RASTERIZAÇÃO Esta é uma etapa importante no pipeline. A saída da rasterização é um fragmento. SOMBREAMENTO DE FRAGMENTOS Nesta etapa, que é opcional, calculamos a cor de cada fragmento que o usuário vê na tela, determinando, assim, a cor final de cada um. 8 9 OPERAÇÕES POR AMOSTRA Na última etapa, o programa faz o processamento de cada amostra de fragmento e executa os processos necessários para criar a imagem final que é exibida na tela. SOMBREAMENTO Veja um exemplo de sombreamento: PROJEÇÕES PARALELAS As classes das transformações projetivas são divididas em: Paralela Perspectiva NESTE MOMENTO, VAMOS NOS ATER À PRIMEIRA CLASSE. A projeção paralela descarta a coordenada z, que representa a dimensão profundidade. Neste caso, trabalhamos com uma direção de projeção em vez de usar o centro de projeção. Além disso, a distância do centro de projeção ao plano do projeto é infinita. ATENÇÃO Apesar de ser menos realista, a projeção paralela é útil para realizar medições exatas. Nela, a imagem é exibida em forma e tamanho reais. Existem vários tipos de projeções paralelas, tais como: PROJEÇÕES ORTOGRÁFICAS Podem ser superior, frontal, lateral e axonométrica. PROJEÇÕES OBLÍQUAS Podem ser Cavalier e Cabinet. Aqui, vamos focar nas projeções ortográficas ou ortogonais. PROJEÇÕES ORTOGRÁFICAS: SUPERIOR, FRONTAL E LATERAL As projeções são chamadas de ortográficas ou ortogonais quando os raios das projeções estão perpendiculares ao plano de visão. Elas nos ajudam a avaliar sem distorções a forma e as proporções do tamanho do objeto. Esse tipo de projeção é bastante utilizado emprojetos de desenho técnico. A seguir, visualizaremos um objeto com cada tipo de projeção ortográfica. Imagem: Sérgio Assunção Monteiro Na figura, há um objeto geométrico no espaço tridimensional, que foi desenhado com o auxílio do aplicativo on-line Tinkercad. javascript:void(0) javascript:void(0) Imagem: Sérgio Assunção Monteiro Agora, vamos visualizar o mesmo objeto, sob a ótica do ponto A, com a projeção ortográfica superior Imagem: Sérgio Assunção Monteiro A seguir, vamos visualizar o objeto sob a ótica do ponto B, com a projeção ortográfica frontal. Imagem: Sérgio Assunção Monteiro Por fim, visualizamos o objeto sob a ótica do ponto C, com a projeção ortográfica lateral. PROJEÇÕES ORTOGRÁFICAS AXONOMÉTRICAS A projeção axonométrica se caracteriza pela posição inclinada do objeto em relação aos planos de projeção. Isso significa que a borda de um objeto parece encurtada, pois, quando um ângulo não é paralelo ao plano de projeção, aparece diferente do ângulo real. Os tipos de projeção axonométrica são: Imagem: Cmglee/ Wikimedia Commons / CC BY-SA 4.0 adaptada por Sérgio Assunção Monteiro PROJEÇÃO ISOMÉTRICA Quando o encurtamento ao longo de cada uma das três direções do eixo é igual. Imagem: Cmglee/ Wikimedia Commons / CC BY-SA 4.0 adaptada por Sérgio Assunção Monteiro PROJEÇÃO DIMÉTRICA Quando o encurtamento ao longo de duas direções do eixo é igual, e o encurtamento ao longo do terceiro eixo é diferente. Imagem: Cmglee/ Wikimedia Commons / CC BY-SA 4.0 adaptada por Sérgio Assunção Monteiro PROJEÇÃO TRIMÉTRICA Quando há encurtamento diferente ao longo das três direções do eixo. PROJEÇÕES EM PERSPECTIVA Agora, vamos conhecer a segunda classe das transformações projetivas: projeção em perspectiva. Uma imagem projetada em perspectiva é criada por meio da projeção de objetos no espaço tridimensional (3D) para um plano de imagem bidimensional (2D) em relação a um ponto de vista. Esse ponto — conhecido como centro de projeção — é o local adequado para visualizar a imagem. Uma imagem em perspectiva vista de qualquer outro ponto vai ficar distorcida. Entre as vantagens da projeção em perspectiva está a melhor aparência da figura com uma representação do espaço e da profundidade, apesar de não ser simples de desenhar. Na figura a seguir, apresentamos um exemplo de projeção em perspectiva: Imagem: Sérgio Assunção Monteiro Projeção em perspectiva. Um conceito importante relacionado à projeção em perspectiva é o de ponto de fuga: aquele em que um conjunto de linhas paralelas parece convergir quando colocado em perspectiva (HEARN; BAKER, 1997). No espaço tridimensional, no máximo três conjuntos de linhas podem ser mutuamente ortogonais entre si, e até dois desses conjuntos podem ser paralelos ao plano de visualização. Existem três tipos de projeção em perspectiva. São eles: PROJEÇÃO EM PERSPECTIVA DE UM PONTO DE FUGA Como o próprio nome sugere, essa projeção contém apenas um ponto de fuga na linha do horizonte. Normalmente, é usada para desenhar imagens de estradas, trilhos de trem e edifícios. Veja um exemplo: Imagem: Sérgio Assunção Monteiro Projeção em perspectiva de um ponto de fuga. PROJEÇÃO EM PERSPECTIVA DE DOIS PONTOS DE FUGA Também chamada de perspectiva angular, essa projeção contém dois pontos de fuga na linha do horizonte. Uma de suas aplicações é no desenho de edifícios ou nos interiores de edificações. Veja um exemplo: Imagem: Ejahng/ Wikimedia Commons / CC BY-SA 3.0 adaptada por Sérgio Assunção Monteiro Projeção em perspectiva de dois pontos de fuga. PROJEÇÃO EM PERSPECTIVA DE TRÊS PONTOS DE FUGA Contém três pontos de fuga: dois na linha do horizonte e um acima ou abaixo da linha. Quando vemos um objeto de cima, o terceiro ponto está abaixo do solo. Quando vemos um objeto de baixo, o terceiro ponto está no espaço acima. Uma das aplicações dessa projeção é no desenho de arranha-céus. Veja um exemplo: Imagem: Sérgio Assunção Monteiro Projeção em perspectiva de três pontos de fuga. CÂMERA VIRTUAL As câmeras são essenciais no processo de renderização, pois é por meio delas que conseguimos ver um objeto (o que vemos) localizado em um contexto (onde vemos) e com suas características (como vemos). Em computação gráfica, o processo que tem a atribuição de exibir os objetos na tela é chamado de viewing (GORDON; CLEVENGER, 2019). Ele precisa de diversos parâmetros, tais como: posicionamento da câmera no espaço, direção para onde a câmera aponta e orientação da câmera. A sequência de transformações do modelo 3D até as coordenadas do dispositivo de saída é dada por: Coordenadas do modelo. Coordenadas do mundo. Coordenadas de viewing. Coordenadas de projeção. Coordenadas do dispositivo de saída. As coordenadas do modelo tridimensional são posicionadas em uma cena (coordenadas do mundo) que, em seguida, são transformadas em um sistema de coordenadas a partir do observador da cena (coordenadas de viewing). Depois, é feita uma transformação, de modo que a imagem seja projetada em um plano de visão. Por fim, realiza-se a transformação da imagem para que seja exibida em um dispositivo (GORDON; CLEVENGER, 2019). A tabela a seguir apresenta os parâmetros que definem a câmera: Posição Local em que a câmera está posicionada. Ponto focal Ponto para o qual a câmera aponta. Orientação Controlada pela posição, pelo ponto focal e por um vetor denominado view up. Direção de projeção Linha de visão entre a posição da câmera e o ponto focal. Plano da imagem Plano em que a cena será projetada. Atenção! Para visualizaçãocompleta da tabela utilize a rolagem horizontal Parâmetros de definição da câmera virtual. Elaborada por Sérgio Assunção Monteiro. Na próxima figura, apresentamos esses parâmetros: Imagem: Schroeder et al (2006, p.44) adaptada por Sérgio Assunção Monteiro Parâmetros da câmera. A localização da câmera e o local para onde aponta são definidos pela posição e pelo ponto focal. A direção de projeção é o vetor que vai da posição da câmera até o ponto focal. O plano da imagem está localizado no ponto focal e, normalmente, é perpendicular ao vetor de projeção. A orientação é controlada pela combinação entre a posição, o ponto focal e o vetor de visualização. Juntos, eles definem completamente a visão da câmera. É no plano da imagem que os objetos são mapeados por meio do método de projeção. No caso da projeção ortográfica, o mapeamento é paralelo. Nesse tipo de projeção, todos os raios luminosos que entram na câmera são paralelos ao vetor de projeção. Já na projeção em perspectiva, os raios luminosos passam por um ponto comum: o centro de projeção, também chamado de ponto de vista. Para aplicar esse tipo de projeção, devemos especificar um ângulo de visão da câmera (ângulo de perspectiva). Os planos de recorte frontal e posterior cruzam o vetor de projeção e, normalmente, são perpendiculares a ele. Esses planos são usados para eliminar dados muito próximos ou distantes da câmera. O resultado é que apenas os objetos ou partes deles que estejam dentro dos planos de recorte são visíveis. ATENÇÃO Geralmente, os objetos da cena são referenciados como “atores”, o que pode ser confundido com personagens que interagem, mas devemos entendê-los apenas como elementos que participam da cena. Para evitar confusões, continuaremos a usar o termo “objetos” para referenciar tais elementos. Os planos de recorte são comumente perpendiculares à direção de projeção. Suas localizações podem ser definidas a partir do uso do intervalo de recorte da câmeranterva bem como da posição da câmera ao longo da direção de projeção. A combinação de todos esses parâmetros define uma pirâmide retangular que se origina na posição da câmera e se estende ao longo da direção de projeção. A pirâmide é truncada na parte superior com o plano de recorte frontal e na parte inferior com o plano de recorte posterior, o que forma um tronco (frustum). É esse troncoque define a região do espaço 3D visível para a câmera. Embora uma câmera possa ser manipulada a partir da definição direta dos atributos que analisamos, já existem algumas operações comuns que tornam o trabalho mais fácil. São elas: INTERVALO DE RECORTE DA CÂMERA É a distância entre os planos de recorte frontal e de fundo. AZIMUTH Faz o giro da posição da câmera em torno de seu vetor de visualização, centralizado no ponto focal. Para entender melhor, um exemplo da aplicação dessa função é mover a câmera para a esquerda ou para a direita enquanto mantemos a distância do ponto focal constante. ELEVAÇÃO (ELEVATION) Faz o giro da posição em torno do produto vetorial de sua direção de projeção, centralizada no ponto focal. Isso corresponde a mover a câmera para cima e para baixo. javascript:void(0) javascript:void(0) javascript:void(0) ROLL (TWIST) Para rolar a câmera, giramos o vetor de visualização para cima sobre o plano de vista normal. YAW Faz a rotação do ponto focal em torno do vetor de visualização por meio do uso da câmera como centro da transformação. PITCH Faz a rotação do ponto focal ao redor do vetor dado pelo produto vetorial entre o vetor de visualização e o vetor direção de projeção, por meio do uso da câmera como centro da transformação. Na próxima figura, apresentamos tais operações: Imagem: Schroeder et al (2006, p.46) adaptada por Sérgio Assunção Monteiro Operações de manipulação da câmera. Ainda há mais dois movimentos da câmera: DOLLY Move a posição da câmera ao longo do vetor de visualização (entrando e saindo). ZOOM Muda o ângulo de visão da câmera, de forma que mais ou menos da cena caia dentro do tronco (frustum) de visão. javascript:void(0) javascript:void(0) javascript:void(0) Para concluir, quando posicionamos a câmera, podemos gerar nossa imagem bidimensional. Alguns raios de luz que viajam pelo espaço tridimensional passam pelas lentes da câmera até atingir uma superfície plana para produzir uma imagem. É esse processo que, de fato, projeta nossa cena tridimensional em uma imagem bidimensional. O posicionamento da câmera e outras propriedades determinam quais raios de luz são capturados e projetados. Em outras palavras, apenas os raios de luz que passarem pela posição da câmera e que estejam dentro de seu tronco de visualização afetarão a imagem bidimensional resultante. PROJEÇÕES GEOMÉTRICAS E CÂMERA VIRTUAL Neste vídeo, abordaremos as Projeções Paralelas Ortográficas, a Projeção Perspectiva e a Câmera Virtual. VERIFICANDO O APRENDIZADO 1. O PIPELINE DE RENDERIZAÇÃO É UM MODELO CONCEITUAL QUE TRATA DAS ETAPAS PARA DESENHAR EM UMA TELA BIDIMENSIONAL UM MODELO TRIDIMENSIONAL. CADA ETAPA TEM UM OBJETIVO BEM DEFINIDO, APESAR DE ALGUMAS DELAS NÃO SEREM OBRIGATÓRIAS. EM RELAÇÃO ÀS ETAPAS DO PIPELINE DE RENDERIZAÇÃO, ASSINALE A ALTERNATIVA CORRETA: A) Na tesselação, os vértices são ordenados em uma lista, de modo a delimitar a figura. B) No sombreamento de vértice, os vértices são posicionados em uma cena. C) Na especificação de vértices, os objetos são divididos em uma malha de triângulos. D) Na rasterização, os vértices são convertidos em triângulos. E) No sombreamento de geometria, os triângulos de uma região são mapeados por meio dos vértices das figuras geométricas. 2. AS PROJEÇÕES ORTOGRÁFICAS E EM PERSPECTIVA SÃO TÉCNICAS FUNDAMENTAIS PARA EXIBIR UMA FIGURA TRIDIMENSIONAL EM UM AMBIENTE BIDIMENSIONAL. CADA UMA DELAS TEM CARACTERÍSTICAS IMPORTANTES PARA REPRESENTAR AS FIGURAS. EM RELAÇÃO ÀS PROJEÇÕES, ASSINALE A ALTERNATIVA CORRETA: A) As projeções ortográficas produzem informações que facilitam a visualização do objeto representado. B) As projeções em perspectiva são adequadas para dar visão total da representação do objeto. C) Quando desejamos representar as cotas de um objeto, a projeção adequada é em perspectiva. D) A projeção em perspectiva elimina ambiguidades da visualização dos objetos. E) A projeção ortogonal varia inversamente em relação à distância de aproximação com o objeto. GABARITO 1. O pipeline de renderização é um modelo conceitual que trata das etapas para desenhar em uma tela bidimensional um modelo tridimensional. Cada etapa tem um objetivo bem definido, apesar de algumas delas não serem obrigatórias. Em relação às etapas do pipeline de renderização, assinale a alternativa correta: A alternativa "B " está correta. Cada uma das etapas do pipeline de renderização tem objetivos específicos que visam a garantir a qualidade da transformação de uma imagem tridimensional para ser exibida em uma tela bidimensional. Entre essas etapas está o sombreamento de vértice, que posiciona, de modo definitivo, os vértices na cena. 2. As projeções ortográficas e em perspectiva são técnicas fundamentais para exibir uma figura tridimensional em um ambiente bidimensional. Cada uma delas tem características importantes para representar as figuras. Em relação às projeções, assinale a alternativa correta: A alternativa "D " está correta. As projeções ortográficas e em perspectiva possuem características complementares. Ambas as projeções apresentam vantagens e desvantagens. Uma das principais vantagens da projeção em perspectiva é produzir uma representação mais realística dos objetos, uma vez que o tamanho deles varia inversamente com a distância. MÓDULO 3 Esquematizar o estudo de caso em OpenGL e Java ESPECIFICAÇÃO E POSICIONAMENTO DA CÂMERA (GLULOOKAT) A câmera é o elemento fundamental para visualizarmos os objetos em uma cena. Nesse contexto, estamos tratando de todas as coordenadas dos vértices observadas a partir do ponto de visão da câmera como a origem da cena. Isso é feito por meio da transformação que a matriz de visão aplica para todas as coordenadas mundiais em coordenadas de visão relativas à posição da câmera e à direção. Portanto, para definirmos uma câmera, precisamos de sua posição no espaço mundial — a direção de observação, ou seja, para onde ela está olhando —, um vetor apontando para a direita e um vetor apontando para cima a partir da câmera, que nos ajudam a determinar um sistema de coordenadas com três eixos de unidades perpendiculares com a posição da câmera como origem. ATENÇÃO A OpenGL não define explicitamente nem a câmera nem uma matriz específica para a transformação. Em vez disso, transforma toda a cena (incluindo a câmera) inversamente em um espaço onde uma câmera fixa está na origem (0, 0, 0) e sempre voltada para o eixo -Z. Esse espaço é chamado de espaço ocular. Na figura a seguir, ilustramos como ocorre o ponto inicial da câmera: Imagem: Sérgio Assunção Monteiro Ponto inicial da câmera. A matriz modelo-visualização é dada por: MMODELOVISUALIZAÇÃO = MMODELOMVISUALIZAÇÃO Atenção! Para visualização completa da equação utilize a rolagem horizontal Cada objeto que está na cena é transformado, primeiro, com sua própria matriz modelo ( MModelo). Em seguida, toda a cena é transformada inversamente com a matriz de visualização ( Mvisualização), a qual consiste em duas transformações: Translação Realiza o movimento da câmera até a origem do sistema de coordenadas. Rotação Rotaciona a cena (universo) inversamente ao movimento da câmera. Formalmente, temos: MVSUALIZAÇÃO = MROTAÇÃOMTRANSLAÇÃO Atenção! Para visualização completa da equação utilize a rolagem horizontal Assim, a câmera será posicionada na origem e voltada para o eixo -Z. A OpenGL usa a matriz GL_MODELVIEW para as transformações do objeto no espaço do mundo e da visualização da câmera no espaço ocular. Para modificar a matriz de visualização, é necessária a função glMatrixMode. Para entendermos melhor, vamos ver um exemplo de sequência de operações sobre a matriz de modelo-visão: No item 1, definimos a matriz de visualização. No item 2, a função “glLoadIdentity” substitui a matriz atual pela matriz de identidade. Já os itens 3, 4 e 5 aplicam rotações na matriz de visualização em torno dos eixos x, y e z, respectivamente. Por fim, noitem 6, é aplicada uma translação sobre a matriz. Agora, para construir a matriz de visualização, a OpenGL utiliza a função gluLookAt. Essa função define a câmera a partir da criação de uma matriz de visualização derivada de um ponto de referência que indica o centro da cena e um vetor para cima. Sua assinatura é: Onde os parâmetros são dados por: EYEX, EYEY E EYEZ Definem as coordenadas x, y e z, respectivamente, em relação à posição da câmera (ou observador). CENTERX, CENTERY E CENTERZ glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glRotatef(45, 1.0, 0.0, 0.0); glRotatef(60, 0.0, 1.0, 0.0); glRotatef(30, 0.0, 0.0, 1.0); glTranslatef(2.0,0.0,0.0); 1 2 3 4 5 6 void gluLookAt(double eyeX, double eyeY, double eyeZ, double centerX, d1 javascript:void(0) javascript:void(0) Definem as coordenadas x, y e z, respectivamente, de onde o observador está olhando (normalmente, o centro da cena), ou seja, da posição do alvo. UPX, UPY E UPZ São as coordenadas x, y e z, as quais estabelecem o vetor up, que indica o “lado de cima” de uma cena 3D. VOLUME DE VISÃO PARA PROJEÇÃO EM PERSPECTIVA (GLFRUSTUM) A característica mais importante da projeção em perspectiva é o volume: quanto mais longe um objeto está da câmera, menor ele aparece na imagem final. Isso ocorre porque o volume de visualização para uma projeção em perspectiva é o tronco de uma pirâmide truncada, cujo topo foi cortado por um plano paralelo à sua base. Os objetos que se enquadram no volume de visualização são projetados em direção ao topo da pirâmide, onde está a câmera, ou ponto de vista. Os objetos que estão mais próximos da câmera parecem maiores, pois ocupam, proporcionalmente, uma parte maior do volume de visualização do que os que estão mais distantes, na parte maior do tronco. Esse método de projeção é aplicado para animação e simulação visual, em que o objetivo é proporcionar realismo à cena, semelhantemente ao modo como nosso olho (ou uma câmera) funciona. Na próxima figura, apresentamos uma ilustração que representa tronco de pirâmide (frustum): javascript:void(0) Imagem: Projection transformations, OpenGL, 2021 adaptada por Sérgio Assunção Monteiro e Eduardo Trindade Frustum A função da OpenGL para definir o frustum é glFrustum(). Ela calcula uma matriz que faz a projeção em perspectiva e faz a multiplicação com a matriz de projeção atual — normalmente, a matriz de identidade. O volume de visualização é usado para recortar objetos que estão fora dele. Os quatro lados do tronco, seu topo e sua base correspondem aos seis planos de recorte do volume de visualização, como foi apresentado na figura anterior. Os objetos ou as partes de objetos fora desses planos são recortados da imagem final. Sua assinatura é: Onde os parâmetros são dados por (SILICON GRAPHICS, 2021): LEFT, RIGHT Coordenadas para os planos de recorte vertical esquerdo e direito. BOTTOM, TOP Coordenadas para os planos de recorte horizontal inferior e superior. NEARVAL, FARVAL Distâncias para os planos de corte de profundidade próximos e distantes (ambas positivas). void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdoubl1 javascript:void(0) javascript:void(0) javascript:void(0) TRANSFORMAÇÕES E CONCATENAÇÃO A transformação de pontos tridimensionais em coordenadas bidimensionais na tela é feita por meio de transformações de matriz. Cada transformação tem como resultado um vetor em um novo sistema de coordenadas, passando, assim, para a próxima etapa. Na figura a seguir, apresentamos a sequência de transformações de sistemas de coordenadas: Imagem: Eduardo Trindade Transformações de coordenadas. A matriz de modelo transforma uma posição de um modelo para uma posição nas coordenadas do mundo. Ela move (faz a translação), dimensiona (faz o escalonamento) e rotaciona (faz a rotação) os objetos dentro do universo. Geralmente, nos projetos de OpenGL, especificamos os vértices em coordenadas mundiais. Então, essa matriz pode ser configurada para a matriz de identidade. Já a matriz de visualização é usada para representar a visão de determinada cena. Na OpenGL, a câmera não pode se mover e é definida para estar localizada na posição (0, 0, 0), voltada para a direção Z negativa (-Z). Isso significa que, em vez de mover e girar a câmera, o mundo é movido e girado ao redor da câmera para construir a visualização apropriada. Como exemplo, uma sequência de comandos típicos na OpenGL é dada por: No item 1, carregamos a matriz de modelo. No item 2, carregamos a matriz identidade. No item 3, deslocamos o ponto por meio da translação. No item 4, aplicamos um escalonamento nas coordenadas x, y e z, multiplicando x e y por 2 e mantendo z inalterada. gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(x, y, 0); gl.glScalef(2, 2, 1); 1 2 3 4 Em algumas situações, queremos salvar matrizes de transformação para usá-las posteriormente. A OpenGL oferece duas funções para fazer esse gerenciamento por meio de uma pilha: glPushMatrix () glPopMatrix () No caso do exemplo que mostramos, para guardar a sequência das operações 3 e 4, devemos escrever: Isso corresponde à concatenação de operações. A matriz MODELVIEW combina as transformações de modelo e visualização em uma única matriz. ALGORITMO Z-BUFFER Também chamado de algoritmo de buffer de profundidade, é uma técnica de computação gráfica usada para determinar a visibilidade de um objeto (ou uma parte dele) em uma cena. Esse algoritmo pode ser implementado em hardware ou software e é utilizado para aumentar a eficiência de renderização (BUSS, 2003). Para cada pixel na tela, mantemos um registro da profundidade de um objeto dentro do pixel que está mais próximo do observador. Além da profundidade, também registramos a intensidade que deve ser exibida para mostrar o objeto. O algoritmo de buffer de profundidade requer duas matrizes: Intensidade Profundidade Quando as cenas são renderizadas, cada pixel tem três coordenadas: X, Y e Z. Onde: gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glPushMatrix (); gl.glTranslatef(x, y, 0); gl.glScalef(2, 2, 1); glPopMatrix(); 1 2 3 4 5 6 X Orientação horizontal para a câmera Y Orientação vertical para a câmera Z Distância da câmera O Z-buffer é uma matriz bidimensional (X e Y) que armazena o valor Z de cada pixel da tela. Se outro objeto for renderizado na mesma localização de pixel, o algoritmo substituirá o valor anterior, sempre que o novo pixel estiver mais próximo da câmera. Esse algoritmo aumenta a velocidade de renderização para objetos opacos, mas os transparentes não se beneficiam, pois os objetos distantes são parcialmente visíveis e devem ser totalmente renderizados. Na figura a seguir, apresentamos um exemplo do algoritmo Z-buffer, em que podemos notar a distância dos objetos em relação ao observador: Imagem: en:User:T-tus / Wikimedia Commons / CC BY 2.0 adaptada por Eduardo Trindade Z-buffer. No caso da OpenGL, todas as informações de profundidade são armazenadas em um algoritmo Z-buffer. É por meio dele, em conjunto com o buffer de cor, que a OpenGL remove a superfície oculta. Ambos os buffers têm uma entrada para cada pixel da tela. À medida que o programa desenha vários objetos em uma cena, as cores de pixel são geradas pelo sombreador de fragmento. Em seguida, são colocadas no buffer de cores, que, por fim, é gravado na tela. Quando vários objetos ocupam alguns dos mesmos pixels no buffer de cores, ou seja, a mesma posição na tela, é necessário determinar quais cores de pixel serão retidas com base no objeto que está mais próximo do visualizador. Para remover a superfície oculta, antes de uma cena ser renderizada, o buffer de profundidade (Z-buffer) é preenchido com valores que representam a profundidade máxima. À medida que uma cor de pixel é fornecida pelo sombreador de fragmento, sua distância do visualizador é calculada. Se essa distância for menor do que a distância armazenada no buffer de profundidadepara aquele pixel, ocorrerão as seguintes etapas: A cor no buffer de cores será substituída pela cor do pixel. O valor no buffer de profundidade será substituído pela distância do pixel. Caso contrário, o pixel será descartado. ATENÇÃO Esse processo é feito automaticamente pela OpenGL. Para verificar se essa biblioteca realmente executa o teste de profundidade, primeiro, precisamos habilitá-lo, pois ele é desativado por padrão. Podemos habilitar o teste de profundidade usando a função glEnable. O comando vai ficar assim: Como estamos usando um buffer de profundidade, também queremos limpá-lo antes de cada iteração de renderização, pois, se não fizermos isso, as informações de profundidade do quadro anterior continuarão no buffer. Além disso, precisamos limpar o buffer de cor. Assim, o comando será: ELIMINAÇÃO DE FACES (BACK-FACE CULLING) glEnable (GL_DEPTH_TEST);1 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);1 Quando as aplicações ficam mais realísticas, é natural que mais objetos tridimensionais façam parte de uma cena, aumentando, assim, a complexidade de renderizá-los. Isso afeta diretamente o desempenho de uma aplicação. Portanto, precisamos de uma forma de tratar especificamente essa situação. Pensando nisso, a OpenGL oferece o recurso de fazer a seleção da face posterior, chamada de back-face culling: uma forma eficaz de melhorar a eficiência de renderização (GORDON; CLEVENGER, 2019). Por exemplo, nos casos de um cubo ou de uma pirâmide, em que há um modelo tridimensional cujo interior do objeto nunca é visível, as partes da superfície externa — ou seja, as faces do objeto — que não estão visíveis para o observador sempre serão escondidas por outra parte do mesmo modelo. No caso da pirâmide, as faces triangulares que estão voltadas para o lado oposto do observador não podem ser vistas. Logo, não há razão para serem renderizadas, uma vez que seriam sobrescritas de qualquer modo. Para tratar desse caso, podemos utilizar a OpenGL, a fim de identificar e não renderizar triângulos voltados para trás com o comando: Nas situações em que não quisermos utilizar mais esse recurso, poderemos desabilitá-lo com o seguinte comando: Por padrão, a seleção de faces está desabilitada. Assim, se quisermos que a OpenGL elimine triângulos voltados para trás, precisaremos habilitá-la explicitamente. Agora, quando ativamos a seleção de faces, ou seja, o back-face culling, por padrão, os triângulos serão renderizados apenas se estiverem voltados para a frente. ATENÇÃO A OpenGL considera um triângulo voltado para a frente se seus três vértices progridem no sentido anti-horário. Os triângulos cujos vértices progridem no sentido horário ficam voltados glEnable (GL_CULL_FACE);1 glDisable (GL_CULL_FACE);1 para trás e não são renderizados. Na figura a seguir, apresentamos um triângulo cujos vértices progridem no sentido horário e outro com os vértices progredindo no sentido anti-horário: Imagem: Sérgio Assunção Monteiro adaptada por Eduardo Trindade Triângulos com vértices progredindo no sentido horário e anti-horário. Essa definição anti-horária de “face frontal”, às vezes chamada de ordem de enrolamento, pode ser determinada explicitamente, usando a chamada de função para anti-horário (padrão): Também é possível fazer isso usando a seguinte chamada para horário: Portanto, a OpenGL possibilita que especifiquemos quais triângulos não devem ser renderizados, ou seja, quais serão os triângulos “selecionados”. É possível especificar que os triângulos voltados para trás sejam selecionados por meio da chamada: Podemos, ainda, especificar que os triângulos frontais sejam selecionados, ou mesmo que todos os triângulos sejam selecionados, substituindo o parâmetro GL_BACK por GL_FRONT ou GL_FRONT_AND_BACK. Resumindo, a função glCullFace tem três opções possíveis: GL_BACK Seleciona apenas as faces posteriores. gl_FrontFace (GL_CCW);1 gl_FrontFace (GL_CW);1 glCullFace (GL_BACK);1 GL_FRONT Seleciona apenas as faces frontais. GL_FRONT_AND_BACK Seleciona as faces frontal e posterior. O valor inicial de glCullFace é GL_BACK. Na próxima figura, ilustramos um exemplo de objeto que destaca a forma como os vértices progridem ao longo dos triângulos e a estratégia da OpenGL para eliminar as faces posteriores a partir do observador da cena: Imagem: Sérgio Assunção Monteiro Eliminação de faces não visíveis. FONTES DE LUZ A iluminação determina as cores dos vértices de um objeto tridimensional na cena, com base nas propriedades da luz e dos materiais atribuídas às diferentes superfícies. Na OpenGL, o modelo de iluminação considera que esta é dividida em quatro componentes independentes (BUSS, 2003): LUZ EMITIDA Aquela que se origina de um objeto e não é afetada por nenhuma fonte de luz, como os faróis de um veículo. LUZ AMBIENTAL Aquela que é espalhada no ambiente, tal que não é possível determinar sua direção. Por exemplo, a iluminação de fundo em uma sala tem um grande componente de luz ambiental, uma vez que a maior parte da luz que atinge nossos olhos foi anteriormente refletida em muitas superfícies. LUZ DIFUSA Aquela que que vem de uma direção. Quando atinge uma superfície, ela é espalhada igualmente em todas as direções. Então, parece igualmente brilhante. Não importa onde o olho esteja localizado. LUZ ESPECULAR Aquela que que vem de uma direção particular e tende a refletir na superfície em uma direção preferida. Por exemplo, objetos metálicos brilhantes têm um alto componente especular, enquanto um giz não tem. Todos esses componentes são calculados independentemente e, em seguida, somados. Na figura a seguir, apresentamos um exemplo em que são destacadas as contribuições das luzes ambiental, difusa e especular: Imagem: Gordon; Clevenger (2019, p. 155) adaptada por Sérgio Assunção Monteiro e Eduardo Trindade Tipos de luz. Na OpenGL, uma fonte de luz é definida pela sua posição e pela intensidade da luz ambiente, difusa e especular que emite na cena. Todas as propriedades de luz são configuradas com o seguinte comando: Onde os parâmetros são dados por: LIGHT Especifica quais propriedades da luz estão sendo definidas. Pelo menos oito luzes são suportadas. Pode assumir os valores GL_LIGHT0 a GL_LIGHT7. PNAME Especifica qual parâmetro da luz está sendo definido. Entre os valores que pode assumir, os principais são GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION. PARAMS Contém os valores do parâmetro definido por “pname”. Ainda em relação aos parâmetros da função glLightfv, seus valores padrões são apresentados na tabela a seguir: Pname Significado Valor padrão GL_AMBIENT Intensidade da contribuição ambiental (r, g, b, a) = (0, 0, 0, 0) GL_DIFFUSE Intensidade da contribuição difusa (r, g, b, a) = (1, 1, 1, 1) GL_SPECULAR Intensidade da contribuição especular (r, g, b, a) = (1, 1, 1, 1) GL_POSITION Posição da luz (x, y, z, w) = (0, 0, 1, 1) Atenção! Para visualizaçãocompleta da tabela utilize a rolagem horizontal Valores padrões dos parâmetros dos tipos de iluminação. Elaborada por Sérgio Assunção Monteiro glLightfv(light, pname, params)1 javascript:void(0) javascript:void(0) javascript:void(0) No caso do parâmetro GL_POSITION, se w = 0, então a fonte de luz é considerada infinita. Isso simplifica cálculos de iluminação, uma vez que a direção de qualquer vértice na cena para uma fonte de luz infinita é constante. Se w ≠ 0, então a fonte de luz é “local” para a cena, e a direção para a fonte de luz deve ser calculada em cada vértice. Além disso, a posição da fonte de luz é tratada como um primitivo geométrico: um vértice. Portanto, está sujeita às mesmas transformações de matriz como qualquer outro objeto primitivo. Isso significa que é possível manipular a posição da luz por meio do MODELVIEW exatamente como podemos fazer para qualquer outro vértice. Uma vez que as propriedades da fonte de luz são definidas, precisamos “ligar” a luz com o comando: RELEMBRANDO Como jávimos, “light” pode assumir os valores de GL_LIGHT0 a GL_LIGHT7. A seguir, apresentamos um trecho de código para exemplificar como usar essa função glLightfv com seus parâmetros: De início, criamos os vetores que contêm informações a respeito da posição da luz e das contribuições da luz ambiental e especular. Agora, passamos a chamar a função glLightfv com os devidos parâmetros: glEnable (light);1 final float[] posicaoLuz = {1.0, 1.0, 1.0, 0.0}; final float[] luzAmbiental = {0.2f, 0.2f, 0.2f, 1f}; final float[] luzEspecular = {0.5f, 0.5f, 0.5f, 1f}; 1 2 3 gl.glLightfv( GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION, pos gl.glLightfv( GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, luzA gl.glLightfv( GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, luz 1 2 3 MODELO DE ILUMINAÇÃO No modelo de iluminação da OpenGL, a luz em uma cena vem de várias fontes emissoras, que podem ser ligadas e desligadas individualmente. Parte da luz vem de determinada direção ou posição, e outra parte, geralmente, é espalhada pela cena. As fontes de luz têm efeito apenas quando existem superfícies que absorvem e refletem a luz. Cada superfície é composta de um material com várias propriedades. Um material pode, por exemplo: EMITIR SUA PRÓPRIA LUZ Como os faróis de um automóvel. ESPALHAR ALGUMA LUZ QUE ENTRA EM TODAS AS DIREÇÕES Como uma folha de papel, ou uma superfície irregular ou rugosa. REFLETIR UMA PARCELA DA LUZ QUE ENTRA EM DETERMINADA DIREÇÃO Como um espelho ou uma superfície brilhante. O modelo de iluminação da OpenGL permite definir as seguintes propriedades da cena: INTENSIDADE DA LUZ AMBIENTE GLOBAL Para isso, usamos o comando: void glLightModelfv(pname, params, params_offset) Onde os parâmetros são definidos como: pname – deve ser GL_LIGHT_MODEL_AMBIENT; params – é um vetor contendo quatro números que fornecem os componentes de cor RGBA da luz ambiente global como números no intervalo de 0.0 a 1.0, que define a intensidade ambiente; params_offset – o último argumento em glLightfv é um deslocamento de onde o vetor inicia. Na prática, sempre vamos utilizar o valor 0 (“zero”) para ele. TIPO DO PONTO DE VISUALIZAÇÃO Esse ponto pode ser local ou infinito. Para isso, usamos o comando: glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, param); Onde o parâmetro “param” pode assumir o valor 0 ou o valor 1 para indicar se a opção deve ser desativada ou ativada. É possível, ainda, usar as constantes simbólicas GL_FALSE e GL_TRUE para o valor, mas esses são apenas nomes para 0 e 1. Por padrão, a OpenGL utiliza o ponto de visualização infinito para fornecer uma direção constante de qualquer vértice ao observador. FACES FRONTAIS OU FRONTAIS E POSTERIORES DOS POLÍGONOS Aqui, determinamos se apenas as faces frontais ou frontais e posteriores dos polígonos devem ter a iluminação executada. Para isso, precisamos executar o comando: glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, param); A constante GL_LIGHT_MODEL_TWO_SIDE é usada para “ligar” a iluminação dos dois lados dos polígonos. Uma vez que o modelo de iluminação é definido, a iluminação deve ser “ligada” com o seguinte comando: Abaixo, apresentamos um exemplo de como podemos utilizar esses comandos: No vetor “luzAmbiente”, definimos os parâmetros do RGBA. Na segunda linha, ativamos o modelo de iluminação. E na terceira linha, ativamos o uso da luz ambiente. ILUMINAÇÃO: PROPRIEDADES DO MATERIAL glEnable (GL_LIGHTING)1 float luzAmbiente[]={0.2f, 0.2f, 0.2f, 1.0f}; gl.glEnable(GL2.GL_LIGHTING); gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, luzAmbiente, 0); 1 2 3 No modo de iluminação da OpenGL, as cores dos vértices não são especificadas diretamente. Em vez disso, precisamos definir as propriedades dos materiais para uma superfície ou um vértice e combiná-las com a normal do vértice, a direção para a fonte de luz, a direção para o observador e as propriedades da luz, a fim de determinar a cor da superfície (BUSS, 2003). Na OpenGL, definimos as propriedades dos materiais com a função: NORMAL DO VÉRTICE Em geral, a “normal” é um vetor unitário, cuja direção é perpendicular à superfície em um ponto específico. A “normal do vértice” é definida como a combinação das “normais” das faces triangulares que circundam o vértice em questão. Onde os parâmetros são dados por: FACE PARAM VALOR FACE Informa se estamos definindo um valor de propriedade do material para a face frontal, posterior ou ambas. Pode assumir um dos seguintes valores: GL FRONT, GL BACK ou GL FRONT AND BACK. PARAM glMaterialfv (face, param, valor);1 javascript:void(0) Informa qual propriedade do material está sendo definida. Pode ser GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, ou GL_AMBIENT_AND_DIFFUSE. VALOR Contém os valores de parâmetro “param” em um vetor RGBA. Os valores padrões associados às entradas dos parâmetros “param” são: GL_AMBIENT – (r, g, b, a) de reflexão ambiente, cujo valor padrão é (.2, .2, .2, 1); GL_DIFFUSE – (r, g, b, a) de reflexão difusa, cujo valor padrão é (.8, .8, .8, 1); GL_SPECULAR – (r, g, b, a) de reflexão especular, cujo valor padrão é (0, 0, 0, 1); GL_SHININESS – expoente especular, cujo padrão é 0. Agora, quando precisamos definir a propriedade do brilho de um material, usamos a função: Semelhante à função “glMaterialfv”, o parâmetro “face” pode ser GL_FRONT_AND_BACK, GL_FRONT ou GL_BACK. Mas o parâmetro “pname” deve ser obrigatoriamente igual a “GL_SHININESS”, que representa o brilho do material. E o parâmetro “param” é um float no intervalo de 0.0 a 128.0, que dá a intensidade do brilho. A seguir, mostramos um trecho de código que exemplifica como usar as funções “glMaterialfv” e “glMaterialf”: Nas duas primeiras linhas, criamos os vetores RGBA corAmbiente e corEspecular. Em seguida, nas linhas 3 e 4, chamamos a função “glMaterialfv” para definirmos as cores ambientes e especulares do material. Por fim, na linha 5, definimos a luminosidade do material. void glMaterialf (face, pname, param);1 float[] corAmbiente = {0.3f, 0.3f, 0.3f, 1f}; float[] corEspecular = {0.8f, 0.8f, 0.8f, 1f}; gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, corAmbiente, 0); gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, corEspecular, 0); gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, 90f); 1 2 3 4 5 ESTUDO DE CASO EM OPENGL EM JAVA No vídeo a seguir, abordaremos os tópicos vistos neste módulo, dentre os quais a especificação e o posicionamento da Câmera, Z-buffer, eliminação de faces e iluminação. VERIFICANDO O APRENDIZADO 1. UM DOS PRIMEIROS CUIDADOS NECESSÁRIOS EM UM PROJETO 3D É A FORMA COMO OS OBJETOS SERÃO VISTOS EM UMA CENA. A OPENGL TRATA A QUESTÃO DO POSICIONAMENTO DA CÂMERA POR MEIO DA FUNÇÃO “GLULOOKAT”. EM RELAÇÃO AO ASSUNTO, ASSINALE A ALTERNATIVA CORRETA: A) A função gluLookAt fornece os recursos para que seja possível realizar os movimentos da câmera. B) Na OpenGL, por padrão, quem se movimenta são os objetos que estão na cena. Se for preciso realizar movimentos da câmera, será necessário parametrizar a função gluLookAt para essa finalidade. C) Na OpenGL, a câmera não se movimenta, e sim os objetos em relação à câmera. D) Por questões de otimização de desempenho, na OpenGL, a câmera é localizada na posição (0, 0, 0) por padrão. Portanto, se for preciso que ela faça movimentos, será necessário parametrizar a função gluLookAt adequadamente. E) Os objetos na OpenGL são uma representação da projeção ortográfica. Isso otimiza o desempenho da câmera para o processo de visualização. 2. AS APLICAÇÕES DE COMPUTAÇÃO GRÁFICA ESTÃO CADA VEZ MAIS AVANÇADAS, AUMENTANDO O REALISMO DAS CENAS. UM DOS ELEMENTOS QUE COMPÕEM ESSE REALISMO É A PROJEÇÃO EM PERSPECTIVA, NA QUAL OS OBJETOS SÃO COLOCADOS EM CENA DE MODO A SIMILAR AO MODO COMO SÃO VISTOS NO “MUNDO REAL”. A OPENGL TRATA ESSE TIPO DE PROJEÇÃO POR MEIO DA FUNÇÃO “GLFRUSTUM”. EM RELAÇÃO A ESSA FUNÇÃO, ASSINALE A ALTERNATIVA CORRETA: A) Representa o posicionamento da câmera. Por meio da parametrização adequada, é possível aumentare diminuir os objetos. B) Auxilia a aumentar o realismo de uma cena por meio de projeções ortogonais. C) A projeção ortogonal que a função produz permite ter precisão no dimensionamento correto dos objetos em relação aos demais itens que compõem a cena. D) Representa uma pirâmide truncada com dois planos que auxiliam a limitar o campo de visão do observador. Por meio dos parâmetros, é possível aproximar um objeto do observador ou distanciá-lo. E) É bastante eficiente para representar a luminosidade dos objetos da cena, aumentando, assim, o realismo. GABARITO 1. Um dos primeiros cuidados necessários em um projeto 3D é a forma como os objetos serão vistos em uma cena. A OpenGL trata a questão do posicionamento da câmera por meio da função “gluLookAt”. Em relação ao assunto, assinale a alternativa correta: A alternativa "C " está correta. Na OpenGL, quando falamos sobre câmera, estamos nos referindo a todas as coordenadas do vértice vistas da perspectiva da câmera como a origem da cena. A OpenGL não define explicitamente nem o objeto da câmera nem uma matriz específica para a transformação da câmera. Em vez disso, transforma toda a cena inversamente em um espaço. Por exemplo, mover a câmera para 5 unidades do eixo Y equivale a mover o mundo para -5 unidades do eixo Y. O mesmo raciocínio vale para todos os outros eixos. 2. As aplicações de computação gráfica estão cada vez mais avançadas, aumentando o realismo das cenas. Um dos elementos que compõem esse realismo é a projeção em perspectiva, na qual os objetos são colocados em cena de modo a similar ao modo como são vistos no “mundo real”. A OpenGL trata esse tipo de projeção por meio da função “glFrustum”. Em relação a essa função, assinale a alternativa correta: A alternativa "D " está correta. A função glFrustum cria uma matriz para um tronco de visão em perspectiva: o chamado frustum. Desse modo, ela realiza o gerenciamento do volume de visualização do tronco por meio da parametrização correta. CONCLUSÃO CONSIDERAÇÕES FINAIS No decorrer do conteúdo, apresentamos aspectos teóricos e práticos sobre computação gráfica, utilizando a OpenGL. Conceitos como sistema de coordenadas e transformações e sistema de coordenadas homogêneas foram abordados para fundamentar o conhecimento matemático em relação às operações de computação gráfica. Ainda verificamos a forma como os objetos são projetados na tela por meio das projeções geométricas e da câmera virtual, o que nos ajudou a entender as possibilidades relacionadas aos movimentos da câmera e como podemos adicionar realismo ao que é exibido em uma cena. Por fim, exploramos a OpenGL e vimos como os conceitos estudados podem ser aplicados à linguagem Java na prática. A compreensão dos diversos aspectos que cobrem o desenvolvimento de uma aplicação gráfica nos ajuda a desenvolver aplicações mais realísticas e eficientes. Apesar de nosso foco ter sido a linguagem Java, o que vimos também pode ser aplicado a outras linguagens de programação, como C, C++ e Python. AVALIAÇÃO DO TEMA: REFERÊNCIAS BUSS, S. R. 3-D computer graphics – a mathematical introduction with OpenGL. New York: Cambridge University Press, 2003. GORDON, V. S.; CLEVENGER, J. Computer graphics programming in OpenGL with Java. Dules: Mercury Learning, 2019. HEARN, D.; BAKER, P. Computer graphics – C version. 2. ed. New Jersey: Prentice Hall, 1997. OPENGL. Projection transformations. Beaverton: OpenGL, 2021. SCHROEDER, W.; MARTIN, K.; LORENSEN, B. The visualization toolkit: an object-oriented approach to 3D graphics. 4. ed. New York: Kitware, 2006. SILICON GRAPHICS. glFrustum – multiply the current matrix by a perspective matrix. Beaverton: Khronos Group, 2021. EXPLORE+ Acesse o site oficial Java - Oracle para conhecer melhor a linguagem. Pesquise e conheça o aplicativo Tinkercad, que permite criar objetos em espaços tridimensionais. Explore o site oficial do JogAmp para ver detalhes da instalação do pacote JOGL. Acesse o livro byhj/OpenGL-Redbook: Sample - GitHub para saber mais sobre as aplicações da OpenGL. CONTEUDISTA Sérgio Assunção Monteiro CURRÍCULO LATTES javascript:void(0);
Compartilhar