2010-06-28 13 views
6

. Bu kez sadece teknik bir tasarım bakış açısından.XNA - Başka bir XNA sorusu için aynı anda çok fazla partikül oluşturma

Durumum şudur: GPU hesaplamalarına dayanan bir parçacık motoru oluşturdum, tamam ama çok işe yarıyor. GPU'm 10k parçacıklarını terlemeden kolayca işleyebilir ve bir grup daha ekleyebilirsem şaşırmam.

Sorunum: Aynı anda çok fazla parçacık oluşturduğumda, kare hızım benden nefret ediyor. Niye ya? Neredeyse sadece bellek işlemlerini içerecek şekilde küçültmüş olmama rağmen bir çok CPU kullanımı.

  • yöntem parçacık oluşturmak isteyen ve bir çağrı yapar: partiküllerin

    Oluşturma hala gibi CPU aramalar ile yapılır.

  • Dört köşe şeklinde oluşturulur ve bir tamponda saklanır
  • Tampon GPU içine yerleştirilir ve zaman işlemci I yaklaşık 4 yayıcılar çerçeve başına bir parçacık oluşturmak başka şeyler

odaklanabilir alınmıştır ancak FPS düşürür (emin olun, sadece saniyede sadece 4 kare ancak 15 yayıcı FPS'imi 25'e düşürür). Bir parçacığın

Oluşturma:

 //### As you can see, not a lot of action here. ### 
     ParticleVertex []tmpVertices = ParticleQuad.Vertices(Position,Velocity,this.TimeAlive); 
     particleVertices[i] = tmpVertices[0]; 
     particleVertices[i + 1] = tmpVertices[1]; 
     particleVertices[i + 2] = tmpVertices[2]; 
     particleVertices[i + 3] = tmpVertices[3]; 
     particleVertices[i + 4] = tmpVertices[4]; 
     particleVertices[i + 5] = tmpVertices[5]; 

     particleVertexBuffer.SetData(particleVertices); 

Düşüncelerim belki çoğu zaman, belki GPU, her şeyi oluşturmak bildirmek için bir yol yoktur parçacıklar oluşturmak gerektiğini ya da belki de sadece don' Bu şeyleri nasıl yaptığını bil. ;)

Düzenleme: Sıklıkla parçacıkları oluşturmak istemediysem, bunun hala iyi görünmesi için geçici çözüm nedir?

Bu yüzden burada iyi bir parçacığın motorunun nasıl tasarlanacağını ve belki de bir yere yanlış yol aldığımı bilmene dair ümitle gönderiyorum.

cevap

4

GPU'nun her şeyi oluşturmasının bir yolu yoktur (SM4.0 gerektiren Geometry Shaders kullanımının kısa olması). Ben en fazla CPU verimliliği için bir parçacık sistemi oluşturmak olsaydı

ben Böyle bir tepe ve işaret tamponunda (sadece Örnek olması için bir sayı almak için) 100 parçacıklarını önceden yaratacak:

  • Dörtlü içeren bir köşe tamponu yapın (sahip olduğunuz altı değil, parçacık başına dört köşe)
  • "zaman ofseti" değerini ve "başlangıç ​​hızı" değerini saklayabilen özel bir köşe biçimi kullanın (XNA Particle 3D Sample)
  • Saat değerini her parçaya bölerek ayarlayın icle, sonuncusundan 1/100'ün altında bir zaman sapmasına sahiptir (yani ofsetler tampondan 1.0 ila 0.01 arasında değişir).
  • Başlangıç ​​hızını rasgele ayarlayın.
  • Her parçacık için dört noktayı kullanarak ihtiyacınız olan iki üçgeni sağlayan bir dizin arabelleği kullanın.

Ve harika olan şey sadece bunu bir kez yapmanız gerektiğidir - tüm parçacık sistemleriniz için aynı köşe tamponu ve dizin arabelleğini yeniden kullanabilirsiniz (en büyük parçacık sisteminiz için yeterince büyük olmalarını sağlar).

  • Per-Vertex:

    Sonra aşağıdaki girdi alacağını bir vertex shader olurdu

    • Zaman ofset
    • ilk hız
  • Shader Parametreler:
    • geçerli saati
    • Parçacık (etrafı sarılan aynı zamanda değer parçacık zamanı ve kullanılan tampon içinde parçacıklar bölümü) süresi
    • Parçacık sistem konum/devir/ölçek (dünya matrisi)
