Mode 7 - Fog

Fog do inglês significa neblina. Como vimos no tutorial anterior, a distância de visualização está ilimitada e não tem um aspecto elegante. Neste tutorial, iremos implementar a rotina para adicionar uma neblina na renderização, e também vamos ajustar o código para utilizar um array de pixels, na qual ganhamos performance e facilidade na implementação.

Se você não viu o tutorial de implementação do mode 7, recomendo verificar, para você não ficar confuso neste tutorial.

Como vimos no nosso tutorial do mode 7, nossa variável Z que define a profundidade (Depth). É nela que iremos trabalhar nosso fog. Quanto mais baixo o valor de Z, mais escuro a cor do pixel a ser renderizado deve ficar. O resultado final deve ser algo como esta imagem:



1. Vamos começar substituindo algumas rotinas que estávamos utilizando no código passado. Uma dela é a forma de renderização dos pixels na tela. Utilizávamos o método setRGB(), porém há uma grande perda de performance se formos selecionar a cor de cada pixel. Iremos então criar um array de pixels, e realizar todas as devidas modificações no array, para no final, renderizar tudo de uma vez só. Sim, iremos usar um array, e não uma matriz, pois o método de renderização dos pixels que iremos utilizar suporta somente um array de pixels. 



2. Iremos agora atribuir as posições do array de pixels com o pixel adquirido da textura.



3. Após isto, cabe agora ajustarmos a forma de renderização para renderizar o array de pixels que criamos. Para isto, irei ajustar a rotina de renderização para utilizar o método setDataElements(), que está localizado no Raster da nossa imagem que será renderizada.



4. Agora está funcionando perfeitamente. Vamos começar a implementar a forma que o fog será gerado. Primeiramente iremos utilizar um array auxiliar, que daremos o nome de zBuffer. ZBuffer é uma técnica utilizada para definir a posição (profundidade) dos objetos renderizados na tela, evitando cada objeto ser renderizado sobreposto ao outro. Neste caso, usaremos o ZBuffer apenas para renderizar o fog. Vamos então criar o array auxiliar.



5. Temos então nosso array. Como mencionei, a variável que controla a profundidade de nosso Mode 7 é a variável Z, portanto vamos atribuir todas as posições de nosso zBuffer com o valor de nossa variável Z, lembrando que devemos ajustar para positivo caso o valor de Z seja negativo. Para isto utilizei um "IF Ternário" antes da atribuição acontecer.



6. Após gerarmos nosso mode 7, más antes de nossa renderização é onde iremos implementar nossa rotina de fog. Para a implementação, teremos que realizar o seguinte fluxo:

Percorrer o array de pixels
Buscar e separar os valores RGB de cada pixel
Subtrair o valor do ZBuffer para os valores RGB
Atribuir o pixel com estes novos valores


7. Para buscar e separar os valores RGB de uma variável inteira, existe um método na qual utilizamos os operadores bitwise para facilitar esta aquisição. Este método é muito utilizado quando se trata de valores RGB. Poderíamos utilizar a classe "Color" para realizar a separação das cores RGB, porém iríamos ter alguma perda de performance, já que estaríamos utilizando métodos para realizar esta separação.



8. Aproveitando, criaremos a rotina de junção dos valores RGB para uma única variável inteira. Este também é um método conhecido quando se trata de valores RGB utilizando operadores bitwise. Assim, vamos atribuir o novo valor ao pixel que está sendo analisado.



9. Após adquirir estes valores, precisamos pegar o valor do array auxiliar ZBuffer. Também vamos realizar uma divisão de um inteiro pelo valor do ZBuffer, para criar um controle de intensidade do fog. Quanto maior o valor, mais intenso o fog será. Utilizei o valor 5000 pois obtive bons resultados.



10. Vamos subtrair o valor RGB pela intensidade para obter o novo valor do pixel. Também devemos criar uma validação, caso o valor ser negativo, para não atribuir o valor das cores com valor abaixo de zero.



Pronto! Nosso FOG está feito! Abaixo segue uma demonstração do resultado.


Caso você deseje ter acesso ao código fonte, acesse meu repositório no GitHub:
https://github.com/vinibiavatti1/mode7

Comentários

Postagens mais visitadas deste blog

Mode 7

RayCasting

Mode 7 - Rotation