Perché le trame sono sempre potenze quadrate di due? E se non lo fossero?


53

Perché la risoluzione delle trame nei giochi è sempre una potenza di due (128x128, 256x256, 512x512, 1024x1024, ecc.)? Non sarebbe intelligente risparmiare sulla dimensione del file del gioco e rendere la trama perfettamente adatta al modello da scartare UV?

Cosa accadrebbe se ci fosse una trama che non era una potenza di due?

Sarebbe errato avere una trama simile a 256x512 o 512x1024? O ciò provocherebbe i problemi che potrebbero causare trame senza potenza di due?


9
I tuoi altri esempi sono anche poteri di due, ma non lo stesso potere di due. I poteri di due rendono la trama ottimizzata per l'hardware grafico.
MichaelHouse

1
@ Byte56 Penso che significhi 2 ^ nx 2 ^ n trama, dove n varia da 1 a infinito. (Non proprio infinito.)
Robin,

Si noti inoltre che i poteri di due hanno il vantaggio di rendere banali le mipmap.
Pubblico

Poiché la trama normalmente si avvolge (sebbene sia possibile sceglierla in uno shader personalizzato) non è necessario sprecare spazio, è sufficiente avvolgere i poligoni con le coordinate uv attorno ai bordi e è possibile utilizzare lo spazio disponibile molto più facilmente. Se non hai una necessità urgente, è più sicuro attenersi alle trame width = height = 2 ^ n perché consentirà una gamma più ampia di hardware al costo di un layout uv leggermente più complicato.
Daniel Carlsson,

Non sono sempre poteri di due.
Almo,

Risposte:


49

Perché la risoluzione delle trame nei giochi è sempre una potenza di due (128x128, 256x256, 512x512, 1024x1024, ecc.)?

Come sottintende Byte56, le restrizioni dimensionali del "potere di due" sono (erano) che ogni dimensione deve essere, indipendentemente, una potenza di due, non che le trame debbano essere quadrate e avere dimensioni che sono una potenza di due.

Tuttavia, sulle schede moderne e sulle API grafiche moderne, questa "restrizione" è stata notevolmente ridotta in modo tale che le dimensioni delle trame possano essere, entro limiti ragionevoli, praticamente qualsiasi cosa ti piaccia. Però:

Non sarebbe intelligente risparmiare sulla dimensione del file del gioco e rendere la trama esattamente adatta al modello da scartare UV? Cosa accadrebbe se ci fosse una trama che non era una potenza di due?

Assicurando che le dimensioni della trama abbiano una potenza di due, la pipeline grafica può trarre vantaggio dalle ottimizzazioni legate all'efficienza nel lavorare con potenze di due. Ad esempio, può essere (e assolutamente diversi anni fa prima che avessimo GPU dedicate e compilatori di ottimizzazione estremamente intelligenti) più veloci da dividere e moltiplicare per potenze di due. Lavorare al potere di due operazioni anche semplificate all'interno della pipeline, come il calcolo e l'uso di mipmap (un numero che è una potenza di due si dividerà sempre equamente a metà, il che significa che non devi affrontare scenari in cui devi arrotondare le dimensioni della mipmap verso l'alto o verso il basso).

È vero che "sprechi" un po 'di spazio in questo modo, ma lo spazio extra di solito vale la pena per il compromesso delle prestazioni di rendering. Inoltre ci sono tecniche, come la compressione o l'imballaggio di più immagini in un unico spazio di trama che può alleviare alcuni dei rifiuti di archiviazione.


11
"È vero che" sprechi "un po 'di spazio in questo modo, ma lo spazio extra di solito vale la pena per il compromesso delle prestazioni di rendering." - Circa dieci anni fa ho lavorato in uno studio che stava trasferendo un gioco PS2 su XBox. Sebbene la PS2 non supporti tecnicamente trame senza potenza di due, in alcuni casi puoi in qualche modo forzarlo a farlo con una piccola manipolazione intelligente e nessuna perdita di velocità. L'XBox, d'altra parte, non li supportava completamente . Il risultato finale è che nonostante l'XBox abbia quasi il doppio della RAM della PS2, abbiamo dovuto sottocampionare alcune delle trame per adattarci.
ZorbaTHut

Sto facendo fatica a trovare una citazione, ma ho letto in precedenza che le immagini JPEG dovrebbero essere a multipli di 8 per la massima efficienza, poiché qualsiasi cosa al di fuori di questo richiede ancora un blocco 8x8.
salmonmoose,

1
@salmonmoose: Corretto; JPEG comprime ogni blocco di 8x8 in modo indipendente e bloccherà i blocchi sul bordo. Ma questo non è correlato a questa domanda.
Salterio il

1
I file JPEG sono codificati in blocchi 8x8, sì. Tuttavia, questa non è davvero una considerazione dell'efficienza. E non è necessariamente nemmeno una potenza di 2. :)
Kylotan,

Un esempio è su Android, dove spesso due trame non poweroft producono trame bianche.
user717572

17

Perché le trame sono sempre potenze quadrate di due?

Le trame non sono sempre quadrate né sono sempre poteri di due . Il motivo per cui tendono ad essere poteri di due è di solito per aumentare la compatibilità con le schede video più vecchie che hanno imposto tale restrizione. Per quanto riguarda le trame non quadrate, di solito non è un problema. Riassumere:

  • Le trame in genere non devono essere quadrate , anche se DirectX ha una D3DPTEXTURECAPS_SQUAREONLYcapacità, ma ho lavorato con trame non quadrate anche in hardware meno recente senza problemi.
  • Le trame dovrebbero essere potenze di due perché molte carte grafiche più vecchie lo richiedono ancora. Il motivo di tale restrizione era che potevano eseguire alcune ottimizzazioni alle operazioni di mappatura delle trame. La maggior parte delle schede grafiche moderne non ha questa limitazione.

