Pürüzsüz Voksel Arazi


13

Kişisel bir proje olarak, Castle Story'nin pürüzsüz arazisine benzeyen bir arazi oluşturacak bir arazi jeneratörü yapmaya çalışıyorum.

Daha önce görmediyseniz, burada: resim açıklamasını buraya girin

Gördüğünüz gibi, blokların ve "pürüzsüz" blokların birleşimi.

Bu görünümü taklit etmek için yapmaya çalıştığım, her yüzey bloğuna mini bir yükseklik haritası vermektir. Bu genellikle işe yarar, ancak böyle bir arazi veren bazı sorunlar vardır:

resim açıklamasını buraya girin

Sorun şu ki, her blok 1x1x1, ancak bazen belirli bir konumdaki yükseklik negatif veya> 1'dir. Bu durumda, onu kırparım ve yüksekliği 0 veya 1 olarak ayarladım.

Ne demek istediğimi daha iyi açıklamak için bir şema: resim açıklamasını buraya girin

Yüksekliği oluşturmak için temelde şunu yaparım:

genColumn(int x, int z)
{
    int highestBlockY = (int)noise2d(x, z);

    bool is_surface = true;

    for(int y = max_height - 1; y >= 0; y--)
    {
        Block b;

        if(is_surface)
        {
            b = Block.Grass;
            b.HasHeightMap = true;

            // generate heightmap
            for(int ix = 0; ix < 5; ix++)
            {
                for(int iz = 0; iz < 5; iz++)
                {
                    float heightHere = noise2d(x + ix / 4, z + iz / 4) - y;

                    // clip heights
                    if(heightHere > 1)
                        heightHere = 1;

                    if(heightHere < 0)
                        heightHere = 0;

                    b.HeightMap[ix][iz] = heightHere;
                }
            }

            is_surface = false;
        }
        else
        {
            b = Block.Dirt;
        }

        setBlock(x, y, z, b);
    }
}

Belki de buna "doğru" perlin gürültü değerini kullanarak yanlış yaklaşıyorum?

Herhangi bir yardım büyük mutluluk duyacağız!

Yanıtlar:


11

Kale Hikayesi teknik kısıtlamalar nedeniyle şöyle görünür: Her yüzey vokseli için bir yükseklik haritası yerine, tüm hacimdeki her voksel için bir yükseklik haritası olsaydı, depolama maliyeti O sırasına göre çok daha yüksek olurdu. ), daha uygun bir O (n ^ 2) yerine engelleyici olabilen, burada n, dünyanızı temsil eden kübik bir voksel boşluğunun yan uzunluğudur. Yeraltı vokselleri için yükseklik haritası bilgilerinin ızgara yapısında örtük olduğunu unutmayın, bu nedenle yükseklik haritası bilgilerinin yalnızca yüzeyde bulunan vokseller için açık bir şekilde saklanması gerekir . Kale Hikayesi adamları depolama maliyetinden ve ağ yapısının karmaşıklığından tasarruf etmek için ızgara boşluklarına köşeler diktiler ... okumaya devam edin.

Öncelikle, seçeneklerinize bakalım:

resim açıklamasını buraya girin

(1) sizin için işleri zorlaştıracaktır, çünkü tek bir voksel sütununda yalnızca en üstteki voksel için mini yükseklik haritası bilgileri istersiniz - nedenleri için ilk paragrafa geri dönün. (1) 'e bakıldığında, sağdaki sütun hem en üstteki hem de yukarıdan ikinci için yükseklik haritası bilgisine sahiptir (ve eğer eğim yeterince aşırı ise, yukarıdan üçüncü ve benzerleri için geçerli olabilir.). Bu iyi değil.

(2) Muhtemelen daha iyi bir seçenektir; yani köşe köşelerinin voksel ızgara aralıklarına yapışmasını sağlamak. Peki o zaman aşırı eğim sorununu nasıl ele alacağız? Sadece dikey bir sütuna yapıştığımız bir gradyan seçmeliyiz ve böylece en üstteki voksellerden çapraz kesebileceğimizden hiçbir gradyanımız olmadığından emin olmalıyız. 45 derecelik bir eğim, aşağıda açıkladığım nedenlerden dolayı doğal kesmedir. Yani (3) yerine, (4) 'e sahiptik:

resim açıklamasını buraya girin

