Escolar Documentos
Profissional Documentos
Cultura Documentos
Inserir SonorosAqui
e
Inserir Título
Visuais para Jogos
Aqui
Efeitos Visuais para Jogos
Revisão Textual:
Prof. Me. Luciano Vieira Francisco
Efeitos Visuais para Jogos
Caro Aluno(a)!
Normalmente, com a correria do dia a dia, não nos organizamos e deixamos para o
último momento o acesso ao estudo, o que implicará o não aprofundamento no material
trabalhado ou, ainda, a perda dos prazos para o lançamento das atividades solicitadas.
Assim, organize seus estudos de maneira que entrem na sua rotina. Por exemplo, você
poderá escolher um dia ao longo da semana ou um determinado horário todos ou alguns
dias e determinar como o seu “momento do estudo”.
Após o contato com o conteúdo proposto, participe dos debates mediados em fóruns de
discussão, pois estes ajudarão a verificar o quanto você absorveu do conteúdo, além de
propiciar o contato com seus colegas e tutores, o que se apresenta como rico espaço de
troca de ideias e aprendizagem.
Bons Estudos!
UNIDADE
Efeitos Visuais para Jogos
Contextualização
Na época em que os jogos digitais começaram a ser desenvolvidos, os gráficos consistiam
de simples blocos na tela. Com o avanço da tecnologia, tais blocos deram lugar a imagens
criadas por artistas e, depois, o visual do jogo começou a ser criado a partir de modelos tri-
dimensionais (3D), processados e exibidos em tempo real, enquanto o jogo era executado.
Com o passar dos anos, o processamento gráfico começou a ser realizado por hardware
dedicado – com o uso de Graphics Processing Unit (GPU) –, sendo que atualmente é possível
escrever código específico para GPU, definindo o que o processador gráfico deve fazer – seja
simplesmente exibir modelos 3D e imagens ou aplicar efeitos especiais no visual do jogo.
6
Pipeline de Renderização
Para aplicar efeitos visuais em jogos ou aplicações com renderização em tempo real, é
importante entender o que é a pipeline de renderização – graphics rendering pipeline – ou
simplesmente pipeline.
Antes de continuarmos, talvez você esteja se perguntando: “O que é uma pipeline?” Podemos
citar um oleoduto, uma linha de produção de fábrica ou um metrô como exemplos de pipeline
do mundo real. Pensando nesses casos, podemos observar que uma pipeline – “linha de tubu-
lação” – consiste de vários estágios e que há um fluxo – de alguma coisa, como petróleo, gás,
produto elaborado na fábrica, pessoas etc. – entre os estágios.
Entrada
(cena 3D)
Saída
(imagem)
Renderização
No fluxo apresentado na Figura 2, a saída da pipeline está indicada como uma imagem.
Ao estudarmos ou trabalharmos com computação gráfica, é comum ouvir a frase “renderi-
zar uma cena 3D” – ou os termos renderização, renderizar, render.
7
7
UNIDADE
Efeitos Visuais para Jogos
O que significa “renderizar uma cena 3D”? Fazendo uma analogia com fotos: para tirar
uma fotografia, precisamos de uma câmera, seja analógica ou digital. Com esse equipamento,
conseguimos capturar as luzes e gerar uma imagem. O processo de renderizar uma cena
3D é similar: precisamos de uma câmera virtual para decidir quais elementos da cena 3D
aparecerão na imagem.
A velocidade de renderização é definida pelo estágio mais lento da pipeline e pode ser
expressa em Frames per Second (FPS), que é a quantidade de imagens renderizadas por
segundo, ou em hertz (Hz), que é a frequência de atualização da tela/display – hardware.
Estágio de Aplicação
O estágio de aplicação é onde a lógica do jogo – ou aplicativo – ocorre e o processamen-
to é tradicionalmente realizado pela CPU, sendo que o programador tem controle total sobre
o que acontece nesse estágio. Ademais, são operações comuns nessa etapa: detecção de
colisão, técnicas de otimização, animação e simulação física.
8
Nesse estágio, os dados da cena 3D são carregados. Por exemplo, modelos tridimensionais que
existem em disco, tais como arquivos nos formatos fbx e obj, são lidos e seu conteúdo carregado
na memória RAM.
No final do estágio de aplicação, a saída de fluxo de dados que segue a pipeline é com-
posta por primitivas – vértices, arestas, triângulos. Assim, a tarefa mais importante do estágio
de aplicação – em termos de renderização/gráfico – é enviar as primitivas para o hardware
gráfico – Graphics Processing Unit (GPU).
Estágio de Geometria
O estágio de geometria é responsável por operações geométricas nos dados de entrada
– as primitivas que foram enviadas pelo estágio de aplicação – e permite realizar operações
como mover objetos e câmeras – multiplicação de matrizes –, calcular iluminação nos vér-
tices dos triângulos, realizar a projeção da cena 3D em um espaço 2D, realizar o clipping
– eliminar triângulos fora da visão – e mapear a cena para a janela onde será exibida.
Transformação de Modelo
Originalmente, um objeto está no espaço – coordenada – do modelo 3D. Nesse subestágio,
o objeto é transformado ao espaço do mundo. Por exemplo, considerando uma esfera com
origem em (0, 0, 0) e escala 1, qualquer operação de translação, rotação e escala fazem a
esfera aparecer em outro lugar.
Transformação de Visão
A câmera virtual e todos os objetos são convertidos ao espaço do mundo. Em seguida, a
câmera é posicionada na origem do mundo, apontando para dentro da tela, usando o eixo Z
negativo ou o eixo Z positivo – a direção do eixo Z depende da API gráfica. O eixo X positivo
aponta para a direita e o eixo Y positivo aponta para cima. Assim, há transformação de visão,
onde a câmera e os objetos são convertidos ao espaço da câmera ou ao “espaço do olho” –
camera space ou eye space. A Figura 5 mostra o resultado da transformação de visão:
9
9
UNIDADE
Efeitos Visuais para Jogos
Vertex Shading
A operação de vertex shading determina o efeito de uma fonte de luz na superfície
do objeto, realizando operações de cálculo de iluminação nos vértices do modelo.
Projeção
Neste subestágio, a projeção transforma o volume de visão em um cubo unitário, sendo
que há duas projeções comumente usadas em computação gráfica: ortogonal ou ortográfica –
ou ainda paralela, lado esquerdo da Figura 6 – e perspectiva – lado direito da Figura 6 –, mais
comum e que simula como vemos o mundo, isto é, o tamanho dos objetos diminui conforme
se distanciam do observador – câmera.
Corte
Com o cubo unitário criado após a projeção, o subestágio de corte – clipping – define
quais primitivas devem ser processadas. As primitivas que estão dentro do cubo não mudam;
as totalmente fora do cubo são descartadas; e as que possuem parte dentro e parte fora do
cubo são cortadas no limite deste cubo, tal como mostrado na Figura 7:
10
Mapeamento na Tela
O subestágio de mapeamento na tela altera o cubo unitário do subestágio de corte, apli-
cando translação e escala, a fim de que o cubo se adapte à região de renderização – uma
janela na tela ou a tela cheia –, conforme a Figura 8:
A Figura 9 contém um resumo sobre o estágio de geometria, criado pelo autor, pesquisa-
dor e professor Tomas Akenine-Möller (2003):
Estágio de Rasterização
O estágio de rasterização é responsável por transformar a saída do estágio de geometria
em pixels na tela – ou qualquer outro dispositivo de saída final –, além de adicionar
texturas, realizar outras operações em nível de pixel e resolver a ordenação de primitivas.
O estágio de rasterização possui subestágios, vejamos: configuração de triângulo – triangle
setup –, conversão de varredura – scan conversion –, shading de pixels – pixel shading,
sombreamento no sentido de tonalidade – e combinação de buffers – memória – e saída –
merging –, conforme a Figura 10:
11
11
UNIDADE
Efeitos Visuais para Jogos
Configuração de Triângulo
Neste subestágio os dados da superfície do triângulo são calculados para serem usados no
próximo subestágio de conversão de varredura – scan conversion.
Conversão de Varredura
Este subestágio é responsável por encontrar os pixels que estão dentro de um triângulo,
aresta ou vértice, por meio da conversão de varredura – scan conversion –, conhecido tam-
bém por triangle traversal.
Pixel Shading
A operação de pixel shading realiza cálculos de tonalização em nível de pixel. O resultado
é uma ou mais cores que são passadas ao próximo estágio de merging. Uma das aplicações
nesse estágio de pixel shading é a texturização de superfícies.
Combinação
No último subestágio do estágio de rasterização ocorre a combinação – merging –
do conteúdo presente na memória. Ademais, a memória conhecida por color buffer
mantém a informação de cada pixel.
Nesse estágio, combina-se a cor do fragmento resultante do pixel shading com o color
buffer. Ocorre também o cálculo de visibilidade com o algoritmo z-buffer – depth buffer.
Além das informações contidas na memória do color buffer – cor – e depth buffer – pro-
fundidade –, há outras memórias e canais que podem ser usados para capturar a informação
dos fragmentos, tais como:
· Alpha channel: canal de transparência ou opacidade;
· Stencil buffer: memória offscreen – não é exibida na tela –, usada para efeitos
especiais, tais como máscara e espelho;
· Accumulation buffer: memória empregada para efeitos especiais, tais como
motion blur, depth of field, antialiasing e soft shadows;
· Frame buffer: geralmente consiste de todos os buffers do sistema;
· Double buffer: a renderização da cena é realizada de modo offscreen – back buffer.
Quando o render offscreen é concluído, o conteúdo do back buffer é copiado ao
front buffer – conteúdo onscreen, que é exibido na tela.
12
Graphics Processing Unit (GPU) e Shaders
Atualmente, as tarefas de processamento gráfico são realizadas por hardware dedicado,
por meio da GPU – Graphics Processing Unit, ou unidade de processamento gráfico –,
diferente do que acontecia há alguns anos, quando o processamento gráfico era realizado
via software. De acordo com Akenine-Möller, Haines e Hoffman (2008), a vantagem do
hardware dedicado é a velocidade, fator crítico para a renderização em tempo real.
Ademais, GPU evoluiu; começou com uma pipeline fixa em que era possível configurar
alguns estados e propriedades dessa e atualmente é programável, sendo que ainda existe a
configuração de alguns estados e propriedades da pipeline – mas programadores definem
também como alguns estágios da pipeline devem se comportar. A Figura 11 mostra a
pipeline da Vulkan API, sendo que os retângulos em azul são os estágios programáveis,
enquanto os com contornos de linhas tracejadas são opcionais.
Vertex Specification
Vertex Shader
Tessellation
Geometry Shader
Vertex Post-Processing
Primitive Assembly
Rasterization
Fragment Shader
Per-Sample Operations
13
13
UNIDADE
Efeitos Visuais para Jogos
Shaders são programados em linguagens parecidas com a C e depois são convertidos para
uma linguagem de máquina – vejamos um histórico resumido sobre as linguagens de shading:
· RenderMan Shading Language (RSL): criada pela Pixar em 1988, é ainda
usada na produção de filmes, porém, o render não é em tempo real;
· C for Graphics (Cg): criada pela Nvidia em 2002 junto com a Microsoft. Foi
usada para render em tempo real, mas está obsoleta – legacy. A recomendação
da própria Nvidia é usar HLSL ou GLSL;
· High-Level Shading Language (HLSL): criada pela Microsoft em 2002 junto
com o Cg – Nvidia – para render em tempo real com Direct3D;
· OpenGL Shading Language (GLSL): criada pela OpenGL ARB – Architecture
Review Board – em 2004 para render em tempo real e em multiplataforma –
suportando OpenGL, OpenGL ES e WebGL;
· Metal Shading Language: criada pela Apple em 2012 para os dispositivos da
própria empresa; é baseada em C++;
· Vulkan/SPIR-V: Vulkan é uma API gráfica multiplataforma criada pelo Khronos
Group – o mesmo consórcio responsável pelo OpenGL, GLSL e OpenCL –;
suporta shaders escritos em Standard Portable Intermediate Representation
(SPIR-V); trata-se de padrão definido em 2015.
Os shaders mais comuns são vertex shader e fragment shader – este conhecido
também como pixel shader –, embora existam outros, tais como tessellation shader
e geometry shader, conforme já mostrado na Figura 11. Cada shader tem aplicações
específicas e seguem a ordem definida pela pipeline:
· Vertex shader: trabalha com dados dos vértices – tais como posição, cor,
vetor normal e coordenada UV de textura –, convertendo os dados de entrada
– que vêm do aplicativo – do espaço do modelo ao da tela, sendo que novos
vértices não podem ser criados neste estágio;
· Tessellation shader: separado em dois tipos de shaders, tessellation control
shader – ou hull shader – e tessellation evaluation shader – ou domain shader
–, o estágio de tessellation recebe um vetor de vértices – patches –, subdividindo-
os em primitivas menores. Dessa forma, é possível definir que objetos mais
próximos da câmera tenham maior nível de detalhe – da malha – e os mais
distantes tenham menos detalhes;
· Geometry shader: este tipo pode criar primitivas a partir das que foram enviadas
no início da pipeline;
· Fragment shader: conhecido também por pixel shader, calcula a cor final e pro-
fundidade de cada fragmento – pixel – que será exibido na tela, podendo realizar
pós-processamento/aplicar filtro na imagem a ser exibida.
Shaders e Unity
Embora a Unity e outras game engines forneçam shaders escritos pela própria equipe que
desenvolve as ferramentas, é interessante entender como funciona e como escrever um shader,
seja para personalizar o visual de seu jogo, seja para entender o que acontece na parte gráfica.
14
Todo shader na Unity é escrito usando uma linguagem que a empresa estabeleceu como
ShaderLab, esta que define propriedades que são expostas no editor da Unity – para que
variáveis do shader possam ser configuradas pelo editor – e subshaders –, de modo que cada
subshader pode ser usado para GPU específicas – que possuem passes, sendo que os códigos
em linguagem de shading – Cg/HLSL, no caso da Unity – são escritos dentro de cada passe.
15
15
UNIDADE
Efeitos Visuais para Jogos
A Figura 14 contém um exemplo simples de vertex shader e fragment shader que converte
o modelo 3D do seu espaço de modelo para o espaço da tela – no vertex shader – e renderiza
o modelo com uma cor sólida estabelecida pelo editor da Unity – no fragment shader.
16
A linha 36 define qual é a função principal do vertex shader. Neste exemplo, é a função
chamada vert(), que está no intervalo de linhas 49 a 55. A linha 37 define a função principal
do fragment shader. Neste exemplo, é a função chamada frag(), que está no intervalo de
linhas 57 a 60.
A estrutura appdata, definida entre as linhas 39 a 42, contém os dados que vêm do jogo
e são enviados ao vertex shader – parâmetro appdata v da função vert(). Neste exemplo,
a estrutura possui apenas uma variável denominada pos, que define a posição do vértice.
A estrutura v2f, definida entre as linhas 44 a 47, contém os dados que são enviados do
vertex shader ao fragment shader – retorno da função vert() e parâmetro v2f i da função
frag(). Neste exemplo, a estrutura também possui apenas uma variável pos que indica a
posição do vértice, este convertido ao espaço da tela pelo vertex shader.
O código do vertex shader recebe um parâmetro appdata, que é preenchido com os da-
dos do jogo. Com base neste parâmetro, o código transforma o vértice – v.pos – ao espaço
da tela e retorna um v2f – que é passado ao fragment shader – que contém a posição do
vértice convertido ao espaço da tela.
Multiplicar a posição de um vértice no espaço do modelo pela matriz MVP é realizar a sequência
descrita no resumo da Figura 9.
Por fim, o fragment shader recebe um parâmetro v2f do vertex shader – neste
exemplo, o parâmetro não é usado pelo fragment shader – e retorna um half4 :
COLOR0, contendo um valor RGBA que define a cor do pixel na tela. Neste exemplo, o
fragment shader retorna a cor definida na propriedade “My Color”, via editor da Unity.
17
17
UNIDADE
Efeitos Visuais para Jogos
18
Material Complementar
Indicações para saber mais sobre os assuntos abordados nesta Unidade:
Sites
KHRONOS GROUP
OpenCL Overview
https://goo.gl/wWiMAK
NVIDIA
CUDA zone
https://goo.gl/PU8eXK
PIXAR
Pixar’s RenderMan
https://goo.gl/BMHxb6
ZUCCONI
A. Tutorials
https://goo.gl/rvuBvj
19
19
UNIDADE
Efeitos Visuais para Jogos
Referências
AKENINE-MÖLLER, T. Advanced computer graphics EDA 425, lp 4. 2003.
(Lecture slides).
20