12
Va notato che per "vecchie carte grafiche" si intende roba prodotta prima del 2006 o giù di lì.
Nicol Bolas,

1
@NicolBolas Grazie, stavo davvero cercando di trovare dei riferimenti su quel punto.
David Gouveia,

7

Si riferisce alle ottimizzazioni della scheda grafica. Sono stati progettati per elaborarli in quel modo. La maggior parte delle carte in questi giorni ti permetterà di caricare trame con dimensioni che non sono potenze di due, ma probabilmente avrà un impatto negativo sulle prestazioni. Vi è una buona probabilità che quando viene caricato verrà effettivamente convertito, cosicché si carica tempo e non si risparmia memoria. Le trame non quadrate sono generalmente OK, purché entrambe le loro dimensioni siano potenze di due.

Un modo per gestire trame di dimensioni dispari è usare un Atlante delle trame . Fondamentalmente, metti insieme più trame in una singola trama e usi le coordinate della trama dei tuoi vertici per fare riferimento alla particolare immagine di cui hai bisogno. Ciò comporta anche ulteriori vantaggi in termini di prestazioni, poiché consente di evitare cambiamenti di stato. Un uso comune di questo è l'inserimento di tutti gli elementi dell'interfaccia in una singola trama, il che significa che se hai raggruppato i vertici delle tue interfacce in un singolo oggetto buffer, puoi disegnare il tutto con una sola chiamata, piuttosto che cambiare trama molte volte e effettuando un call call separato per ognuno.


6

Il problema è che alcuni hardware hanno un supporto limitato per le trame che non hanno una potenza di due dimensioni.

Ad esempio, guarda la parte inferiore di http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876%28v=vs.85%29.aspx e leggi le note 3 e 4 lì.

3 Ai livelli di funzionalità 9_1, 9_2 e 9_3, il dispositivo di visualizzazione supporta l'uso di trame 2D con dimensioni che non sono potenze di due in due condizioni. Innanzitutto, è possibile creare un solo livello di mappa MIP per ciascuna trama e, in secondo luogo, non sono consentite le modalità di campionamento a capo per le trame (ovvero, i membri AddressU, AddressV e AddressW dei membri D3D11_SAMPLER_DESC non possono essere impostati su D3D11_TEXTURE_ADDRESS_WRAP).

4 Ai livelli di funzionalità 10_0, 10_1 e 11_0, il dispositivo di visualizzazione supporta incondizionatamente l'uso di trame 2D con dimensioni che non sono potenze di due.


6

L'hardware grafico è ottimizzato per operazioni a matrice, operazioni su frammenti e operazioni vettoriali. In poche parole, le matrici quadrate sono più facili da gestire, poiché i calcoli possono essere eseguiti in blocchi (chiamati frammenti), l'hardware è ottimizzato per le operazioni a blocchi, motivo per cui ci sono cose come i buffer di file, la memoria RAM non si carica su disco fino a un blocco è stato popolato. Lo stesso vale per la memoria grafica.

Il frame buffer è composto da frammenti quadrati. Ad esempio in uno schermo con una risoluzione 800x600 e uno spazio colore RGB (0-255) ci sono 800x600 punti con 3 byte per canale, un totale complessivo di 3x800x600 = 1.440.000 byte da indirizzare nel frame buffer. Ciò significa che ci sono 1.875 frammenti indirizzabili che sono 256x256x3 byte. Poiché i dati di trama sono quadrati, è molto più semplice mappare dalla matrice GRAM alla matrice del buffer dello schermo usando il ridimensionamento bicubico, dove come se non fosse quadrata la distorsione per il lato più lungo richiederebbe più tempo per calcolare quando è necessario essere ridimensionato.

Molte API grafiche accetteranno dati di trama non quadrati, poiché accettano le coordinate di mappatura UV come dati a virgola mobile, tuttavia una volta inviato alla GPU, il riempimento viene aggiunto ai dati di trama, poiché le proporzioni effettive dell'immagine non cambiano la mappatura appare inalterato, tuttavia il riempimento viene aggiunto ai dati della trama, perché alla GPU piace considerarlo come un quadrato perfetto.

Quindi, se viene utilizzata un'immagine 100x1024 e viene utilizzata un'immagine 1024x1024, il che significa che 946.176 byte vengono sprecati. Ancor di più se si deve eseguire la composizione, poiché sarà necessario aggiungere un canale alfa per indicare che i dati di riempimento non devono influenzare la trama composta.


Questa è una spiegazione interessante (titbit sulle matrici quadrate) che non si trova nel solito potere di 2 risposte (+1) - potresti fornire alcune citazioni se possibile?
Samaursa,

1

Il nostro mondo digitale funziona con la numerazione binaria, quindi per moltiplicare o dividere per 2 un valore puoi "spostare" un valore a sinistra o a destra, ad es.

<<  Left shift      x = 5 << 1    0101 << 1     1010     10
>>  Right shift     x = 5 >> 1    0101 >> 1     0010      2

Lavorare con valori "potenza di due" è più facile per una CPU.


0

L'hardware moderno può (finalmente) far fronte all'abilitazione delle modalità di avvolgimento su non-power di due trame basate, tuttavia la non-power di due trame tende ancora a sprecare la memoria GPU poiché tende ad essere imbottita lungo la larghezza di una certa quantità hardware specifica (o di alcune dimensioni della piastrella o arrotondato alla potenza successiva di due dimensioni che contiene la trama).

Poiché questo dipende dall'hardware e i fornitori generalmente non entrano nei dettagli di questi dettagli, la cosa più sicura da fare è continuare a utilizzare la potenza di due dimensioni per le trame, in modo da non sprecare il ram della GPU.

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.