Jestem w trakcie wdrażania rozpraszania atmosferycznego planet z kosmosu. Korzystam z shaderów Seana O'Neila z http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html jako punktu wyjścia.
Mam prawie ten sam problem związany z fCameraAngle, z wyjątkiem modułu cieniującego SkyFromSpace w przeciwieństwie do modułu cieniującego GroundFromSpace, jak tutaj: http://www.gamedev.net/topic/621187-sean-oneils-atmospheric-scattering/
Dziwne artefakty z nieba pojawiają się z modułu cieniującego, gdy nie są używane fCameraAngle = 1
w wewnętrznej pętli. Co jest przyczyną tych artefaktów? Artefakty znikają, gdy fCameraAngle zostanie ograniczone do 1. Wydaje mi się, że brakuje mi też odcienia obecnego w piaskownicy O'Neila ( http://sponeil.net/downloads.htm )
Pozycja kamery X = 0, Y = 0, Z = 500. GroundFromSpace po lewej, SkyFromSpace po prawej.
Pozycja kamery X = 500, Y = 500, Z = 500. GroundFromSpace po lewej, SkyFromSpace po prawej.
Przekonałem się, że kąt kamery wydaje się różnie traktowany w zależności od źródła:
W oryginalnych modułach cieniujących kąt kamery w SkyFromSpaceShader jest obliczany jako:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Natomiast w ziemi z modułu cieniującego kąt kamery oblicza się jako:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
Jednak różne źródła online majstrują przy negacji promienia. Dlaczego to?
Oto projekt C # Windows.Forms, który demonstruje problem i użyłem go do generowania obrazów: https://github.com/ollipekka/AtmosphericScatteringTest/
Aktualizacja: dowiedziałem się z projektu ScatterCPU znalezionego na stronie O'Neila, że promień kamery jest negowany, gdy kamera znajduje się powyżej punktu cieniowanego, dzięki czemu rozproszenie jest obliczane od punktu do kamery.
Zmiana kierunku promienia rzeczywiście usuwa artefakty, ale wprowadza inne problemy, jak pokazano tutaj:
Ponadto w projekcie ScatterCPU O'Neil chroni przed sytuacjami, w których głębokość optyczna światła jest mniejsza niż zero:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
Jak wskazano w komentarzach, wraz z tymi nowymi artefaktami wciąż pozostaje pytanie, co jest nie tak z obrazami, na których aparat jest ustawiony na 500, 500, 500? Wydaje się, że halo koncentruje się na całkowicie niewłaściwej części planety. Można się spodziewać, że światło będzie bliżej miejsca, w którym słońce powinno uderzyć w planetę, a nie w miejsce, w którym zmienia się z dnia na noc.
Projekt github został zaktualizowany, aby odzwierciedlić zmiany w tej aktualizacji.
źródło
Odpowiedzi:
Obecnie nie mam działającego kodu, ponieważ zmieniam silnik, ale były to moje parametry pracy:
To był moduł cieniujący:
Daj mi znać, jeśli nadal działa. Jeśli potrzebujesz innej pomocy, postaram się przekopać mój kod. Wydaje mi się, że do renderowania użyłem dwóch sfer: jednej dla powierzchni i jednej dla atmosfery.
źródło
kilka pomysłów: sprawdź dokładność swoich pływaków. w skalach kosmicznych większość czasu float32 to za mało. Sprawdź bufor dpeth, jeśli masz prymitywne renderowanie, takie jak kula pod shaderem rozpraszającym.
Te artefakty można również znaleźć w śledzeniu promieni, są to zwykle przecięcia promieni wtórnych z drżeniem pierwotnej powierzchni z powodu problemów z precyzją ruchu.
EDYCJA: przy 1000 (wszystkie liczby całkowite są w pełni reprezentatywne do 16 milionów w reprezentacji float32, dzięki 24-bitowej mantysie), kolejna liczba dla float32 to 1000.00006103, więc twoja precyzja jest nadal całkiem dobra w tym zakresie.
jeśli jednak użyjesz zasięgów metrów, aby zobaczyć planetę, odległość ta oznaczałaby wartości 100 000 000, a następna to 100000008: 8 metrów precyzji na 100 000 km.
spowodowałoby to skoki kamery, gdybyś próbował na przykład poruszać się po satelicie, a rendering samego satelity zostałby przerwany, jeśli zero twojego świata jest centrum planety. jeśli jest to środek układu gwiezdnego, jest jeszcze gorzej.
wyszukaj Flavien Brebion (Ysaneya) i poszukiwanie nieskończoności gry dla Ziemi. Ma ciekawy dziennik deweloperów gamedev i swoje forum, na których wyjaśnia, w jaki sposób nie można zarządzać odległościami między systemami gwiezdnymi za pomocą absolutów.
Wspomina także o problemie bufora głębokości przy tego rodzaju zakresach i jest jednym z pierwszych, jeśli nie pierwszym, który wprowadza logarytmiczne skale z. http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/ wiele więcej tutaj: http://outerra.blogspot.jp/ 2012/11 / maksymalizacja-głębokość-bufor-zakres-i.html
Oprogramowanie testowe: dobry pomysł, jest to doskonały sposób na tworzenie shaderów, dzięki czemu możesz debugować to, co dzieje się krok po kroku. po prostu sprawdzaj wartości po linii, a jeśli coś wygląda dziwnie, możesz to sprawdzić. Nie widziałem w kodzie, w którym opublikowałeś część, w której kąt cieniowania jest używany w module cieniującym, więc jestem nieco zdziwiony tą częścią.
źródło