Ho un motore di gioco 2D che disegna tessere disegnando tessere da un'immagine di tessera. Perché per impostazione predefinita OpenGL può solo avvolgere l'intera trama ( GL_REPEAT
) e non solo una parte di essa, ogni riquadro è suddiviso in una trama separata. Quindi le regioni della stessa tessera vengono rese adiacenti l'una all'altra. Ecco come appare quando funziona come previsto:
Tuttavia, non appena si introduce il ridimensionamento frazionario, appaiono le cuciture:
Perché succede? Ho pensato che fosse dovuto al filtro lineare che fonde i bordi dei quad, ma succede ancora con il filtro punti. L'unica soluzione che ho trovato finora è garantire che tutto il posizionamento e il ridimensionamento avvengano solo a valori interi e utilizzare il filtro punti. Ciò può degradare la qualità visiva del gioco (in particolare il posizionamento dei pixel secondari non funziona più, quindi il movimento non è così fluido).
Cose che ho provato / considerato:
- l'antialiasing riduce, ma non elimina del tutto, le cuciture
- la disattivazione del mipmapping non ha alcun effetto
- renderizzare ciascuna piastrella singolarmente ed estrudere i bordi di 1px - ma questa è una de-ottimizzazione, poiché non può più eseguire il rendering di regioni di tessere in una volta sola e crea altri artefatti lungo i bordi di aree di trasparenza
- aggiungi un bordo 1px attorno alle immagini sorgente e ripeti gli ultimi pixel, ma non sono più power-of-two, causando problemi di compatibilità con i sistemi senza supporto NPOT
- scrivere uno shader personalizzato per gestire le immagini piastrellate, ma cosa faresti in modo diverso?
GL_REPEAT
dovrebbe afferrare il pixel dal lato opposto dell'immagine ai bordi e non scegliere la trasparenza. - la geometria è esattamente adiacente, non ci sono errori di arrotondamento in virgola mobile.
- se lo shader di frammenti è codificato per restituire lo stesso colore, le cuciture scompaiono .
- se le trame sono impostate su
GL_CLAMP
invece diGL_REPEAT
, le cuciture scompaiono (sebbene il rendering sia errato). - se le trame sono impostate su
GL_MIRRORED_REPEAT
, le cuciture scompaiono (anche se il rendering è di nuovo sbagliato). - se rendo rosso lo sfondo, le cuciture sono ancora bianche. Ciò suggerisce che sta campionando il bianco opaco da qualche parte piuttosto che la trasparenza.
Quindi le cuciture appaiono solo quando GL_REPEAT
è impostato. Per qualche motivo solo in questa modalità, ai bordi della geometria c'è un po 'di spurgo / perdita / trasparenza. Come può essere? L'intera trama è opaca.
GL_NEAREST
campionamento nella R
direzione delle coordinate funzionano allo stesso modo delle trame array per la maggior parte delle cose in questo scenario. Il mipmapping non funzionerà, ma a giudicare dalla tua applicazione probabilmente non avrai bisogno di mipmap.