sexta-feira, 14 de abril de 2017

Atividade 5 - Implementando o Path Tracer

Depois de criar a base necessária, agora é hora de construir o verdadeiro propósito da disciplina, um Path Tracer. Path Tracing é o método de renderização de uma cena 3D mais realista da atualidade, e por isso usa um algoritmo bem pesado, chegando a demorar mais de 10 minutos para renderizar uma imagem de baixa resolução com qualidade aceitável, isso claro quando ainda não foi aplicado nenhum algoritmo de otimização, que é o nosso caso.

Para entender como implementar o algoritmo, nós precisamos estudar o comportamento da luz e dos materiais em conjunto com ela para criar uma imagem.
Uma fonte de luz emite infinitos raios em todas as direções, estes raios ao colidirem com alguma superfície são refletidos, como e para onde eles são refletidos depende de que material é feita a superfície em que ele colidiu.
Neste trabalho nós implementamos o material difuso, onde um raio de luz, ao se chocar numa superfície com essas características é refletida igualmente para todos os lados.

Diferente do algoritmo anterior, onde eram lançados raios através de um pixel da tela e na sua primeira intersecção o pixel era pintado da cor do material intersectado, para que o resultado fosse realista nós precisaríamos aplicar uma fórmula, mais conhecida como a Rendering Equation:


Que nos dá a radiância (Lo) que sai de uma superfície a partir da soma da radiância emitida (Le) e refletida. A radiância refletida é o somatório das radiâncias incidentes (Li) de todas as direções multiplicada pela refletância da superfície (fr) e o cosseno do ângulo de incidência.

Essa equação necessita do cálculo de uma integral recursiva, e para resolvê-la é utilizado a Método Monte Carlo de integração, obtendo o seguinte estimador:


Que quando é designada para materiais difusos, pode ser ainda mais simplificado.


Com a equação podemos determinar a cor dos pixels, a aplicando em cada raio gerado a partir da câmera e suas reflexões subsequentes. Um raio de luz pode ser refletido até que ele fique sem energia, por isso nós fomos aconselhados pelo professor a refletir o raio que vem da câmera 5 vezes, e assim obter mais exatidão no resultado final.

Agora vamos para a implementação propriamente dita. A primeira coisa feita foi modificar as primitivas, para que ao invés de possuir um atributo cor, possuir uma brdf e uma emitância, ambos vetores de três variáveis.

Depois disso só restou restou criar a função recursiva que calcula a integral para cada raio, o que claro não foi um trabalho fácil, gastamos muito tempo resolvendo bugs e melhorando nosso código, aqui estão algumas imagens do nosso código em desenvolvimento, com vários erros e bugs:


Mas depois de muito sofrimento nós conseguimos resolver os problemas e nosso Path Tracer agora está funcionando perfeitamente:


Nós também fizemos algumas experiências comparando o tanto e raios lançados para cada pixel da imagem, e colocamos tudo em um gif:

rpp: Raios por pixel
Como pode-se ver há uma melhora exponencial no começo, de 100 para 200 rpp, onde ainda dá para ser visto o padrão criado pela função de aleatoriedade que nós usamos, mas conforme o número de raios por pixel aumenta, mais o resultado converge para o esperado até que mesmo aumentando muito a diferença é pouca, como por exemplo de 1200 para 1700 rpp.

Com isso nós concluímos mais um post e com orgulho de dizer que agora nós temos o nosso próprio Path Tracer, a próxima etapa agora é implementar algoritmos que deixem este código mais rápido e otimizem o resultado sem comprometer o realismo. Até a próxima!

quinta-feira, 2 de março de 2017

Atividade 4 - Carregando Malhas de Triângulos e aplicando cores


Carregando Malhas

Após implementar a câmera perspectiva, a próxima etapa é, com a ajuda do Assimp, implementar o suporte a formas mais complexas de objetos 3D, pois não se pode fazer nada muito realista só com esferas e triângulos. A biblioteca Assimp oferece suporte para tornar mais fácil a leitura e tratamento de vários formatos de objetos 3D. Através do Assimp, um arquivo do tipo ".obj" foi transformado em uma lista de triângulos, e nós só precisávamos renderizar estes triângulos na tela usando a função que nós já criamos, logo, carregando o modelo default do blender, a cabeça de macaco, o resultado foi esse:


Atribuindo Cores

A próxima etapa foi descartar este algoritmo que controlava o tom de branco de acordo com a distância da tela e, atribuir cor para todas as primitivas. A maneira mais simples de fazer isso é simplesmente adicionar o atributo "cor" para a classe "primitives", o qual seria um vetor de três valores, r, g e b, representando respectivamente Vermelho, Verde e Azul. E para demonstrar o funcionamento desta mudança nós carregamos um modelo de um boneco Lego e atribuímos cores aleatórias para todos os seus triângulos, o resultado é mostrado abaixo:

  

E assim concluímos nossa quarta atividade da disciplina.

Repositório no GitHub do nosso Ray Tracer: https://github.com/avin1cius/RT-Template

Atividade 3 - Câmera Pinhole arbitrária


A implementação da câmera pinhole foi bem trivial. Partindo do reaproveitamento do código da câmera ortográfica, bastou ser adicionado o atributo de distância entre o ponto focal e a tela, e com isso o cálculo da direção dos raios, que agora possuem a mesma origem.

