โดยสรุป: พืชพรรณหนาแน่นแทบไม่เคยถูกฆ่าด้วยจำนวนสามเหลี่ยมอย่างเดียว (มันตายด้วย draw call เป็นพัน overdraw จากการ์ด อัลฟาที่ประมาท และเงาที่ไม่มีใครจำได้ว่ายังเปิดอยู่ ใช้ความพยายามตามลำดับนี้: instancing ก่อน ระยะ cull ที่สอง เงาที่สาม LOD ที่สี่ การวางความหนาแน่นที่ห้า) และตรวจสอบทุกขั้นด้วยกล้องคงที่ตัวเดียวกัน ทีละตัวแปร ไม่งั้นคุณจะไม่เรียนรู้อะไรเลย คู่มือนี้ครอบคลุมแต่ละขั้นพร้อมลายเซ็นโปรไฟเลอร์ที่บอกคุณว่านี่คือปัญหาของคุณ
ป่าจริงเรนเดอร์ "ฟรี" เพราะฟิสิกส์ขนานกันมหาศาล GPU ของคุณปลอมภาพนั้นได้ที่ 60 fps แต่ต่อเมื่อคุณหยุดเอาชนะกลไกที่เอนจิน มีมาพร้อมอยู่แล้วสำหรับงานนี้พอดี
โมเดลความคิด: ห้าคอขวด หนึ่งลำดับ
ประสิทธิภาพพืชพรรณไม่ใช่ปัญหาเดียว แต่เป็นห้า และมันครอบงำตามลำดับที่คาดเดาได้ draw call มัด CPU ก่อน; ระยะ cull ตัดสินว่าคุณ ขอให้ GPU วาดมากแค่ไหนตั้งแต่ต้น; เงาแอบเพิ่มต้นทุนของทุกสิ่งที่ทอดมันเป็นสองเท่า; LOD และ overdraw ปกครองบิลต่อพิกเซล; และ การวางความหนาแน่นตัดสินว่าคุณจำเป็นต้องใช้ทั้งหมดนั้นมากเท่าไร โจมตีผิดลำดับแล้วคุณจะปรับแต่งสิ่งที่ไม่ใช่คอขวด ลำดับด้านล่าง คือลำดับที่ต้นทุนกัดจริง
instancing ก่อน อย่างอื่นทั้งหมดที่สอง
ต้นไม้หนึ่งต้นวาด 5,000 ครั้งถูกกว่าต้นไม้แยก 5,000 ต้นอย่างสุดขั้ว ทั้งสองเอนจินแบตช์เมชซ้ำเป็นการวาดแบบ instance และงานแรกของคุณคือแค่ไม่เอาชนะกลไกนั้น
Unreal แบตช์ผ่าน foliage และ hierarchical instanced static meshes; Unity ผ่าน GPU instancing และรายละเอียดภูมิประเทศ สิ่งที่ แอบทำลายการแบตช์:
- พืชพรรณที่วางเป็น แอ็กเตอร์/ออบเจกต์เฉพาะ แทนที่จะเป็น instance;
- ตัวแปรวัสดุต่อ instance ใช้ข้อมูลต่อ instance (สี สเกล) ภายในวัสดุ หนึ่ง ตัว แทนการเขียนวัสดุต่อรูปลักษณ์;
- การวางกระจายเชิงองค์กรจนเอนจิน cull กลุ่มเป็นหน่วยไม่ได้
สัญญาณโปรไฟเลอร์ชัดเจน: draw call ที่ขยายตามจำนวนต้นไม้ ถ้ามุมมองป่าแสดง draw call เป็นพัน แก้อันนี้ก่อนแตะอย่างอื่น ไม่มี อะไรที่ต่ำกว่าในรายการนี้ช่วยคุณได้ เพราะคุณ CPU-bound ก่อน GPU จะเริ่มด้วยซ้ำ พืชพรรณ instance ที่แข็งแรงคง draw call ใน หลักร้อยต่ำ สำหรับมุมมองป่าทั้งหมด ไม่ว่าจะมีต้นไม้กี่พันในนั้น
ระยะ cull คือเงินฟรี
หญ้าไม่จำเป็นต้องเรนเดอร์ที่ 800 เมตร ตั้งระยะ cull ต่อประเภท (พืชคลุมดิน 30–60 ม. พุ่ม 100–200 ม. เฉพาะต้นไม้ สมควรได้ระยะไกล) พร้อมช่วง fade เพื่อซ่อนการเด้ง
นี่คือการตั้งค่ามูลค่าต่อนาทีสูงสุดในทั้งไปป์ไลน์ และถูกทิ้งไว้ที่ "อนันต์" เป็นประจำเพราะดีฟอลต์อยู่ตรงนั้นและไม่มีใครสังเกต เหตุผลเชิงการรับรู้: พืชคลุมดินกินไม่ถึงหนึ่งพิกเซลนานก่อน 100 ม. มันไม่เพิ่มอะไรให้ภาพสุดท้ายเลยตามตัวอักษร ในขณะที่ยังกิน เวอร์เท็กซ์ overdraw และงานเงาทุกเฟรม การครอบคลุมระยะไกลเป็นของระบบที่ถูกกว่า: สีของวัสดุภูมิประเทศ อิมโพสเตอร์ทึบ หรือแค่ LOD ไกลของเลเยอร์ภูมิประเทศที่ทาสีเขียวถูกต้อง
ช่วง fade (dithered หรืออัลฟา) ซ่อนการเด้งออกเพื่อให้ผู้เล่นไม่เคยเห็นระยะ cull เอง ปรับ fade ยาวพอดีให้มองไม่เห็นและไม่ยาวกว่า fade ยาวเกินหมายความว่าคุณจ่ายสำหรับสองการแทนของพืชต้นเดียวกันระหว่างครอสเฟด
เงา: ครึ่งเงียบของบิล
ปิดการทอดเงาไดนามิกสำหรับพืชคลุมดินเล็ก เก็บไว้สำหรับต้นไม้ และจำกัดตามระยะสำหรับพุ่ม เงาหญ้าเพิ่มต้นทุนของ คุณเป็นสองเท่าเพื่อกำไรทางสายตาเกือบศูนย์
ใบหญ้าทุกใบในพาสเงาถูกวาด อีกครั้ง จากมุมมองของแสง ในฉากหนาแน่นพาสเงามักกินเท่ากับพาสฐาน (ซึ่งหมายความว่าเงาหญ้าอาจเป็น รายการเดี่ยวที่ใหญ่ที่สุดในงบพืชพรรณทั้งหมด ในขณะที่แยกไม่ออกทางสายตาจากการมืดลงของสภาพแวดล้อมง่าย ๆ ที่โคนกอ การแก้แทบฟรี: ปิดการทอดเงาสำหรับพืชคลุมดิน เปิดสำหรับต้นไม้ (เงาของมันทำงานจัดองค์ประกอบจริง) จำกัดระยะสำหรับตรงกลาง แล้วเช็คพาสเงาในโปรไฟเลอร์ ก่อนและหลัง) มักเป็นชัยชนะเดี่ยวที่ใหญ่ที่สุดหลัง instancing และใช้เวลาไม่กี่นาที
LOD: จัดงบให้เงา ไม่ใช่รูปหลายเหลี่ยม
โซ่ LOD พืชพรรณที่ดีรักษาเส้นรอบรูปและสังหารส่วนใน ตรวจสอบระยะเปลี่ยนผ่านด้วยตา และปรับแต่งหนักที่สุดที่ mesh LOD สุดท้ายก่อนอิมโพสเตอร์ เพราะนั่นคือตัวที่อยู่บนจอในทุกช็อตกว้าง
พืชชั้นพื้นแบบนี้คือที่ที่การตั้งค่าระยะ cull และเงาคุ้มที่สุด instance เป็นพัน แต่ละตัวเพิ่มแทบไม่มีอะไรเลยพ้นไม่กี่สิบเมตร แต่ละตัวเพิ่มต้นทุนเป็นสองเท่าถ้าทอดเงาไดนามิก
โซ่ใช้งานจริงสำหรับต้นไม้ฮีโร่: เมชเต็ม → ลดส่วนใน ~50% (เงาเดียวกัน) → ~15% ด้วยการ์ดรวม → อิมโพสเตอร์/บิลบอร์ดทึบ สองข้อบันทึก ที่ประหยัดความเจ็บปวดจริง:
- แม้ในเอนจินที่มีเรขาคณิตเสมือน อิมโพสเตอร์ระยะไกลยังคุ้ม เพราะ overdraw และเงา ยังเป็นต้นทุนจริงไม่ว่าสามเหลี่ยมจะจ่ายอย่างไร เรขาคณิตเสมือนแก้จำนวนสามเหลี่ยม ไม่ใช่ต้นทุนความโปร่งใส
- ความโปร่งใสคือศัตรูที่ระยะไกล การ์ด alpha-tested หนาแน่นซ้อน overdraw ตรงที่ GPU อ่อนที่สุด LOD กลาง เลือกใบเมชในระยะใกล้และ อิมโพสเตอร์ ทึบ ในระยะไกล; กลางที่หนักอัลฟาคือที่ที่เวลาเฟรมซ่อนตัว ถ้า LOD หนึ่งแพงอย่างลึกลับ เกือบเสมอคืออันที่โปร่งใส
overdraw: ต้นทุนที่คุณมองไม่เห็น
overdraw คือ GPU เชดพิกเซลเดียวกันหลายครั้งผ่านพื้นผิวโปร่งใสที่ซ้อนกัน คำสาปเฉพาะของพืชพรรณ มองไม่เห็นในภาพ สุดท้าย และมักเป็นเหตุผลที่ฉาก "เบา" ช้า
เอนจินส่วนใหญ่มีโหมดแสดงภาพ overdraw; เปิดมันแล้วมองทุ่งหญ้า ถ้ามันเรืองแสงขาว คุณกำลังเชดแต่ละพิกเซลห้าหรือสิบครั้งขณะที่การ์ด อัลฟาที่ทับซ้อนซ้อนกัน การบรรเทา: ใบน้อยกว่าและใหญ่กว่าแทนที่จะบางจำนวนมาก; เรขาคณิตทึบตรงที่เงายอมให้; และ cull การ์ดที่เพิ่ม น้อยที่สุดอย่างดุดัน overdraw คือผู้ร้ายคลาสสิกของ "ฉากช้าแต่ไม่มีอะไรดูแพง" เพราะสามเหลี่ยมถูกและพิกเซลถูกจ่ายหลายเท่า
ความหนาแน่นเป็นการตัดสินใจออกแบบ ไม่ใช่ตำแหน่งสไลเดอร์
หนาที่ผู้เล่นเดินและมอง เบาที่ไม่ แถบรายละเอียดหนา 20 ม. ตามทางอ่านออกว่า "เขียวชอุ่มทุกที่" ด้วยเศษเสี้ยวของต้นทุน สม่ำเสมอ
มาสก์ความลาดชันและความสูงทำส่วนนี้อัตโนมัติ (หน้าชันและที่ราบสูงไกลไม่ต้องการพืชคลุมดินเลย) และการจับกลุ่มทำที่เหลือ (กลุ่มมี ช่องว่างเรนเดอร์ถูกกว่าการเติมสม่ำเสมอ และ ดูธรรมชาติกว่า ดังนั้นชัยชนะประสิทธิภาพและชัยชนะความงามชี้ทางเดียวกัน ที่นี่เครื่องมือ วางตำแหน่งได้ค่าตัวคืน: ระบายความหนาแน่นด้วยมาสก์และกฎรายสปีชีส์ แล้วเบคตรงเป็น instance เนทีฟของเอนจิน คือความต่างระหว่างหนึ่ง บ่ายกับหนึ่งสัปดาห์ มันคือแก่นของสิ่งที่ scatter ของ Numivo ทำ) และเพราะมันเบคเป็น foliage ธรรมดาและเมช instance ทุกเทคนิคในบทความนี้ใช้กับผลลัพธ์ได้ไม่เปลี่ยนแปลง ไม่มี runtime ปลั๊กอินระหว่างคุณกับการปรับแต่งมาตรฐาน; ฉากที่เบคแล้วเป็นแค่ เนื้อหาเอนจิน
ลูปโปรไฟล์
กล้องเดียวกัน มุมมองเดียวกัน ทีละตัวแปร: วัดเวลาเฟรม GPU, draw call, พาสเงา และ overdraw หลังทุกการเปลี่ยน
เลือก "กล้องงบ" คงที่ในวิวหนาที่สุดของคุณ และแคปเจอร์สถิติก่อนและหลังทุกขั้นด้านบน วินัยสำคัญเพราะการปรับแต่งพืชพรรณ ปฏิสัมพันธ์: การเปลี่ยนระยะ cull เปลี่ยนจำนวน instance ที่พาสเงาเห็น; การเปลี่ยน LOD เปลี่ยน overdraw; การเปลี่ยนความหนาแน่นเปลี่ยนทั้งหมดพร้อมกัน การบินสุ่มให้ตัวเลขสุ่มและข้อโต้แย้งพิสูจน์ผิดไม่ได้ว่าการเปลี่ยนช่วยไหม กล้องคงที่ให้การตัดสินใจที่คุณปกป้องได้ เก็บตัวเลขในชีต ที่แชร์ แล้วเส้นแนวโน้มจะบอกเรื่องที่การวัดเดียวบอกไม่ได้
ตัวเลขภาคสนามที่ควรขโมย
- cull พืชคลุมดิน: 30–60 ม. · พุ่ม: 100–200 ม. · ต้นไม้: แนวสายตา
- draw call สำหรับมุมมองป่า instance ที่แข็งแรง: หลักร้อยต่ำ
- ส่วนแบ่งพาสเงาในฉากหนาแน่น: บ่อยครั้ง ~ครึ่งหนึ่ง ของต้นทุนพืชพรรณ ปิดเงาหญ้าคือชัยชนะใหญ่ที่ถูกที่สุดที่มี
- ความกว้างแถบดรสซิงตามทางที่อ่านออกว่า "เขียวชอุ่มทุกที่": ~20 ม.
- จำนวน LOD สำหรับต้นไม้ฮีโร่: 3 mesh LOD + อิมโพสเตอร์ทึบ
- เป้า overdraw สำหรับหญ้า: น้อยกว่า ~3× ในมุมมอง overdraw ไม่ใช่ 8–10× ขาวเรืองของการ์ดอัลฟาที่ซ้อนกัน
มินิ FAQ
Nanite / เรขาคณิตเสมือนทำให้อันนี้ล้าสมัยไหม? มันเปลี่ยนว่า บรรทัดไหน ครอบงำ ไม่ใช่วินัย overdraw จากการ์ดอัลฟา ต้นทุนเงา และโอเวอร์เฮดต่อ instance ยังคงอยู่ทั้งหมด และอิมโพสเตอร์ที่ระยะไกลยังคุ้ม วัดบนฮาร์ดแวร์เป้าหมายแทนที่จะสมมติว่าเทคโนโลยีใหม่ แก้คอขวดเฉพาะของคุณ มันอาจย้ายมัน ไม่ใช่ลบมัน
ทำไมฉากของฉันช้าแม้ที่ความหนาแน่นต่ำ? ผู้ต้องสงสัยประจำ ตามลำดับ: หญ้าทอดเงาไดนามิก วัสดุเฉพาะต่อตัวแปรเอาชนะการแบตช์ ระยะ cull ที่อนันต์ หรือโซ่ LOD alpha-tested ที่ซ้อน overdraw แต่ละอันมีลายเซ็นโปรไฟเลอร์ต่างกัน เช็คก่อนเปลี่ยน ไม่งั้นคุณจะแก้ผิดตัว
หนาแค่ไหนคือ "หนาเกินไป" สำหรับเกมเพลย์? ความอ่านออกในการต่อสู้จำกัดความหนาแน่นก่อนประสิทธิภาพ: ถ้าเงารูปหายเข้าไปในความรก ผู้เล่นโทษเกม ไม่ใช่ดรสซิง หนาในวิว ปานกลางในสนามคือแพตเทิร์นที่รอดทั้งโปรไฟเลอร์และการทดสอบเล่น
ควรเบคหรือคงโพรซีเดอรัล? เบคเพื่อส่งมอบ instance ที่เบคโปรไฟล์อย่างซื่อสัตย์และส่งมอบโดยไม่มีการพึ่งพา runtime เก็บการตั้งค่า โพรซีเดอรัล (มาสก์ กฎ ซีด) ไว้ในการควบคุมเวอร์ชันเพื่อให้คุณเบคใหม่หลังเปลี่ยนภูมิประเทศได้โดยไม่ต้องทำงานซ้ำด้วยมือ
ดูหนา และ เร็วไม่ใช่ความขัดแย้ง ส่วนใหญ่มันคือวินัยของการทำห้าสิ่งในลำดับที่ถูกและพิสูจน์แต่ละอย่างด้วยกล้องเดียวกัน