Gestione dei dati Voxel


8

Sto programmando in C ++ come hobby da circa 4 mesi e mi è davvero piaciuto creare cose usando voxel. Ho scritto un "gioco" (più che altro una sfida personale, dato che ho fatto solo il terreno, nessun gameplay) che ha reso un mondo simile a Minecraft, ma recentemente ho pensato di provare a scrivere un gioco / sfida / ecc. che utilizza un algoritmo come Marching Cubes o Dual Contouring e riduce le dimensioni del voxel. Quando ho scritto il mio progetto simile a Minecraft, ho archiviato i dati di ogni blocco in un array multidimensionale di short senza segno (dandomi così fino a 65536 tipi di blocchi diversi). Inoltre, per il rendering, ho memorizzato solo un punto (come GLubyte) e un altro GLubyte per indicare quale delle 6 facce rappresentava il punto. Ho quindi reso il viso usando uno shader di geometria.

Con il nuovo progetto a cui ho pensato, la cosa su cui non riesco a capire è come posso archiviare abbastanza dati voxel per avere voxel di circa 5 cm o 10 cm rispetto ai vecchi voxel da 1 m che avevo. Quando ho eseguito il rendering di un'area di blocchi di 704x704x704, il mio vecchio progetto utilizzava circa 670 MB di RAM. Se riducessi la dimensione del voxel a 10 cm e mantenessi la stessa distanza di rendering, sarebbero circa 649 GB di dati Voxel (ipotizzando 2 byte per voxel e un'area di 7040 ^ 3 voxel). Esiste un modo per archiviare i dati voxel in modo più efficiente che mi consenta ancora una vasta gamma di diversi tipi di voxel?

Risposte:


5

Hai bisogno di avere ogni singolo pezzo (presumendo che stai usando blocchi) in memoria contemporaneamente? Alcuni saranno occlusi - in particolare sottoterra - o dietro le montagne, ecc. Molti saranno probabilmente solo aria / vuoti e quindi potrebbero essere contrassegnati con una bandiera.

Inoltre, è possibile utilizzare un otturatore LOD o una struttura simile per provare a mantenere i dettagli attualmente visibili inversamente correlati alla distanza dall'osservatore. Come affermato da Jason, è molto più probabile che ti acquisti prestazioni, ma è un grande cambiamento strutturale da una mappa piatta.

Vedi questo articolo sulle clipmap dal mio blog preferito (ha un motore voxel simile a quello che descrivi con una dimensione voxel di ~ un decimetro).


2
Prima di tutto, sì, sto usando pezzi. In secondo luogo, il tuo suggerimento di scaricare blocchi completamente nascosti sarebbe sicuramente di grande aiuto, grazie. Appena al di sopra della mia testa, un potenziale metodo che potrei usare sarebbe quello di utilizzare una query di occlusione con il riquadro di selezione del blocco (poiché sono note tutte le dimensioni del blocco) per vedere se un blocco è visibile e caricare / scaricare un blocco a seconda del risultato. Modifica: ho appena visto la tua modifica e in realtà ho già visto quel blog. È la ragione per cui voglio sperimentare una dimensione voxel più piccola =)
Shadow

L'occlusione è molto meno importante di LOD. L'occlusione non ti procura nulla se non sei sottoterra o non guardi il fianco di una montagna. LOD da solo ti permette di renderizzare un intero pianeta. Le query di occlusione sono una cattiva idea, in quanto introducono un round trip GPU-> CPU-> GPU. Il rendering condizionale è fattibile, tuttavia, ma la CPU può probabilmente fare abbastanza da sola.

Buon punto. Ho appena dichiarato LOD secondo perché è un grande cambiamento strutturale.
ThorinII,

3

L'approccio standard per motori come VoxLap di Ken Silverman e il suo successore Ace of Spades, consiste nell'utilizzare la compressione RLE e molti altri trucchi a livello di bit per archiviare e accedere ai dati. Questo tipo di compressione 1D tende ad essere altamente efficiente e considerevolmente più facile da usare rispetto alle ocre. Credo che il motore di Silverman abbia raggiunto una risoluzione voxel di circa 10 cm al cubo. Qualcosa che oggi non si vede comunemente e che è stato realizzato su hardware molto più debole.

Credo sia anche vero che il suo approccio non ha memorizzato i colori per i voxel non esposti, che ha invece calcolato il colore per i voxel di superficie in funzione dell'altezza, o ricordando quali aree del terreno erano state fatte saltare e colorandole come "terreno fresco ". Per fare ciò, potresti usare una sorta di funzione continua come il rumore del perlin, ma potrebbe rapidamente diventare costoso per grandi aree di superficie (a meno che, forse, eseguito sulla GPU).

Gli ocre non sono male, ma sono difficili da usare nella pratica e l'allocazione efficiente nella cache è considerevolmente più impegnativa di RLE, che è facile da linearizzare a pezzi. Il seminario di Tero Karras e Samuli Laine sugli SVO indica quanto sforzo è necessario per l'implementazione octree veramente performante - e questo sta prendendo in considerazione solo il rendering, non il gameplay o le comunicazioni di rete.


0

Non so quanto sei andato lontano nel tuo progetto, ma io e un mio amico stiamo usando l' algoritmo Dual Marching Cubes , basato sulla struttura di Octree chunck e usando una doppia griglia per il rendering dei dati. Ha molti vantaggi, come la memoria molto bassa richiesta e un rendering molto veloce. Potrebbe essere un po 'complicato implementare il Level Of Detail (LOD) nei bordi dei blocchi con altri blocchi, ma se hai del tempo libero potresti scoprire come hanno fatto gli sviluppatori Ogre3D .

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.