Uwzględnianie fal przy odbiciach planarnych

13

Studiowałem przykłady Nvidii z SDK, w szczególności projekt Island11 i znalazłem coś ciekawego w kawałku kodu HLSL, który koryguje odbicia w górę iw dół w zależności od stanu wysokości fali.

Oczywiście po przeanalizowaniu krótkiego akapitu kodu:

// calculating correction that shifts reflection up/down according to water wave Y position
float4 projected_waveheight = mul(float4(input.positionWS.x,input.positionWS.y,input.positionWS.z,1),g_ModelViewProjectionMatrix);
float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;
projected_waveheight = mul(float4(input.positionWS.x,-0.8,input.positionWS.z,1),g_ModelViewProjectionMatrix);
waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;
reflection_disturbance.y=max(-0.15,waveheight_correction+reflection_disturbance.y);

Moje pierwsze przypuszczenie było takie, że kompensuje odbicie planarne, gdy jest poddawane pionowym zaburzeniom (falom), przesuwając odbijaną geometrię do punktu, w którym nic nie ma, a woda jest renderowana tak, jakby nic tam nie było lub tylko niebo:

wprowadź opis zdjęcia tutaj

Teraz to niebo odbija się w miejscu, w którym powinniśmy zobaczyć zielone / szare / żółtawe odbicie terenu z linią bazową wody. Mój problem polega teraz na tym, że nie jestem w stanie dokładnie określić logiki, która się za tym kryje. Rzutowanie rzeczywistej pozycji w przestrzeni świata punktu geometrii fali / wody, a następnie pomnożenie przez -5f, tylko po to, aby wykonać kolejną projekcję tego samego punktu, tym razem ze współrzędną y zmieniono na -0,8 (dlaczego -0,8?).

Wskazówki w kodzie wydają się wskazywać, że został uzyskany metodą prób i błędów, ponieważ występuje nadmiarowość. Na przykład autor przyjmuje ujemną połowę rzutowanej współrzędnej y (po podziale w):

float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;

A potem robi to samo dla drugiego punktu (tylko pozytywne, aby uzyskać jakąś różnicę, jak sądzę) i łączy je:

waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;

Po usunięciu podziału przez 2 nie widzę żadnej różnicy w poprawie jakości (jeśli ktoś chce mnie poprawić, proszę). Sednem tego wydaje się być różnica w rzutowanym y, dlaczego tak jest? Ta redundancja i pozornie arbitralny wybór -8f i -0,15f doprowadziły mnie do wniosku, że może to być kombinacja pracy heurystycznej / zgadywania. Czy jest to uzasadnione logicznie, czy jest to desperacki hack?

Oto przesada pierwotnego problemu, który naprawia fragment kodu, obserwowany na najniższym poziomie teselacji. Mam nadzieję, że zrodzi to pomysł, za którym tęsknię. -8f może być wysokością odniesienia, na podstawie której można wywnioskować, jak bardzo zakłócać współrzędną tekstury próbkowanie renderowanej geometrii płaskiej, a -15f może być dolną granicą, środkiem bezpieczeństwa.

wprowadź opis zdjęcia tutaj

CloseReflector
źródło

Odpowiedzi:

1

Ta technika musi mieć ten artefakt i dlatego przez większość czasu, gdy jest używana, stosujemy przesunięcie pionowe do wyszukiwania, aby zrobić to tak, jakby rzeczywista płaszczyzna odbicia znajdowała się pół metra powyżej jej rzeczywistej pozycji. Tak, ma tę wadę, że nie ma idealnie dopasowanego odbicia, ale lepiej jest dziury.

v.oddou
źródło
2
Czy możesz opracować więcej?