Estou no processo de implementar a dispersão atmosférica de planetas do espaço. Eu tenho usado os shaders de Sean O'Neil em http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html como ponto de partida.
Eu tenho praticamente o mesmo problema relacionado ao fCameraAngle, exceto com o sombreador SkyFromSpace, em oposição ao sombreador GroundFromSpace, como aqui: http://www.gamedev.net/topic/621187-sean-oneils-atmospheric-scattering/
Recebo artefatos estranhos com o céu do sombreador do espaço quando não uso fCameraAngle = 1
no loop interno. Qual é a causa desses artefatos? Os artefatos desaparecem quando o fCameraAngle é limitado a 1. Parece que também não tenho o tom presente na caixa de areia de O'Neil ( http://sponeil.net/downloads.htm )
Posição da câmera X = 0, Y = 0, Z = 500. GroundFromSpace à esquerda, SkyFromSpace à direita.
Posição da câmera X = 500, Y = 500, Z = 500. GroundFromSpace à esquerda, SkyFromSpace à direita.
Descobri que o ângulo da câmera parece ser tratado de maneira muito diferente, dependendo da fonte:
Nos shaders originais, o ângulo da câmera no SkyFromSpaceShader é calculado como:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Enquanto no solo, a partir do espaço shader, o ângulo da câmera é calculado como:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
No entanto, várias fontes online mexem com a negação do raio. Por que é isso?
Aqui está um projeto C # Windows.Forms que demonstra o problema e que eu usei para gerar as imagens: https://github.com/ollipekka/AtmosphericScatteringTest/
Atualização: Descobri no projeto ScatterCPU encontrado no site de O'Neil que o raio da câmera é negado quando a câmera está acima do ponto que está sendo sombreado, para que a dispersão seja calculada do ponto para a câmera.
Alterar a direção do raio de fato remove os artefatos, mas introduz outros problemas, conforme ilustrado aqui:
Além disso, no projeto ScatterCPU, O'Neil protege contra situações em que a profundidade óptica da luz é menor que zero:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
Como apontado nos comentários, junto com esses novos artefatos, isso ainda deixa a questão: o que há de errado com as imagens em que a câmera está posicionada em 500, 500, 500? Parece que o halo está focado na parte completamente errada do planeta. Seria de esperar que a luz estivesse mais próxima do ponto em que o sol deve atingir o planeta, e não de onde muda de dia para noite.
O projeto github foi atualizado para refletir as alterações nesta atualização.
fonte
Respostas:
No momento, não tenho código de trabalho, pois estou fazendo a transição do mecanismo, mas essas foram as configurações dos parâmetros de trabalho:
Este era o shader:
Deixe-me saber se ainda funciona. Se você precisar de outra ajuda, tentarei pesquisar meu código. Acho que usei duas esferas para fazer a renderização: uma para a superfície e outra para a atmosfera.
fonte
algumas trilhas de pensamento: verifique a precisão de seus carros alegóricos. em escalas espaciais, na maioria das vezes float32 não é suficiente. Marque dpeth buffer se você tiver renderização primitiva, como uma esfera sob o shader de dispersão.
Esses artefatos também podem ser encontrados no traçado de raios, geralmente são interseções de raios secundários com a superfície primária tremendo devido a problemas de precisão do flutuador.
EDIT: em 1000 (todos os números inteiros são totalmente representáveis até 16 milhões na representação float32, graças à mantissa de 24 bits), o próximo número para um float32 é 1000.00006103, portanto sua precisão ainda é muito boa nesse intervalo.
no entanto, se você usar faixas de medidores, ver um planeta a essa distância significaria valores de 100.000.000 e o próximo é 100000008: 8 metros de precisão a 100.000 km.
isso causaria pulos de câmera se você tentasse se mover por um satélite, por exemplo, e a renderização do satélite em si ficaria quebrada se o zero do seu mundo fosse o centro do planeta. se é o centro do sistema estelar, é ainda pior.
procure o flavien brebion (Ysaneya) e a busca infinita do jogo pela terra. Ele tem um interessante diário de desenvolvimento de gamedev e seu fórum, onde explica como é impossível gerenciar distâncias do sistema estelar usando absolutos.
Ele também menciona o problema do buffer de profundidade nesses tipos de faixas e é um dos primeiros, se não o primeiro, a introduzir escalas z logarítmicas. http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/ muito mais completo aqui: http://outerra.blogspot.jp/ 2012/11 / maximizing-depth-buffer-range-and.html
Cama de teste de software: boa ideia, é uma excelente maneira de criar shaders para que você possa depurar o que está acontecendo passo a passo. basta verificar seus valores, linhas por linhas, e se algo parecer estranho, você poderá investigar. Eu não vi no código que você postou a parte em que o ângulo da câmera é usado no sombreador, então estou um pouco intrigado com essa parte.
fonte