(Modifica: ho provato un campione che dipingeva semplicemente un triangolo senza texture o shader e solo OpenGL-ES 1.1 sul mio dispositivo e poteva vedere gli stessi artefatti. Ho provato lo stesso campione nell'emulatore e non c'erano artefatti lì potrebbe essere un problema di Tegra 2 o devo impostare uno stato specifico o qualcosa che non è necessario nell'emulatore?)Perché i colori dei pixel non sono corretti in OpenGL ES 2.0 su Android?
Sto riproducendo un quadrato corretto di pixel sullo schermo ma quando creo uno screengrab e guarda il pixel poi alcuni di loro sono leggermente fuori come antializzati o filtrati o qualcosa del genere. Lo vedi solo quando lo zoom su di loro, ma non è questo il punto. Voglio fare un po 'di matematica nel pixel shader e se i pixel sono leggermente spenti e questo non mi va bene. Ho bisogno di loro esattamente come nella bitmap in cui li ho inseriti.
Ecco uno screengrab ingrandito del problema. Intorno alla linea bianca i valori scuri sono leggermente più brillante di quello che dovrebbe essere:
Ho già provato:
GLES20.glDisable(GLES20.GL_DITHER);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
, ma non ha avuto alcun effetto. I pixel sono leggermente fuori. È facile da vedere tra pixel scuri e bianchi, perché il pixel scuro accanto ad esso è leggermente più luminoso e anche i valori r, g, b con un programma di pittura mi mostrano questo.
Qualcuno potrebbe aiutarmi con questo?
qualche informazione in più: CPU
mio dispositivo è un Tegra 2.0. Rendo esattamente un quadrato 256x256 in 256x256 pixel (l'ho verificato prendendo uno schermo con DDMS eclipse). La trasparenza è disattivata e la bitmap ha un valore alfa di 255 per ciascun pixel. Ho creato la superficie come una superficie 32bit con alfa con:
glSurface.setEGLConfigChooser(8, 8, 8, 8, 0, 0);
ho semplificato il codice, ma comunque possibile verificare il problema quando mi rendono con seguenti shaders:
String vshaderquad = "attribute vec4 a_pos; \n" + // in position
"attribute vec2 a_tex; \n" + // in Texture coordinates
"varying vec2 vtex; \n" + // out Texture coordinates
"void main(void) { \n" +
" gl_Position = vec4(a_pos); \n" +
" vtex = a_tex; \n" +
"}";
String fshaderquad = "precision mediump float; \n" +
"varying vec2 vtex; \n" +
"uniform sampler2D samp0; \n" +
"void main() { \n" +
" gl_FragColor = texture2D(samp0, vtex); \n" +
"}";
e comandi:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mapid[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glUniform1i(handlesampler0, 0);
GLES20.glDisable(GLES20.GL_DITHER);
GLES20.glViewport(0, 0, screenx, screeny);
float screenx = (float)ddimx;
float screeny = (float)ddimy;
//
vdata.put(0*4+0, 0.0f * (2.0f/screenx));
vdata.put(0*4+1, 256.0f * (2.0f/screeny));
vdata.put(0*4+2, 0.0f * (1.0f/256f));
vdata.put(0*4+3, 256.0f * (1.0f/256f));
//
vdata.put(1*4+0, 0.0f * (2.0f/screenx));
vdata.put(1*4+1, 0.0f * (2.0f/screeny));
vdata.put(1*4+2, 0.0f * (1.0f/256f));
vdata.put(1*4+3, 0.0f * (1.0f/256f));
//
vdata.put(2*4+0, 256.0f * (2.0f/screenx));
vdata.put(2*4+1, 256.0f * (2.0f/screeny));
vdata.put(2*4+2, 256.0f * (1.0f/256f));
vdata.put(2*4+3, 256.0f * (1.0f/256f));
//
vdata.put(3*4+0, 256.0f * (2.0f/screenx));
vdata.put(3*4+1, 0.0f * (2.0f/screeny));
vdata.put(3*4+2, 256.0f * (1.0f/256f));
vdata.put(3*4+3, 0.0f * (1.0f/256f));
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
PS: il leggero cambiamento di colore non è realmente visibile senza uno zoom estremo ma voglio fare calcoli con i valori e questo significa che devono essere precisi.
Modifica: ho aggiunto un'immagine a piena risoluzione. I colori sulle linee dovrebbero andare da (0,0,0) a (255,255,255) e sono inversi al gradiente di sfondo. Ho fatto questa immagine solo per testare l'accuratezza della trama e lì ho trovato il problema che non è proprio preciso. È necessario ingrandire anche se per distinguere le differenze è per questo che ho postato l'immagine ingrandita. Nota: le coordinate sono diverse rispetto al codice pubblicato sopra, ma il problema è lo stesso (ho provato diverse coordinate su schermo e il problema persiste).
Uno screengrab sarebbe grande per mostrare il problema, ma da quello che si scrive ho il sospetto che sia [dithering] (http://www.curious-creature.org/2010/12/08/bitmap-quality-banding-and-dithering/). È una postelaborazione, quindi non dovrebbe influenzare i pixel shader. –
Ciao, grazie per la tua risposta e ho aggiunto un'immagine per mostrare meglio il problema. Inoltre, non penso che sia solo un errore di post-elaborazione perché eseguo alcuni calcoli negli shader e i valori attesi erano spenti e puntano a questo come al problema. – HardCoder
Chiedo come dunce Android: esiste un modo in cui si utilizza un display PenTile e si leggono i colori che vengono calcolati dagli effettivi elementi di visualizzazione? – Tommy