วิธีที่เร็วที่สุดในการสร้างเอฟเฟกต์ของอนุภาคอย่างง่าย


12

ฉันกำลังมองหาวิธีที่เร็วที่สุดในการสร้างเอฟเฟกต์อนุภาคแบบง่าย ๆ ที่จะถูกสแปมเหมือนนรกในเกม ...

โดยทั่วไปเกมของฉันดูเหมือนว่าเกม vectrex ส่วนใหญ่สร้างจากเส้น ... ฉันต้องการระเบิดขนาดเล็กที่จะเป็นเรื่องธรรมดา

มีบางสิ่งที่เร็วกว่าแค่เคลื่อนที่ไปรอบ ๆ บางจุดและเรนเดอร์ด้วย GL_Point?


+1 สำหรับการอ้างอิง Vectrex ฉันใช้เวลาหลายชั่วโมงกับ Scramble และ Tempest ในฐานะเด็กในช่วงต้นยุค 80 ไม่ว่าฉันอาจจะไม่ได้ลงเอยด้วยการเป็นผู้พัฒนาเกมในวันนี้
Kylotan

อ๋อ, พายุที่น่ากลัว: D
แข่ง

ฉันจะบอกได้อย่างไรว่าไม่มีใครถูกต้อง?
speeder

คำตอบ:


13

ไม่จำเป็นต้องเก็บหน่วยความจำสำหรับทุกอนุภาคและทำให้แต่ละอนุภาคแยกกัน คุณสามารถทำได้โดยการสร้างตำแหน่งของอนุภาคระหว่างการวาดใหม่โดยใช้สมการฟิสิกส์คลาสสิก s = ut + 1 / 2.at ^ 2

ตัวอย่างง่ายๆ (ไม่มีการเร่งอนุภาคคงที่):


void drawExplosion(ExplosionParameters& s)
{
  Random rng;
  rng.seed(s.startSeed);
  glBegin(GL_POINTS);
  for (int i = 0; i < s.numParticles; i++)
  {
    vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
    float timeBias = rng.getRandom(0, s.particleTimeBias);
    vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
    glPoint3fv(&pos);
  }
  glEnd();
}

จากนั้นคุณเพียงเพิ่ม s.timeElapsed ในทุกการวนซ้ำของการวนรอบการอัปเดตของคุณ

นอกจากนี้ยังมีการตอบสนองอย่างสมบูรณ์ในการติดตั้งบน GPU ซึ่งจะทำให้ CPU ของคุณไม่ต้องทำงานใด ๆ การติดตั้ง gpu อาจมีลักษณะเช่นนี้:

void drawExplosion(ExplosionParameters& s)
{
    //bind Vertex Shader If Not Already Bound();
    ...
    // bindVertexBuffer of Zeroes If Not AlreadyBound();
    glVertexPointer(...)
    //uploadShaderUniformsForExplosion(s);
    glUniform3f(...)
    ...
    glDrawArrays(GL_POINTS, 0, s.numParticles);
} 

GPU vertex shader จะสร้างตำแหน่งอนุภาคใหม่ผ่านสมการทางฟิสิกส์และเครื่องแบบ / ค่าคงที่ที่ส่งผ่านไป - เช่นเดียวกับรุ่น CPU

หากต้องการเพิ่มความแปรปรวนบางอย่างคุณสามารถใช้การระเบิดพร้อมกันมากขึ้นด้วยพารามิเตอร์ที่แตกต่างกันเล็กน้อยเคลื่อนไหวสี / อัลฟ่าเลือกตำแหน่งเริ่มต้นต่างกัน เป็นต้น


นอกจากนี้คุณสามารถใช้ความสามารถในการคาดเดาของตัวเลขสุ่มหลอกเพื่อสร้างเวกเตอร์เริ่มต้นของอนุภาคทั้งหมดโดยสร้างอนุภาคนับร้อยจากค่าข้อมูลจำนวนน้อยของ int การใช้ GPU เพื่อสร้างควาร์ดเป็นความคิดที่ดีสำหรับอนุภาคอย่างง่าย
Skizz

