Voksel araziyi temsil etmek için hangi veri yapısı kullanılmalıdır?


18

Vikipedi hakkındaki Wikipedia sayfasına göre , "[...] bir vokselin konumu, diğer voksellere göre konumu (yani, tek bir hacimsel görüntüyü oluşturan veri yapısındaki konumu) temel alınarak çıkarılır."

Böyle bir veri yapısı nasıl uygulanmalıdır? Bir oktree düşünüyordum ama hiç duymadığım başka bir şey olup olmadığını merak ediyorum.


1
Bu sormak biraz zor bir soru çünkü voksel verilerinizin hangi verilere ihtiyacı olacağına çok bağlı. Vokselin ne kadar dolu olduğu, neye benzediği, vb. Yaptığınız şeylere oldukça bağımlı olacak. İkincisi, veri yapısı, verilerin gerçek zamanlı manipülasyonu ve daha sonra güncellenmesi için yüksek hızlı erişime borç vermek zorundadır. Voksel başına bellek yapısının düşük tutulması ve veri hızlı erişim / manipülasyonun hızlı olması, voksel motorları ile çalışırken oldukça spesifiktir. Bir cevap değil, bir yorum.
James

Yanıtlar:


14

İlk. Her bir voksel hakkında ne bildiğimizi yazalım:

voxel = (x, y, z, color) // or some other information

Genel depolama

Genel yol basitçe şudur:

set of voxels = set of (x,y,z, color)

Bu üçlünün (x, y, z) her bir vokseli benzersiz bir şekilde tanımladığına dikkat edin, çünkü voksel uzayda bir noktadır ve iki noktanın bir yeri işgal etmesinin bir yolu yoktur (bence statik voksel verileri hakkında konuşuyoruz).

Basit veriler için iyi olmalıdır. Ancak hiçbir şekilde hızlı bir veri yapısı değildir.

İşleme AFAIK tarama hattı algoritması ile yapılır. Tom'un voksellerle ilgili Donanım makalesinde tarama çizgisi algoritması görüntüsü vardır .

Hızlı arama

Hızlı arama gerekiyorsa, arama için en hızlı veri yapısı karma'dır (aka dizi, harita ...). Bu yüzden karma yapmak zorundasınız. Yani, saf bir şekilde keyfi bir öğe elde etmenin en hızlı yolunu istiyoruz:

array [x][y][z] of (color)
  • V, x, y, z koordinatlarına göre voksel aramak için O (1) vardır.

  • Sorun, alan gereksinimlerinin O (D ^ 3) olması, burada D her x, y ve z sayısının aralığıdır (Gerçek sayıyı unutun, çünkü 256 değer aralığına sahip Chars olsaydı 256 ^ olurdu) 3 = 2 ^ 24 == 16 777 216 dizideki elemanlar).

Ancak bu, voksellerle ne yapmak istediğinize bağlıdır. Oluşturmak istediğiniz şeyse, muhtemelen istediğiniz bu dizidir. Ancak depolama sorunu hala devam ediyor ...

Depolama alanı sorunsa

Bir yöntem dizide RLE sıkıştırması kullanmaktır. Bir dilim voksel düşünün (voksellerin bir koordinat sabit değerine sahip olduğu voksel seti .... örneğin z = 13 olduğu düzlem gibi). Bu tür voksel dilim MSPaint'te basit bir çizim gibi görünecektir . Voksel modeli, söyleyebilirim, genellikle tüm olası yerlerin bir kısmını işgal eder (tüm olası voksellerin D ^ 3 alanı). "Bir çift koordinat üçlüsü almak ve kalan ekseni sıkıştırmak" hile yapacağına inanıyorum (örneğin [x] [y] almak ve her öğe için verilen x, y de tüm eksenlerde z ekseni sıkıştırmak .. 0 ila birkaç öğe olmalı, RLE burada iyi olur):

array [x][y] of RLE compressed z "lines" of voxel; each uncompressed voxel has color 

Depolama sorununu çözmek için diğer yöntem, ağaç veri yapısını kullanarak dizi yerine:

