OpenGL - bordi bianchi su cubi


12

In un gioco in stile Minecraft che sto realizzando, ottengo bordi bianchi sui miei cubi:

inserisci qui la descrizione dell'immagine

È molto più evidente nelle trame più scure. Le trame vengono configurate in questo modo: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Qualsiasi aiuto?


3
Puoi mostrare un po 'di codice su come renderizzare ogni cubo e come posizionare i cubi?
Joncodo,

1
Avvolgere le trame fa qualcosa di diverso? Che aspetto ha la trama / dimensione a cui ti stai legando?
Chuck D,

Volevo solo sottolineare che ho visto che ciò avveniva anche in grandi atlanti a trama, che usano piccole tessere. Ad esempio, supponiamo di avere un set di tessere / atlante 1024 * 1024 e di utilizzare tessere di 32 * 32. Si ottengono errori di arrotondamento perché il punto decimale associato a tale riquadro è un doppio molto piccolo. Questo rende la precisione quasi impossibile. Una soluzione? Suddividere l'atlante delle piastrelle in singole tessere. Questo è ciò che fa Minecraft o una volta. Avevano un grosso set di tessere e in fase di esecuzione lo hanno suddiviso in singole trame.
Krythic,

Risposte:


19

Esistono due possibili cause per questo tipo di problema, a seconda del problema esatto. Elencherò entrambi:

1. Stai vedendo altri colori dalla tua trama lungo i bordi delle piastrelle.

Questo mi sembra il problema in questo caso, perché tutti i pixel dei bordi sono di tre colori che sono plausibilmente nella tua trama: bianco, nero e marrone.

Se stai usando più immagini affiancate l'una accanto all'altra in una singola trama (un atlante di trama), come immagino tu stia facendo, questo è inevitabile. Si verifica perché la GPU non combacia perfettamente con l'interpolazione lungo il bordo di un triangolo con l'interpolazione lungo la trama e si ottengono piccoli frammenti della trama adiacente.

Ci sono molte cose che puoi fare.

  • Usa una trama array invece di un atlante texture. Una trama di matrice è composta da una pila di immagini 2D della stessa dimensione e si specifica una terza coordinata per selezionarne una; è inteso esattamente come un sostituto per atlanti di trama senza il problema di filtraggio. Tuttavia, le trame di array sono una funzionalità più recente potrebbe non essere disponibile nella versione di OpenGL in uso.
  • Genera un bordo di 1 pixel in ciascuna delle tessere texture, che replica il colore del pixel regolare adiacente. (Questo è essenzialmente reimplementazione di GL CLAMP[_TO_EDGE], ma in un modo che è a conoscenza degli atlanti delle trame - il tuo uso non ha alcun effetto perché la maggior parte dei bordi delle tue tessere non sono al bordo della trama.) Questa è la soluzione che uso nella mia voce nel genere, Cubes . Non conosco particolari svantaggi se non che utilizza più memoria di trama.
  • Inserite leggermente le coordinate della trama, in modo che non vadano fino al bordo della piastrella della trama. In questo modo si otterrà una notevole magrezza dei bordi della trama rispetto ai pixel al centro.
  • Usa una singola trama per tipo di piastrella. Ciò comporta costi di cambio trama.

2. Stai vedendo degli spazi tra le tessere.

Non penso che questo sia il problema in questo caso, dal momento che non vi è alcun terreno verde visto attraverso le lacune, ma lo sto includendo per completezza.

Ciò può verificarsi quando non si forniscono esattamente le stesse coordinate per i vertici dei bordi delle riunioni delle tessere adiacenti, che di solito si verificano a causa di un errore in virgola mobile. Ad esempio, se si dispone di tessere di dimensioni 0,6 e si calcola il bordo destro della tessera x=100con (100*0.6) + 0.6, e il bordo sinistro della tessera x=101con (100*0.6), non si otterrà la stessa risposta esatta e la differenza può essere visibile come piccoli punti di lacune.

La soluzione è garantire che l'aritmetica sia coerente; alcuni modi per farlo sono:

  • Assicurati di non essere (anche indirettamente) informatico index*size + size, ma solo (index+1)*size.
  • Assicurati che l'aritmetica sia esatta; il modo più semplice per farlo è rendere esattamente la dimensione della piastrella 1,0, il che si tradurrà in un'aritmetica intera esatta anche se si eseguono i calcoli con float a 32 bit (fino a 16 milioni di blocchi dall'origine, comunque).
  • Usa numeri interi effettivi per i calcoli delle coordinate del vertice; questo ti dà ancora più portata.

Mi sembra che ci siano delle lacune - nessun sanguinamento della trama (a meno che non sia una trama piuttosto ad alta risoluzione) considerando i frammenti piccoli e nitidi.
Mario,

Grazie, l'inserimento delle coordinate della trama di un po 'sembra risolverlo.
Luis Cruz,

@Mario Presumo che ciò avvenga con l'ingrandimento PIÙ VICINO - notare il bordo nitido all'interno della piastrella. Quindi, per quella prospettiva, è una trama a risoluzione infinita.
Kevin Reid,

È inoltre possibile utilizzare un array di trame per evitare i costi di commutazione.
danijar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.