Ho dei problemi nel rendere un insieme di valori in un rendertarget. I valori non finiscono mai nell'intervallo esatto che desidero. Fondamentalmente uso un quad a schermo intero e un pixel shader per eseguire il rendering sulla mia texture di rendering rendertarget e quindi intendo utilizzare le coordinate della texture come base per alcuni calcoli nello shader. Le coordinate della trama del quadruplo vanno da (0,0) nell'angolo in alto a sinistra a (1,1) nell'angolo in basso a destra ... il problema è che, dopo l'interpolazione, questi valori non arrivano al pixel shader in quanto tale .
Un esempio: eseguo il rendering su una trama 4x4 e lo shader in questo caso genera semplicemente le coordinate della trama (u, v) nei canali rosso e verde:
return float4(texCoord.rg, 0, 1);
Quello che voglio uscire da esso è una trama in cui il pixel in alto a sinistra è RGB (0,0,0) e quindi nero, il pixel in alto a destra è RGB (255,0,0) e quindi un luminoso rosso e il pixel in basso a sinistra è RGB (0,255,0) - un verde brillante.
Tuttavia, invece ottengo questo qui a destra:
(rendering quad dritto, nessuna correzione)
Il pixel in alto a sinistra è nero, ma ottengo solo un rosso relativamente scuro e un verde scuro negli altri angoli. I loro valori RGB sono (191,0,0) e (0,191,0). Sospetto fortemente che abbia a che fare con le posizioni di campionamento del quad: il pixel in alto a sinistra campiona correttamente l'angolo in alto a sinistra del quad e ottiene (0,0) come coordinate UV, ma gli altri pixel d'angolo non campionano da gli altri angoli del quad. L'ho illustrato nell'immagine a sinistra con la casella blu che rappresenta il quadratino e i punti bianchi le coordinate di campionamento superiori.
Ora so dell'offset di mezzo pixel che dovresti applicare alle tue coordinate quando esegui il rendering di quad allineati sullo schermo in Direct3D9. Vediamo che tipo di risultato ottengo da questo:
(quad renderizzato con offset di mezzo pixel di DX9)
Il rosso e il verde sono diventati più luminosi ma non sono ancora corretti: 223 è il massimo che ottengo sul canale di colore rosso o verde. Ma ora non ho più nemmeno il nero puro, ma invece un grigio scuro, giallognolo con RGB (32,32,0)!
Ciò di cui ho effettivamente bisogno sarebbe questo tipo di rendering:
(rendering target, dimensione quadrupla ridotta)
Sembra che devo spostare il bordo destro e quello inferiore del mio quad esattamente di un pixel verso l'alto e verso sinistra, rispetto alla prima cifra. Quindi la colonna destra e la riga inferiore di pixel dovrebbero ottenere correttamente tutte le coordinate UV proprio dal bordo del quad:
VertexPositionTexture[] quad = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1f), new Vector2(0,0)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, 1.0f, 1f), new Vector2(1,0)),
new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};
Tuttavia, ciò non ha funzionato del tutto e ha impedito il rendering dei pixel inferiore e destro. Suppongo che i centri di questi pixel non siano più coperti dal quad e quindi non vengano elaborati dallo shader. Se cambio il calcolo di pixelSize di una piccola quantità per rendere il quad molto più grande, funziona un po '... almeno su una trama 4x4. Non funziona su trame più piccole e temo che distorca sottilmente la distribuzione uniforme dei valori uv anche su trame più grandi:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(Ho modificato il calcolo pixelSize di 0.001f - per trame più piccole, ad esempio tabelle di ricerca 1D, questo non funziona e devo aumentarlo a 0,01f o qualcosa di più grande)
Ovviamente questo è un esempio banale e potrei fare questo calcolo molto più facilmente sulla CPU senza dovermi preoccupare di mappare gli UV ai centri di pixel ... tuttavia, ci deve essere un modo per rendere effettivamente un completo, completo [0, 1] intervallo ai pixel su un rendertarget !?