tree data structure  = recursively classified voxels
for octrees: recursively classified by which octant does voxel at (x,y,z) belong to
  • Octree, Nick'in belirttiği gibi. Vokselleri sıkıştırmalıdır. Octree arama için iyi bir hıza sahip, sanırım N'nin voksel sayısı olduğu bazı O (log N).
  • Octree düzgün rasgele voksel verilerini depolayabilmelidir.

Eğer vokseller basit bir yükseklik haritasıysa, sadece bunu saklayabilirsiniz. Veya parametreyi, yükseklik haritasını oluşturan, yani yordamsal olarak üreten işleve depolayabilirsiniz ...

Ve elbette tüm olası yaklaşımları birleştirebilirsiniz. Ancak kodunuzun çalışıp çalışmadığını test edip GERÇEKTEN daha hızlı olduğunu (yani optimizasyona değdiğini) ölçmedikçe aşırıya kaçmayın.

TL; DR

Octrees dışında voxels, google "voxlap", "ken silverman" ile RLE sıkıştırma ...

kaynaklar

Kaynakların listesi ve hızlı voksel oluşturucunun nasıl yapılacağı hakkında tartışmalar, kağıtlar ve kaynak kodu içerir .


1
"Depolama sorunu varsa": ayrıca VTC ( oss.sgi.com/projects/ogl-sample/registry/NV/… ) veya DXT sıkıştırmasını kullanabilirsiniz
KindDragon

@KindDragon bu bilgi için teşekkür ederim. :) Bu çok iyi bir fikir.
user712092

Kaynak bağlantısı kapalı.
Ezequiel

4

Bahsettikleri iki farklı veri yapısı yönü vardır.

Dizi yapıları

Herhangi bir sayıda boyuttan oluşan bir dizinin bir öğesine başvurduğunuzda, dizinin kendisini geçtikten sonra dizinin kendisinin, myArray[4][6][15]o konumda ne olduğunu bildiğini düşünün . Bu konumda bulunan bir voksel ise, bu vokselin ayrıca kendi x, y ve z koordinatlarını kaydetmesi gerekmez - vokselin bulunduğu dizi, dizine endeksli konumuna bağlı olarak dünya konumunu belirtir.

Bunun iyi olmasının nedeni, bu tür dizi erişimi için kullanılan işaretçi aritmetiğinin doğası gereği hızlı ve genel olarak konuşması, diller arasında bulunan hızlı (genellikle "yerel" olarak adlandırılır) dizilerin çoğunun temelini oluşturmasıdır. Bu dizilerin dezavantajı, bahsedilen işaretçi aritmetiğinin geçerli olması için bayt cinsinden eşit boyutta elemanlara sahip olmalarıdır.

Octrees

