2013-03-31 7 views
10

Sto disegnando pianeti in OpenGL ES e ho riscontrato alcuni problemi di prestazioni interessanti. La domanda generale è: il modo migliore per rendere trame "estremamente dettagliate" su una sfera?Dipingi un oggetto con texture ad altissima risoluzione (sfera) in OpenGL ES

(la sfera è garantito; Mi interessa ottimizzazioni specifiche sfera)

Caso base:

  • Window è circa. 2048 x 1536 (es iPad3)
  • mappa Struttura a globo è 24.000 x 12.000 pixel (un'area metà delle dimensioni USA misura l'intera larghezza dello schermo)
  • Globe viene visualizzato tutto da ingrandita (USA riempie schermo) zoom indietro (intero globo visibile)
  • Ho bisogno di un MINIMO di 3 livelli di texture (1 per la superficie del pianeta, 1 per le differenze giorno/notte, 1 per l'interfaccia utente (hilighting diverse regioni)
  • Alcuni degli strati sono animati (cioè devono caricare e rilasciare la loro trama in fase di esecuzione, rapidamente)

Limitati eccita:

  • compresse top-end sono limitati a 4096x4096 texture
  • compresse di fascia sono limitati a 8 unità texture simultanee

Problemi:

  • In totale, è ingenuamente 500 milioni di pixel di dati di texture
  • La suddivisione in trame più piccole non funziona bene perché i dispositivi hanno solo 8 unità; con solo un singolo livello di texture, potrei dividere in 8 unità di texture e tutte le trame sarebbero inferiori a 4096x4096 - ma questo consente solo un singolo strato
  • Rendering dei livelli in quanto la geometria separata funziona male perché devono essere miscelati usando frammenti- shaders

... al momento, l'unica idea che ho che suona praticabile è:

  1. dividere la sfera in NxM "pezzi di sfera" e rendere ognuno come geometria separata
  2. usa mipmap per rendere trame a bassa risoluzione quando lo zoom out
  3. ... si affidano a semplice abbattimento di tagliare fuori la maggior parte di loro utilizzando lo zoom in, e mipmapping di utilizzare piccole texture (er) quando non possono essere abbattuti

... ma sembra ci deve essere un modo più semplice/opzioni migliori?

+0

Utilizzerebbe una sfera impostore di aiuto qui: http://stackoverflow.com/questions/10488086/drawing-a-sphere-in-opengl-es/10506172#10506172? Ciò semplifica drasticamente la geometria, ma richiede una funzione di ricerca nello shader dei frammenti per mappare la trama quadrata sulla superficie sferica. Fornisce anche qualcosa che è perfettamente liscio a tutte le scale di zoom. –

+0

Non significa buttare via tutto OpenGL e scrivere una libreria di raytracing software? Dici "una sfera sembra più o meno la stessa da ogni angolazione", ma in effetti sembra diversa da OGNI angolo: questa è mappata sulla trama! – Adam

+1

Una sfera non strutturata sembra identica da qualsiasi direzione, che è ciò che ti permette di farla franca con la caduta della geometria e il calcolo di un set di normali, altezze, ecc. Per pixel. Per texturing, la rotazione della sfera in un dato frame, combinata con la posizione dei pixel, può essere inserita in una funzione di mappatura della trama per pixel nello shader del frammento. Noterai che tutto quanto sopra nella mia risposta è fatto in OpenGL ES, quindi non stai buttando via niente, a parte la generazione della tua geometria. L'ho già fatto per strutturare le sfere in questo modo e funziona bene. –

risposta

0

Sembra che non ci sia modo di montare trame così grandi in memoria della GPU mobile, anche in quella dell'iPad 3.

Quindi è necessario eseguire lo streaming dei dati di trama. La cosa che ti serve è chiamata clipmap (resa popolare dal software di identificazione con tecnologia megatexture estesa).

Si prega di leggere su questo qui, ci sono collegamenti a documenti che descrivono la tecnica: http://en.wikipedia.org/wiki/Clipmap

+0

Sembra una tecnica sbagliata, poiché richiederebbe molto più impegno e prestazioni inferiori a quelle che ho già descritto. Se mi manca qualcosa, ti preghiamo di spiegare come questo aiuta. – Adam

+0

Inoltre: rileggete la mia domanda. Il problema non è "non può contenere trame enormi in memoria". Possiamo * inserire * texture enormi in memoria - l'ho già fatto e funziona. – Adam

0

Questo non è fatto facilmente in ES, in quanto non v'è alcuna estensione trama virtuale (ancora). Fondamentalmente è necessario implementare la texturing virtuale (alcuni dispositivi ES implementano ARB_texture_array) e lo streaming nella risoluzione più bassa possibile (dipendente dalla vista) per la propria sfera. In questo modo, è possibile eseguire tutto in uno shader di frammenti, non è richiesta la suddivisione della geometria. Vedere this presentation (e la carta) per i dettagli su come questo può essere implementato.

Se si fa la matematica, è semplicemente impossibile trasmettere in streaming 1 GB (24.000 x 12.000 pixel x 4 B) in tempo reale. E sarebbe anche dispendioso, poiché l'utente non potrà mai vederlo tutto allo stesso tempo.