Jaki jest najlepszy sposób wypróbowania pełnoekranowych tekstur w module cieniującym fragmenty, na przykład bufor g w odroczonym rendererze lub tekstura sceny w shaderze postprocesowym?Najlepszy sposób na przetestowanie pełnoekranowej tekstury
Obecnie używam dwóch następujących sposobów:
Pass rozmiar ekranu do modułu cieniującego jako jednolite i obliczyć (u, v) od
gl_FragCoord
:vec2 texCoord = gl_FragCoord.xy/vScreenSize; vec3 c = texture(tex, texCoord).rgb;
nie działa wydają się idealne, ponieważ wymagany jest podział, a dostarczanie cieniowania z rozmiarem ekranu jest kłopotliwe.
Konwersja
gl_FragCoord.xy
w produktivec
i używaćtexelFetch
:vec3 c = texelFetch(tex, ivec2(gl_FragCoord.xy), 0).rgb;
także nie jest idealny, ponieważ wymagana jest konwersja z
float
doint
.
Czy istnieje lepszy sposób? Naprawdę chcę tylko wypróbować bufor dokładnie w punkcie, w którym rysuje się mój moduł cieniujący pikseli.
// EDIT:
Ok, z sugestiami interpolowana współrzędnych tekstury, które pochodzą z vertex shader udało mi się zorientować się następujący kod:
Vertex shader:
#version 150
uniform mat4 im_ModelViewProjectionMatrix;
in vec3 iv_Vertex;
noperspective out vec2 vVertCoord;
void main(void)
{
gl_Position = im_ModelViewProjectionMatrix * vec4(iv_Vertex, 1.0);
vVertCoord = (gl_Position.xy/gl_Position.w) * (0.5) + vec2(0.5);
}
Zasadniczo obliczam znormalizowane współrzędne urządzenia (NDC) z odległości między klipami e pozycję z podziałem perspektywicznym, a następnie zmapuj NDC (w zakresie od [-1,1]) do przedziału [0,1]. Działa to doskonale na quadach pełnoekranowych (nawet bez podziału perspektywy, ponieważ współrzędne są tak proste). Arbitralna geometria, którą muszę narysować jako geometrię światła w moim odroczonym rendererze, ma jednak pewne problemy. W wyjściu I vertex shader vVertCoord
jako kolor na czerwony = x i zielony = Y:
#version 150
noperspective in vec2 vVertCoord;
out vec4 colorOut;
void main(void)
{
colorOut = vec4(vVertCoord.x, vVertCoord.y, 0, 1);
}
Wynika to gdy jestem w środku punktu światła sfery, wszystko wygląda w porządku (czarne linie są renderowane na cel):
jednak gdybym zbliżyć się do światła geometrii jest to wynik:
Co to jest ta czerwona plama w lewym górnym rogu? Nie chcesz widzieć rezultatów w kolorze rzeczywistym z wyłączonymi kolorami debugowania, ponieważ wygląda na to, że lsd-trip, wszystko kręci się wokół, gdy poruszasz aparatem. Czy ta precyzja jest powiązana? Zauważ, że wszystko jest w porządku, gdy używam gl_FragCoord w pixel shader.
Czy istnieje jakiś szczególny powód, dla którego współrzędne tekstury są oparte na gl_FragCoord, a nie na zwykłym atrybucie interpolowanym? W pierwszym przykładzie, który już wyeliminowałby potrzebę podziału. p.s. zamiast vScreenSize możesz mieć odwrotność rozmiaru ekranu (zmieniając podział na mnożenie). –
Prawdopodobnie nie chcesz tego drugiego, co wyeliminuje możliwość wykonania filtrowania tekstur. Choć może się wydawać, że tak naprawdę nie dbasz o to, w odroczonym mechanizmie cieniowania może być przydatne generowanie G-bufora i cieniowanie w różnych rozdzielczościach (szczególnie w przypadku sprzętu niższego rzędu, który jest zwykle dość ograniczony). –