Abaixo temos uma imagem gerada a partir da Pinhole, todas as esferas estão posicionadas nas mesmas coordenadas x e y, mas com z variando de -1 a -5 para demonstrar a distorção perspectiva gerada pela câmera.


A imagem cima foi gerada com a câmera posicionada no centro do universo. Posicionando-a em um ponto arbitrário foi gerada a seguinte imagem:



Repositório no GitHub do nosso Ray Tracer: https://github.com/avin1cius/RT-Template


quinta-feira, 16 de fevereiro de 2017

Atividade 2 - Interseção Raio-Triângulo


Após nos socializarmos com o Mitsuba, agora é a hora de começar a codificar o nosso próprio render, mas partindo de um template [RT-Template] com as funções básicas e a primitiva Esfera já implementados.
Como exercício foi solicitado a implementação da primitiva Triângulo, para isso foi necessária a leitura do Capítulo 10 do livro Realistic Ray Tracing de Peter Shirley que demonstra o algoritmo de interseção Raio-Triângulo.
Nós implementamos o algoritmo da maneira que foi instruído no livro e o resultado foi o esperado:


Depois adicionamos mais triângulos como foi pedido pelo professor:



sexta-feira, 3 de fevereiro de 2017

Tutorial: Instalando o Mitsuba no Ubuntu 16.04


A instalação do Mitsuba no Ubuntu 16.04 não é trivial como nas versões que possuem pacotes disponibilizado para download no site.

Antes de começar o processo, é necessário baixar os seguintes arquivos:

mitsuba e collada-dom: http://www.mitsuba-renderer.org/releases/current/trusty/
libpython3.4-minimal: https://launchpad.net/ubuntu/xenial/amd64/libpython3.4-minimal/3.4.4-2ubuntu3
libpython3.4-stdlib: https://launchpad.net/ubuntu/xenial/amd64/libpython3.4-stdlib/3.4.4-2ubuntu3
libpython3.4: https://launchpad.net/ubuntu/xenial/amd64/libpython3.4/3.4.4-2ubuntu3

Como os pacotes do Mitsuba e COLLADA são destinados para o Ubuntu 14.04 (Trusty Tahr), eles dependem de bibliotecas com versões específicas para o Trusty, e para as instalarmos temos que adicionar o repositório dessa versão, e para isso, basta por as seguintes linhas no terminal:

sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty main"
sudo apt update


Com isso já se pode instalar o COLLADA

cd Downloads (pasta onde foram baixados os arquivos)
sudo dpkg -i collada-dom_2.4.0-1_amd64.deb
? sudo apt -f install

E também as bibliotecas do Python 3.4

sudo dpkg -i libpython3.4-minimal_3.4.4-2ubuntu3_amd64.deb
sudo dpkg -i libpython3.4-stdlib_3.4.4-2ubuntu3_amd64.deb
sudo dpkg -i libpython3.4_3.4.4-2ubuntu3_amd64.deb

Finalmente, com todas as dependências necessárias instaladas, pode-se então instalar o Mitsuba

sudo dpkg -i mitsuba_0.5.0-1_amd64.deb.








quinta-feira, 2 de fevereiro de 2017

Atividade 1 - Criar uma cena utilizando um Physically Based Renderer


Como primeira atividade nos foi designado escolher um dos seguintes renderers: PBRT e Mitsuba Renderer, ambos são Physically Based Renderers, ou seja, eles simulam a luz e todos os efeitos de iluminação usando fórmulas avançadas de física e assim fazendo com que a simulação seja fotorealista.

Primeiramente nós queríamos usar o PBRT, pois ele aparenta ser mais completo, devido à todo o trabalho que foi feito sobre ele. Mas depois de passar dois dias com problemas para instalá-lo tanto no Windows quanto no Ubuntu, nós decidimos usar o Mitsuba Renderer, pois ele nem necessitava de instalação no Windows e funcionava perfeitamente.

Primeiramente nós baixamos uma cena exemplo, para nos familiarizarmos com a interface do Mitsuba, e também para começar a compreender a sintaxe dos arquivos xml que ele usa como fonte para construir as cenas.

Após mexer bastante nesta cena nós criamos um arquivo novo e começamos de zero, criando e localizando cada objeto na nossa cena.

Nós produzimos duas cenas, a primeira mostra um modelo de um cavaleiro feito de ouro, com um retângulo abaixo dele para representar uma mesa de mármore, e duas esferas, uma luminosa e outra de material reflexivo (alumínio polido). Esta imagem explora bastante os efeitos visuais provocados pela reflexão da luz na armadura do cavaleiro que não é nada uniforme, espelhando a luz em vários ângulos, e também podemos ver a reflexão completamente uniforme na segunda esfera do que há ao redor dela, sendo distorcida por causa de sua forma:

Ornstein the Dragonslayer
A segunda imagem mostra uma miniatura de uma Esfinge feita de plástico colocada em um plano perto de uma parede, a mesma com um ponto de luz apontado diretamente para ela, projetando assim a sua sombra contra a parede:

Mesma cena mas com uma luz mais forte
Com isso pudemos aprender como manipular o Mitsuba, que servirá como base de comparação com o renderer que será desenvolvido durante o curso, e também pudemos entender melhor e presenciar como funciona um Rederer Baseado em Física.