Sto implementando lo scattering atmosferico di un pianeta dallo spazio. Ho usato gli shader di Sean O'Neil da http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html come punto di partenza.
Ho praticamente lo stesso problema relativo a fCameraAngle tranne che con lo shader SkyFromSpace rispetto allo shader GroundFromSpace come qui: http://www.gamedev.net/topic/621187-sean-oneils-atmospher-scattering/
Ottengo strani artefatti con il cielo dallo space shader quando non lo uso fCameraAngle = 1
nel circuito interno. Qual è la causa di questi artefatti? Gli artefatti scompaiono quando fCameraAngle è limitato a 1. Mi sembra anche che manchi la tonalità presente nella sandbox di O'Neil ( http://sponeil.net/downloads.htm )
Posizione della telecamera X = 0, Y = 0, Z = 500. GroundFromSpace a sinistra, SkyFromSpace a destra.
Posizione della telecamera X = 500, Y = 500, Z = 500. GroundFromSpace a sinistra, SkyFromSpace a destra.
Ho scoperto che l'angolazione della telecamera sembra gestita in modo molto diverso a seconda della fonte:
Negli shader originali l'angolo della telecamera in SkyFromSpaceShader viene calcolato come:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Mentre nel terreno dallo space shader l'angolo della telecamera viene calcolato come:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
Tuttavia, varie fonti online armeggiano con la negazione del raggio. Perchè è questo?
Ecco un progetto Windows.Forms in C # che dimostra il problema e che ho usato per generare le immagini: https://github.com/ollipekka/AtmospherScatteringTest/
Aggiornamento: ho scoperto dal progetto ScatterCPU trovato sul sito di O'Neil che il raggio della videocamera viene negato quando la videocamera si trova sopra il punto in ombra, in modo che la dispersione venga calcolata dal punto alla videocamera.
La modifica della direzione del raggio rimuove effettivamente gli artefatti, ma introduce altri problemi come illustrato qui:
Inoltre, nel progetto ScatterCPU, O'Neil protegge da situazioni in cui la profondità ottica della luce è inferiore a zero:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
Come sottolineato nei commenti, insieme a questi nuovi artefatti questo lascia ancora la domanda, cosa c'è di sbagliato con le immagini in cui la fotocamera è posizionata a 500, 500, 500? Sembra che l'aureola sia focalizzata su una parte del pianeta completamente sbagliata. Ci si aspetterebbe che la luce sarebbe più vicina al punto in cui il sole dovrebbe colpire il pianeta, piuttosto che dove cambia da giorno a notte.
Il progetto github è stato aggiornato per riflettere le modifiche in questo aggiornamento.