เป็นเวลาหลายปีมาแล้วที่ฉันได้สร้างระบบอนุภาคแบบดั้งเดิมโดยใช้อาร์เรย์ของคลาสที่จัดการกับอนุภาคในรูปแบบกึ่งอัจฉริยะและมันดูเหมือนจะสิ้นเปลืองและป่องเสมอ วิธีนี้ดีกว่ามากสำหรับอนุภาคพื้นฐานที่ไม่ได้ทำอะไรมากไปกว่าการพ่นควันผ่านหน้าจอ
Piku

7

ฉันทำการทดสอบหลายครั้งและวิธีที่เร็วที่สุด (ไม่ใช่รหัสที่เร็วที่สุด) คืออนุภาคที่ทำจาก GL_LINE ที่รู้ตำแหน่งและความเร็วของพวกเขาและใช้สิ่งนั้นเป็นจุดในการเรนเดอร์ (ดังนั้นยิ่งอนุภาคเร็วขึ้น มันจะกลายเป็นช้ากว่ามันจะกลายเป็นจุด)

เอฟเฟกต์นั้นยอดเยี่ยมมาก ๆ (ดูวิดีโอรูปทรงเรขาคณิตของสงครามเพื่อดู) และเร็วมากเช่นกัน เตะอึออกจากล่าม (โดยเฉพาะเพราะล่ามจะทำให้ฉันต้องคำนวณยอดจุดยอดสองเท่า)

นอกจากนี้มันยังดีกว่าการใช้ระบบอนุภาคที่ทำไว้แล้วเพราะฉันต้องการผลกระทบที่เฉพาะเจาะจงและ FAST ระบบอนุภาคมักจะสนับสนุนคุณสมบัติมากมายด้วยค่าใช้จ่ายตามสัดส่วน


2
+1 สำหรับอธิบายสิ่งที่คุณทำลงไปแม้ว่าฉันอยากรู้อยากเห็นรายละเอียดเพิ่มเติมเกี่ยวกับการทดสอบของคุณ =)
โน้มเอียง

Btw: ทั้งหมดนั้นอยู่ในโหมดทันที (นั่นเป็นเพียงสิ่งเดียวที่ฉันรู้วิธีการเขียนโค้ดและฉันเรียนรู้ชื่อเมื่อวานนี้ ... )
speeder

6

โดยปกติฉันคิดว่าคุณจะทำอนุภาคเป็นคณะสี่คน ปฏิบัติต่อพวกมันเหมือนสไปรต์ 2D โดยทั่วไปแล้วจางหายไปตามกาลเวลาทำลายมันเมื่อมองไม่เห็น ยังดีกว่าใช้ซ้ำเก่าเมื่อคุณสร้างใหม่เพื่อให้คุณไม่หวดหน่วยความจำสำหรับสิ่งเหล่านี้

หากคุณใช้อัลฟ่าแบบไม่ จำกัด เวลากับงานศิลปะคุณสามารถรองรับไฟไฟควันและสิ่งอื่น ๆ ได้อย่างง่ายดายด้วยการผสมแบบเดียว


ฮัม ... คะแนนไม่เร็วกว่าพื้นผิวเหรอ?
speeder

2
ฮาร์ดแวร์กราฟิกได้รับการปรับแต่งเป็นพิเศษสำหรับการปรับแต่งพื้นผิวให้กับเฟรมเฟรม หากคะแนนเร็วกว่าอาจเป็นไปได้ว่ามีจำนวนเล็กน้อยและคุณสูญเสียความเป็นไปได้ทั้งหมดที่คุณได้รับจากการทำพื้นผิว
Kylotan

เช่นอะไร? ใจคุณฉันไม่ได้ทำระบบอนุภาคเต็มรูปแบบมันเป็นเพียงผลกระทบเฉพาะ (การระเบิดขนาดเล็กส่วนใหญ่สำหรับข้อเสนอแนะการเล่นเกมที่คุณตีบางสิ่งบางอย่าง)
speeder

หากคุณต้องการใช้คะแนนหรือเส้นนั่นก็ไม่เป็นไร ฉันสามารถแสดงความคิดเห็นในสิ่งที่คนส่วนใหญ่ทำเพื่ออนุภาค บางทีสามเหลี่ยมที่ไม่ได้เติมจะทำให้เกิดอนุภาคที่ดี
Kylotan

4

ด้วย OpenGL ES 2.0, ES 1.X พร้อมกับส่วนขยายและ OpenGL => 2.1 คุณสามารถใช้ GL_POINT_SPRITES GL_POINT_SPRITES เปรียบเสมือนรูปสี่เหลี่ยมอยู่ด้านหน้าของกล้องเสมอ

ในเฉดสีคุณสามารถ:

  • กำหนดขนาดของสไปรต์ด้วย gl_PointSize ในเวอร์เท็กซ์เชดเดอร์
  • ใช้ gl_PointCoord (พิกัด uv) ในตัวแบ่งส่วน

คุณสามารถใช้ texture กับ alpha เพื่อวาด sprite ball ...

บทแนะนำสำหรับ Point Sprites


ฉันกำลังหลีกเลี่ยงส่วนขยายตัวโง่ ๆ ที่เอ็นจิ้น (ที่ฉันไม่ได้ทำ) ที่ใช้ไปแล้วนั้นมีความรุนแรงพอที่หลาย ๆ คนบ่นว่าเกมไม่ทำงาน ...
speeder

1

ส่วนใหญ่ระบบการผลกระทบของอนุภาคที่ผมเคยเห็นแทนการวาดภาพขนาดใหญ่จำนวนจุดวาดจำนวนที่ค่อนข้างมีขนาดเล็กของพื้นผิวที่ป้ายโฆษณาที่แต่ละพื้นผิวมีลักษณะเป็นบิตเช่นการระเบิด ถ้าหากสไตล์ศิลปะของคุณป้องกันไม่ได้จริงๆ มันจะลดปริมาณของอนุภาคที่คุณต้องการในการเคลื่อนไหวและเรนเดอร์ทีละตัวในขณะที่ยังให้เอฟเฟกต์ภาพขนาดใหญ่


1
จริง แต่เขาตั้งเป้าที่จะเป็นสไตล์ Vectrex มันจะทำงานได้ไม่ดีเท่าไหร่
Kaj

1
สิ่งที่ Kaj พูด ... มันจะไม่มีจุดหมายและจะเพิ่มขนาดการดาวน์โหลด (ฉันเปลี่ยนกราฟิกส่วนใหญ่ที่ฉันสามารถทำได้จากเทพดาเป็นเวกเตอร์ที่แท้จริงดังนั้นฉันจึงสามารถลดขนาดไฟล์ได้)
speeder

1

สำหรับวิธีเล็ก ๆ น้อย ๆ ที่เป็นระเบียบในการจัดการการวางไข่ / ลบ / อัปเดตของอนุภาคสมมติว่าคุณมีอาร์เรย์ของอนุภาคอย่างง่าย - อนุภาค [MAX_PARTICLES]:

ติดตามอนุภาคที่แอคทีฟ (เริ่มต้นด้วย NumActiveParticles = 0)

อนุภาคใหม่จะถูกเพิ่มเข้าไปในตอนท้ายของอาร์เรย์เสมอ:

pNewParticle = &Particles[NumActiveParticles++];

The clever bit - เมื่อลบอนุภาค 'Dead' - สลับกับอนุภาคที่แอคทีฟล่าสุดและลดค่า NumActiveParticles:

if ( DeadParticle < NumActiveParticles-1 )
{
  Particles[ DeadParticle ] = Particles[ NumActiveParticles-1 ];
}
NumActiveParticles--;

วิธีนี้จะช่วยหลีกเลี่ยงการค้นหา 'อนุภาคที่ไม่ได้ใช้' เมื่อวางไข่และหลีกเลี่ยงการสแกนผ่านอาร์เรย์ MAX_PARTICLES หากไม่มีการใช้งาน

โปรดทราบว่าจะใช้งานได้เฉพาะในกรณีที่คำสั่ง update / render นั้นไม่สำคัญ (เช่นในกรณีของเอฟเฟกต์ของอนุภาคจำนวนมากซึ่งใช้การผสมแบบเสริม) - เนื่องจากวิธีนี้ในการลบอนุภาคสั่งออเรย์อีกครั้ง


-1

วิธีที่เร็วที่สุดที่ฉันคิดเอาไว้คือการค้นหาเครื่องยนต์อนุภาคและใช้สิ่งนั้นเพื่อผลของคุณ นี่คือบางส่วน:

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.