środa, 25 marca 2009

Premature optimization is root of all evil

Niby wiem wiem, że tak jest. Nawet nie dawno na forum warsztatu sugerowałem Lukaz'owi, żeby najpierw nauczył się programować i dopiero potem pomyślał o wydajności. I co, i sam się wpakowałem w optymalizowanie czegoś, co wciąż jest dla mnie nowością.

Chcę wykorzystać shadow mapping jako technikę oświetlenia w swoim silniku. Kod od strony silnika jest już gotowy. Zostało tylko napisać (raczej dostosować niż napisać) shadery.
1) Renderowanie shadow mapy. Trzeba zapisać wartość głębokości, czyli z / w. Sprytnie wymyśliłem, że można tu ładnie zaoszczędzić wykonując to dzielenie w vertex shaderze. Wartość powinna się ładnie interpolować.
W vertex shaderze dodałem parametr:
out float oDepth : TEXCOORD2
, oraz kod obliczający ten parametr:
oDepth = oPosition.z / oPosition.w;
Pixel shader był nowy:
void ps(in float depth : TEXCOORD2, out float3 oColor : COLOR)
{

oColor = float3(depth , depth , depth);
}

2) Renderowanie wynikowego obrazka. Tutaj vertex shader wzbogacił się o wyliczanie pozycji względem światła, a pixel shader zajął się wyznaczeniem koordynatów dla shadow mapy, dystansu od światła i stwierdzeniem czy cień jest czy go nie ma.
GeometriaProjekcja shadow mapyDystans do światła


Jak widać zawartość shadow mapy nie pokrywa się z dystansem. Dokładniej to mamy źle wyznaczoną shadow mapę. Czemu ?? Błąd pojawia się gdy któryś wierzchołek znajduję się za światłem, czyli ma ujemną współrzędną z. Nie wiem dokładnie czemu tak się dzieje, jednak wydaje się, że taki trójkąt ma niewłaściwie interpolowany parametr depth. Przeniosłem dzielenie z / w do pixel shadera, rozwiązało to problem.
Wynikowe światło

Efekt wciąż nie jest poprawny, ale jest progress :)

Brak komentarzy: