Qual è il modo migliore per assaggiare le texture a schermo intero in uno shader frammento, così per esempio la g-buffer in un renderer differita, o la trama scena all'interno di uno shader post elaborazione?Il modo migliore per gustare una texture fullscreen
Al momento io uso due modi seguenti:
passare la dimensione dello schermo allo shader come uniforme e calcolare (u, v) da
gl_FragCoord
:vec2 texCoord = gl_FragCoord.xy/vScreenSize; vec3 c = texture(tex, texCoord).rgb;
non sembra essere l'ideale dato che è necessaria una divisione e fornire lo shader con le dimensioni dello schermo è ingombrante.
Converti
gl_FragCoord.xy
in univec
e utilizzaretexelFetch
:vec3 c = texelFetch(tex, ivec2(gl_FragCoord.xy), 0).rgb;
Inoltre non è l'ideale, perché è necessaria la conversione da
float
aint
.
Quindi c'è un modo migliore? Voglio solo campionare un buffer nel punto esatto in cui il mio pixel shader sta disegnando.
// EDIT:
Ok, i consigli di interpolati tessitura coordinate che provengono dal vertex sono riuscito a capire il codice seguente:
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);
}
io fondamentalmente calcolare le coordinate del dispositivo normalizzate (NDC) dal fermaglio spac e posiziona con la divisione prospettiva e poi mappa i NDC (che vanno da [-1,1]) all'intervallo [0,1]. Funziona perfettamente per quad a schermo intero (anche senza la divisione prospettiva perché le coordinate sono così semplici). La geometria arbitraria che ho bisogno di disegnare come geometria della luce nel mio renderer differito ha però alcuni problemi. In uscita I vertex shader vVertCoord
come colore per il rosso = x e verde = y:
#version 150
noperspective in vec2 vVertCoord;
out vec4 colorOut;
void main(void)
{
colorOut = vec4(vVertCoord.x, vVertCoord.y, 0, 1);
}
Questo è il risultato quando sono all'interno di un punto-luce-sfera, tutto osserva benissimo (le linee nere sono resi di proposito):
Tuttavia, se mi avvicino alla luce geometria questo è il risultato:
Che cosa sta facendo quella patch rossa nell'angolo in alto a sinistra? Non vuoi vedere i risultati in colore reale con i colori di debug disabilitati perché assomigliano a un lsd-trip, tutto si muove attorno quando muovi la telecamera. Questa precisione è correlata? Nota che tutto va bene quando uso gl_FragCoord nel pixel shader.
C'è qualche ragione particolare per cui le coordinate della trama sono basate su gl_FragCoord e non un normale attributo interpolato? Nel primo esempio si eliminerebbe già la necessità della divisione. post scriptum invece di vScreenSize puoi avere il reciproco delle dimensioni dello schermo (trasformando la divisione in una moltiplicazione) –
Probabilmente non vuoi il secondo, che eliminerà la possibilità di fare qualsiasi filtro di trama. Mentre si potrebbe pensare che non ci si preoccupi veramente di questo, in un motore di shading differito può essere utile eseguire la generazione e l'ombreggiatura di G-Buffer a risoluzioni diverse (in particolare su hardware di fascia bassa che di solito è piuttosto limitato al tasso di riempimento). –