(Bu ikinciyi not ediyorum, çünkü wikipedia'nın bahsettiği şey daha az olasıdır ve voksel uygulamaları oktrees kullanımını gerektirmez, ancak neredeyse tüm modern olanlar octrees kullanır.)

Bir oktree'nin kök düğümü tek, bölünmemiş bir küp. Bir örnek verelim. Diyelim ki oktree'nizin kökü, küpün en merkezi, {0, 0, 0}3B alanda. Nesneleri bu boşluğun içine yerleştirmeye başladığınızda (okuma: birden fazla nesne), oktree'yi daha fazla alt bölümlere ayırmanın zamanı gelmiştir. Bu, 3 düzlem kullanarak dilimleyerek 8'e ( okt- ) bölündüğünüz yerdir , bu düzlemler xy, xz ve yz düzlemleridir. Orijinal küpünüz artık tam olarak 8 küçük küp içeriyor. Bu alt düğümlerin her biri merkezi ana küpün ofseti olarak konumlandırılır . Yani, örneğin, pozitif xyz oktantta yatan küpün, ana / içeren küpün merkezinden tam olarak bir ofseti olacaktır.{root.width / 4, root.height / 4, root.depth / 4}. Her bir alt düğüm için mutlak bir konum belirtmek yerine, ana düğümü çocuk alanının kaynağı olarak kabul etmek daha mantıklıdır. Sahne grafikleri de aynı şekilde çalışır.

Bunu bir kare çizdiğiniz ve 4 eşit bölgeye böldüğünüz bir 2B çizimde görmek yeterince basittir. Oktree kök düğümümüz gibi, ana karenin merkezi olarak kabul {0, 0}edilirse, çocuk karelerinin 4 merkezi

{root.width / 4, root.height / 4}, {-root.width / 4, root.height / 4}, {root.width / 4, -root.height / 4}, {-root.width / 4, -root.height / 4}

... Ebeveynlerine göre - 3D'de olduğu gibi aynı prensip.


Cevabınız için teşekkür ederim. Benim durumumda, arazinin bazı büyük bölümleri aynı tür vokselden yapılırdı, bu yüzden octrees'i düşünüyordum (büyük bir parça alt bölümlere ayrılmak zorunda kalmayacaktı). Bununla birlikte, uygulanması daha basit göründüğü için 3D diziye bir şans vereceğim. Eminim arazi sınıfımın uygulama detaylarını yeterince soyutlamayı başarabildim, böylece ihtiyaç duyulacak uygulamaları değiştirmek o kadar zor değil.
pwny

Rica ederim. Kesinlikle octrees bakarak öneririz, gerçekten kavramak zor değil. Ama evet, yaklaşımınız şimdilik mantıklı, kesinlikle bir 3D dizi kullanarak ilk prototipleme yapmaya değer.
Mühendis

Daha fazla okuma olarak, Intel'in Oyunlar için STL'yi Genişletme makalesinde birkaç yararlı referans da dahil olmak üzere octrees uygulamasının iyi bir tartışması bulunabilir .
Martin Foot

1

RLE kullanabilirsiniz. Ancak SVO (Sparse Voxel Octree) kullanabilirsiniz, id Tech 6 SVO kullanır. SVO, bir oktree veri sunumuna bir yeniden yayınlama veya bazen bir ışın izleme yaklaşımı kullanan bir 3D bilgisayar grafik oluşturma tekniğidir.

Teknik biraz değişir, ancak genellikle ekranın çözünürlüğü ve boyutu göz önüne alındığında görünür veya görülebilen noktaların (seyrek vokseller) gövdesini üretmeye ve işlemeye dayanır.

Daha hızlı olduğu için yeniden yayınlama kullanın.


0

Genellikle arazi için 3B veri yapısından kaçınabilirsiniz. Bunun yerine bir yükseklik haritası kullanabilirsiniz . Bu, çalışma zamanında çok ucuz ve verimli bir şekilde vokselleştirilebilir. Genellikle her bir sütunda oluşturmanız gereken minimum yüksekliği ve bazen başlangıç-bitiş-üst açılarını izlemek için (deneyimime göre) ödeme yapar, böylece arka yüz sütunlarını da çıkarabilirsiniz.

İşte uzun zaman önce yaptığım: http://sites.google.com/site/williamedwardscoder/spinning-voxels-in-flash

Arazinizde az sayıda çıkıntı veya mağara veya bir yükseklik haritasının gösteremediği diğer özellikler varsa, yükseklik haritanızda delikler olabilir ve alternatif bir temsiliniz olabilir, örneğin yalnızca çalışma zamanının harcandığı yerelleştirilmiş yerleri dolduran gerçek 3D voksel nesneleri garantilidir.

Geniş gerçek voksel dünyalarınız olduğunda seyrek voksel gösterimleri buna değer. John Carmack son birkaç yıldır onları konuşuyor ...


Boy haritalarını da düşündüm ama birkaç şey beni onlardan uzaklaştırdı. Mesele şu ki, benim durumumda, arazi hiçbir şekilde gerçekten büyük değil veya çok karmaşık (labirent tipi bir arazi düşünün, çok kartezyen). Ayrıca, arazinin bir kısmının yıkılabilir olmasını veya kullanıcının araziyi inşaat yoluyla etkilemesine izin vermesini istiyorum. Bu, oyuncunun arazide bir yükseklik haritası ile temsil edilmesi daha karmaşık görünen "tüneller" oluşturmasına neden olabilir.
pwny
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.