Image Based Cartoon
Style Rendering
Jeronimo Silvério Venetillo
Fabio Issao Nakamura
O que é Cartoon Render?
• É uma uma forma de renderização não
fotorealística.
• Não é baseada nas leis físicas de
iluminação, mas sim na percepção
humana.
• Tenta realçar detalhes do modelo,
visando entendimento e não
fidelidade.
Características
• Realce de silhuetas.
• Realce de arestas.
• Poucos tons.
Silhueta
• Delimita o modelo
• É o conjunto de arestas que formam o
contorno de um modelo, dado um
observador.
Arestas
• Mostra as quinas do modelo.
• É o conjunto de arestas que compartilham duas
faces em que suas normais possuem um angulo
maior/menor que um determinado valor de
referencia.
Tons
• Normalmente apenas dois tons são usados.
• Não traz a noção de profundidade que a iluminação de phong
nos dá.
• Esta percepção é dada pela silhueta e/ou arestas do modelo.
• Um dos tons simula a parte iluminada e o outro a parte “em
sombra”.
• Com isso, a cor do material é preservada na integra e a
parte não iluminada é apenas um tom mais escuro desta cor.
• Temos uma divisão melhor de o que está sendo iluminado e o
que não está sendo iluminado.
Tons
Como Fazer?
• Usando Geometria e API Padrão
• Usando Geometria e Programação em
Placa (Vertex Shader).
• Usando Processamento de Imagem e
API Padrão.
• Usando Processamento de Imagem e
Programação em Placa (Pixel Shader).
Opção 1
• API convencional
• Independente de plataforma.
• Maquinas Silicon Graphics não tem
GPU programável.
Opção 2
• Processamento de Imagem
• “Não dependede” da geometria usada.
• Não tem a necessidade de desenhar
linhas.
Método
Cor Ambiente e Silhueta
• Renderizar cena vista da posição da
camera com as luzes desligadas. Cada
objeto tem sua cor ou textura afetado
apenas pela iluminação ambiente.
• Com esta renderização, obtemos dois
buffers. O ambientBuffer e o Z-Buffer.
• Aplicamos um filtro de detecção de
descontinuidade no Z-Buffer para
obtermos as silhuetas dos modelos
(silhuetteBuffer).
Filtro ( Parte 1 )
• O filtro usado para detecção de
descontinuidade foi o filtro de Sobel.
Filtro ( Parte 2 )
• Este operador produz um gradiente do Z-Buffer.
• As silhuetas são as áreas que possuem um
gradiente alto.
• Para extrair estas áreas, usamos o seguinte filtro
não linear:
p = min{ [(gmax – gmin )/kp]^2, 1 }
Onde gmax e gmin são os valores máximos e mínimos
da vizinhança 3x3 considerada.
• O parâmetro kp é o limiar de detecção e está
entre 0 e 1. Quanto menor kp, mais silhuetas serão
consideradas.
Método
Arestas
• Teoricamente a aplicação de um filtro de
segunda ordem no Z-buffer nos dá as
arestas.
• Na pratica, esse resultado se mostra muito
instável por problemas de aproximação.
• Podemos aplicar o mesmo filtro que
aplicamos no Z-Buffer se tivessemos um
mapa de normais da cena.
Mapa de Normais
• Podemos criar um mapa de normais da
cena!!
• Usamos a cor de cada pixel para guardar o
valor da normal naquele pixel ( rgb -> xyz )
• Substituimos as cores e texturas de todos
os objetos por um material totalmente
difuso e branco ( corAmbiente = preto,
corDifusa = branco, sem Especular )
• Desligamos as fontes de luz.
Mapa de Normais
• Fazemos uma passada de render ligando três luzes
direcionais, gerando normalBuffer1.
– Uma vermelha, na direção x
– Uma Verde, na direção y
– Uma Azul, na direção z
• Cada pixel que tem a normal (nx, ny, nz), terá a cor
( max(nx, 0), max(ny, 0), max(nz, 0) )
• Fazemos outra passada de render, invertendo a
direção das luzes , gerando normalBuffer2.
– Vermelha na direção –x
– Verde na direção –y
– Azul na direção -z
Mapa de Normais
• Precisamos agora fazer:
normalBuffer = normalBuffer1 – normalBuffer2
y
z
x
Arestas
• Aplicamos agora o mesmo
procedimento utilizado no Z-Buffer
no normalBuffer para obtermos as
arestas (creaseBuffer).
Linhas de Realce
• Temos agora dois buffers que mostram todas as
linhas que devem aparecer na imagem final.
• Para criarmos um único buffer, multiplicamos os
dois anteriores.
• lineBuffer = silhuetteBuffer * creaseBuffer
Método
Tons
• Calculamos os tons da imagem a partir do normalBuffer e do
•
•
ambientBuffer.
Usamos o produto escalar da posição da luz com o valor da normal
no pixel.
Caso ( Plight dot normalBuffer[p] ) > 0
iluminatedBuffer[p] = ambientBuffer[p] * LightColor
Caso contrário
iluminatedBuffer[p] = ambientBuffer[p]
Para cada luz a mais
Caso ( Plight dot normalBuffer[p] ) > 0
iluminatedBuffer[p] += ambientBuffer[p] * LightColor
Caso contrário
iluminatedBuffer[p] += ambientBuffer[p]
repeat
Normalmente apenas uma luz é utilizada.
Imagem Final
• Para gerar a imagem final,
multiplicamos o iluminatedBuffer pelo
lineBuffer.
• finalBuffer = iluminatedBuffer*lineBuffer
Método
Resultados e Conclusões
• Esse método utiliza muito a comunicação
entre a placa gráfica e a CPU, o que
geralmente é feito de maneira muito lenta.
• Por causa disso, taxas para tempo real
estão longe de serem alcançadas.
• Porém, alcançamos facilmente taxas
iterativas, o que nos permite fazer
visualização e inspeção de modelos.
Resultados e Conclusões
• O resultado visual se mostra muito
bom diante do proposto.
• Realmente o realce de detalhes fica
bem evidente.
Demo
• Cartoon.exe
Download

Cartoon - PUC-Rio