Raytracer OSL usando a estrutura BRL-CAD

Faz algum tempo que eu não posto sobre meu projeto do BRL-CAD, mas é porque eu não vinha tendo nenhum resultado interessante para mostrar. A maior parte do tempo eu gastei resolvendo aspectos mais técnicos de programação, sobre os quais escrevi nas últimas semanas.

Interface OSL BRL-CAD

Comecei escrevendo uma interface para o renderizador OSL. Essa interface recebe os dados necessários sobre o ponto sendo renderizado. Esses dados incluem: as coordenadas do ponto P sendo renderizado, o nome do shader da superfície a qual P pertence, a normal dessa superfície em P e a direção do raio de incidência em P.

Essa modularização permite que o modo como o renderizador OSL calcula a cor nesse ponto seja transparente à aplicação. Por outro lado, o renderizador não precisa saber como os objetos da cena são manipulados e como as interseções são calculadas.

Um problema é que o renderizador OSL pode decidir que o raio será refletido (por exemplo se o shader não for totalmente opaco). Como ele não sabe nada sobre a cena sendo renderizada, ele precisa devolver o trabalho para a aplicação. Por isso, ele retorna uma estrutura dizendo se houve reflexão e qual a direção do raio refletido.

Com esse novo raio, a aplicação fará seus cálculos e chamará a interface novamente.

Testando a interface

Antes de partir para a implementação do shader osl, decidi testar a nova interface com uma adaptação daquele raytracer sobre o qual falei em um post anterior.

Usando a mesma cena, consegui reproduzir as mesmas imagens.

Conversando com um dos meus mentores, me foi sugerido então tentar renderizar uma cena modelada no BRL-CAD usando apenas shaders osl.

Cornell box na interface do mged.

A cena é conhecida por caixa de cornell. Para determinar as interseções de um raio com um objeto, usei a função rt_shootray provida pelo BRL-CAD. Para ela, devemos passar a origem e direção do raio além de uma callback que será chamada sempre que um raio for atingido. Me baseei nesse exemplo.

Para testar, fiz as paredes e o teto serem um azul difuso, o chão ser vermelho difuso, a caixa alta um amarelo difuso e a caixa mais baixa um espelho. O resultado ficou o seguinte, com 400 amostragens:

Cena renderizada com 400 amostragens.

Apesar de a cena ter ficado meio escura, gostei do resultado.

Próximos passos

Minha ideia agora é adaptar esse código para o shader osl. Já andei fazendo alguns testes e a tarefa não parece simples. Um problema é que o aplicativo rt, que usará o shader osl, só atira um raio por pixel, enquanto o código acima usa vários.

Isso é necessário porque a direção do raio de saída de um shader osl é probabilística e é preciso uma grande amostragem de raios para ter a cor mais próxima do esperado.

Para se ter uma ideia, veja a cena da caixa de cornell renderizada com um número baixo de amostragens:

Cena renderizada com 4 amostragens.

Outro problema com o qual terei que lidar é a mistura de shaders do BRL-CAD com os shaders OSL. O mecanismo de funcionamento deles é meio diferente e terei que estudá-los mais a fundo para fazer uma eventual adaptação.

No mais, fiquei mais tranquilo de ter conseguido implementar um renderizador independente, pois isso se mostra um projeto mais concreto no qual eu posso continuar trabalhando e apresentar no final, caso a implementação do shader osl não dê resultados.

Meu medo era de ficar enroscado com algum problema e por isso o projeto não ser bem sucedido.

Nota finais

Ganhei acesso de commit ao código-fonte do BRL-CAD. É bastante satisfatório poder contribuir diretamente com um código grande, que é usado por muitas pessoas.

A regra da comunidade é fazer commits constantemente, sempre que o código estiver estável. Por enquanto só fiz atualizações do meu programa e uma correção de erros de digitação que encontrei perdidos no código.

O BRL-CAD possui uma página no ohloh, onde dá pra ver os contribuidores e os commits que foram feitos.

Os comentários estão fechados.