Estoy en el proceso de implementar la dispersión atmosférica de planetas desde el espacio. He estado usando los sombreadores de Sean O'Neil de http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html como punto de partida.
Tengo casi el mismo problema relacionado con fCameraAngle, excepto con el sombreador SkyFromSpace en lugar del sombreador GroundFromSpace que aquí: http://www.gamedev.net/topic/621187-sean-oneils-atmospheric-scattering/
Obtengo artefactos extraños con el cielo del sombreador espacial cuando no lo uso fCameraAngle = 1
en el bucle interno. ¿Cuál es la causa de estos artefactos? Los artefactos desaparecen cuando fCameraAngle se limita a 1. También parece que me falta el tono que está presente en la caja de arena de O'Neil ( http://sponeil.net/downloads.htm )
Posición de la cámara X = 0, Y = 0, Z = 500. GroundFromSpace a la izquierda, SkyFromSpace a la derecha.
Posición de la cámara X = 500, Y = 500, Z = 500. GroundFromSpace a la izquierda, SkyFromSpace a la derecha.
Descubrí que el ángulo de la cámara parece manejarse de manera muy diferente dependiendo de la fuente:
En los sombreadores originales, el ángulo de la cámara en SkyFromSpaceShader se calcula como:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Mientras que en el suelo desde el sombreador espacial, el ángulo de la cámara se calcula como:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
Sin embargo, varias fuentes en línea juegan con negar el rayo. ¿Por qué es esto?
Aquí hay un proyecto de C # Windows.Forms que demuestra el problema y que he utilizado para generar las imágenes: https://github.com/ollipekka/AtmosphericScatteringTest/
Actualización: descubrí por el proyecto ScatterCPU encontrado en el sitio de O'Neil que el rayo de la cámara se niega cuando la cámara está por encima del punto sombreado, de modo que la dispersión se calcula de un punto a la cámara.
Cambiar la dirección del rayo de hecho elimina los artefactos, pero introduce otros problemas como se ilustra aquí:
Además, en el proyecto ScatterCPU, O'Neil protege contra situaciones en las que la profundidad óptica de la luz es inferior a cero:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
Como se señaló en los comentarios, junto con estos nuevos artefactos esto todavía deja la pregunta, ¿qué hay de malo en las imágenes donde la cámara está posicionada en 500, 500, 500? Parece que el halo está enfocado en una parte completamente equivocada del planeta. Uno esperaría que la luz estuviera más cerca del lugar donde el sol debería golpear el planeta, en lugar de donde cambia de día a noche.
El proyecto github se ha actualizado para reflejar los cambios en esta actualización.