vb parçacık boyutu, yerçekimi, rüzgar,
  • bir zaman ölçeği (hız ve diğer fizik hesaplamaları mantıklı böylece, gerçek bir saati almak için): gibi sizin gibi
  • başka ilginç girişler, Bu köşe gölgelendiricisi (yine XNA Particle 3D Sample gibi), bir parçacık başlangıç ​​noktasının başlangıç ​​hızına ve bu parçacığın simülasyonda olduğu zamana göre konumunu belirleyebilir. Zaman ilerledikçe, partiküller (dolayı dengelemek için) sabit bir hızda çıkacak Diğer bir deyişle,

    time = (currentTime + timeOffset) % particleLifetime; 
    

    : her bir parçacık için

    süresi (sözde kod) olur. Ve bir parçacık (veya 1.0? Kayan noktalı modülde kafa karıştırıcıdır)'da zaman kaybettiğinde, parçacık tekrar animasyonu yeniden girecek şekilde time = 0.0'a geri döner.

    Daha sonra, parçacıklarımı çizmek için zaman geldiğinde, arabelleklerim, gölgelendirici ve shader parametrelerim ayarlanmış olur ve DrawIndexedPrimitives'u arayın. Şimdi zekice bir bit: startIndex ve primitiveCount'u, hiçbir parçacığın animasyonun ortasında çıkmayacağı şekilde ayarlayacağım. Parçacık sistemi ilk başladığında 1 parçacık (2 ilkel) çekerdim ve parçacık ölmek üzereyken, 100'ünü başlayacak olan tüm 100 parçacığı çizecektim.

    Ardından, bir saniye sonra, 1. partikülün zamanlayıcı döngü etrafında dönecek ve onu 101st parçacığı haline getirecektir.

    (Ben sadece sistemde 50 partikülleri isteseydim, sadece 0.5 benim parçacık ömrünü ayarlamak ve sadece hiç tepe/index tamponu içinde 100 parçacıkların ilk 50 çizerdim.)

    Ve ne zaman Parçacık sistemini kapatmak için zaman geldi - sadece aynı şeyi tersten yapın - startIndex ve primitiveCount'u, parçacıklar öldükten sonra çekilmeyi durdurun.

    Şimdi ben dahil matematik ve parçacıklar için dörtlü kullanımı hakkında bazı ayrıntılar üzerinde glossed ettik itiraf etmeliyim - ama anlamaya çok zor olmamalı. Anlamakla ilgili temel ilke, köşe/indeks tamponunuzu parçacıkların dairesel bir tamponu olarak ele almanızdır.

    Dairesel bir tamponun bir dezavantajı, partikülleri yaymayı bıraktığınız zaman, şu anki zaman partikül ömrünün bir katı olduğu zaman durmadıkça, uçların üst tarafına yerleştirilen aktif parçacıklar kümesine sahip olursunuz. ortada bir boşluk ile tampon - böylece iki çizim çağrıları (biraz daha yavaş) gerektirir. Bundan kaçınmak için durmadan önce zamanın doğru olduğunu beklemelisiniz - çoğu sistem için bu tamam olmalı, ancak bazıları için garip görünebilir (örneğin: anında durması gereken "yavaş" bir parçacık sistemi).

    bu yöntemin bir diğer dezavantajı parçacıklar sabit bir hızda serbest gerektiğidir - ki (tabii ki bu başına bir sistemdir ve hızı ayarlanabilir), genellikle tanecik sistemleri için oldukça tipik olmasına rağmen. Küçük bir düzenleme ile bir patlama etkisi (bir kerede salınan tüm parçacıklar) mümkün olmalıdır.

    Bütün bunlar söylenirse: Mümkünse, mevcut bir parçacık kütüphanesi kullanılmaya değer.

  • İlgili konular