(4) Vokselin köşe tepe noktasını en yakın ızgara aralığına yaslamak çözümdür. Görsel efekt - çapraz kenar yumuşatma - Castle Story ekran görüntüsünde görülebilir. Vokseller için kesme eğimi 1: 1 eğim veya 45 derecedir (dikey olarak görüldüğü gibi). Çözümden geriye doğru çalışarak, nedenlerine bakalım:

  • Kesintisiz, aşırı bir eğime sahip olmamızın tek yolu, bir voksel dikey olarak uzatılmışsa ...
  • .... Ama gerçek yumuşatılmış şekli ne olursa olsun, hiçbir vokselin ağ alanı sınırlayıcı alanı aşamaz; bir vokselin, tam biçimine göre değilse, en azından eksene hizalanmış sınırlama kutusunu hesaba katan 3B ızgarada tanımlı bir alanda oturması gerekir.

Bu şekilde yaklaşmanın bir başka nedeni, daha önce keşfettiğiniz gibi, yapışma (ayrıklaştırma) kullanmamanın, en iyi şekilde kaçınılması gereken bir dizi geometrik karmaşık yüzey yumuşatma senaryosuna yol açmasıdır ... bu tür oyunlar genellikle gerektirmez uygun bir CSG algoritmasının sağlayacağı doğruluk derecesi, bu nedenle vokselleri ilk etapta kullanmamızın nedeni budur: Vokseller, kayan nokta (sürekli) çokgen kavşağı / CSG algoritmalarından daha fazla hacimlerle çalışmayı çok daha kolaylaştırır .


Sadece uygulamayı denedim ve biraz karışıklık yaşadım - "aralıklarla" ne demek istiyorsun? Entegre ızgara koordinatlarını mı kastediyorsunuz?
başlıksız

@ThomasBradworth. "Şeyler arasında müdahale eden bir alan." 2B için, anxn hücre ızgarası varsa, (n + 1) x (n + 1) aralıkları olacaktır. Bu doğrudan 3D'ye kadar uzanır. Her hücreyi bağlayan ve çoğunlukla birden fazla hücre / voksel arasında paylaşılan "köşe noktalarıdır". 1D'ye (bir çizgi) kadar kaynatırsanız, hem hücreler hem de boşluklar dizi olarak temsil edilirse, hücre 0, aralık 0 ve aralık 1 ile, hücre 1 ise aralık 1 ve aralık 2 ile sınırlanır ... vs
Mühendis

Cevap için teşekkürler! Bunu tam olarak yapmaya çalıştım, ancak bazı olumsuz sonuçlar aldım. İlk başta, kenarlardaki yükseklik değerlerini yuvarlamayı denedim (x 0 veya 4 olduğunda veya z 0 veya 4 olduğunda), ama bu beni yakaladı: i.imgur.com/eQW7Y.png ( pastebin.com/Lr8vyyHB ) Sonra, ortadaki noktaları düzeltmeyi denedim, bu yüzden bir "yükseklik ayarı işlevi" ekledim: pastebin.com/AazQ07Xm Bununla birlikte, bana daha açısal ama aynı zamanda kötü bir sonuç verdi: i.imgur.com/q1JVP .png Gürültü işlevimde bir sorun olabilir mi?
başlıksız

@ThomasBradsworth Ne yazık ki, yazmak ve düzenlemek için bir saatten fazla sürdüğüm yanıtı sadece yarı okuduğunuzu / anladığınızı düşünüyorum. Gürültüyü unutun; dahası, gürültü işlevini anlamadıysanız, şimdilik denklemden kaldırın. Sorununuz, tek tek voksel ağ verilerinin nasıl oluşturulduğuna dayanıyor ve gürültünün bununla hiçbir ilgisi yok, çünkü gürültü olmadan bir yükseklik haritası oluşturabilirsiniz. En basit test senaryosuyla çalışın, yani height dizisini sabit kodlayın. Sonra sonuçlarınızı görüntüleyin ve mesh oluşturma algoritmanızı düzenleyin. Bekleneni yapana kadar tekrarlayın. Sonra gürültüyü geri koyun ve gözden geçirin.
Mühendis

"Ara" noktaların yükseklik değerlerini değil, yalnızca köşelerin yükseklik değerlerini saklamam gerektiğini mi söylüyorsunuz?
isimsiz
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.