Sat
12
May 2007
Dzisiaj dopisałem nowy tryb Shadow Mappingu, w którym używam tekstury w formacie A8R8G8B8. To już nie ma prawa nie działać :) Wartość głębokości pakuję do składowych RGB. Składowa A pozostaje do wykorzystania przez Alpha Testing. Zresztą kodując liczbę typu float i tak nie uzyskałbym dokładności większej niż 24 bity, a nawet 16 wystarczy do tego celu.
Jak to się dokładnie robi? Niełatwo znaleźć konkretne informacje na ten temat. Pomogły mi dwa tematy forum: ten i ten. Ostatecznie mój kod wygląda tak:
// Kodowanie float v = In.ShadowMapZW.x / In.ShadowMapZW.y; // Tak naprawdę to zw Out = v * float4( 256*256, 256, 1, 0 ); Out = frac(Out); //Out -= Out.rrgb * float4( 0, 1.0/256.0, 1.0/256.0, 0 ); // Dekodowanie const float4 Factors = float4(1/256/256, 1/256, 1, 0); sample = dot(Factors, tex2D(s, t)); itd...
Ta ostatnia linijka w kodowaniu jest zakomentowana, ponieważ choć na forum zalecali ją jako niezbędna do pozbycia się artefaktów, a w moim przypadku właśnie jej usunięcie doprowadziło cienie do porządku. Rozchodzi się tutaj tak naprawdę o pytanie, czy kodując wychodzącą z Pixel Shadera wartość rzeczywistą 0.0 .. 1.0 do całkowitoliczbowego bajtu 0, 1, ..., 255 karta pozostałą część ułamkową obcina czy też zaokrągla? Ayufan twierdzi że obcina i moje doświadczenie też to potwierdza. Ale czy tak jest zawsze? Czy to jest zdefiniowane, czy zależne od konkretnej karty? Tego chyba trudno będzie się dowiedzieć...