มีสองสิ่งที่คุณสามารถทำได้เพื่อเพิ่มประสิทธิภาพการวาด
คุณบอกว่าพวกเขาค่อนข้างไกล คุณสามารถใช้LODเพื่อลดจำนวนจุดยอดของต้นไม้เหล่านั้นและลดเวลาที่ต้องใช้ในการผ่านจุดยอดทั้งหมดที่ถูกวาด แม้ว่านี่จะไม่ใช่ปัญหาในมือ (GTX1080 ที่มีต้นเพียง 10k ต้นที่มี 200 ต้นต่อต้น แต่ยังมีตัวเลขที่อ่อนแอสำหรับ GPU) ฉันยังคงรวมมันไว้ Billboarding เป็นเครื่องมือที่มีประสิทธิภาพสำหรับระดับ LOD ที่ต่ำที่สุดเนื่องจากเป็นระนาบพื้นราบที่หันหน้าเข้าหากล้องพร้อมกับภาพต้นไม้ที่อยู่ในนั้น มันเสียความรู้สึกลึกซึ่งเป็นสาเหตุที่ดีสำหรับระดับต่ำสุดเนื่องจากผู้เล่นส่วนใหญ่จะไม่สังเกตเห็นความแตกต่าง
คุณเปิดใช้งานการแบทช์แล้วหรือยัง การสร้างแบตช์แบบไดนามิกมักจะทำโดยอัตโนมัติหากยอดของตาข่ายนั้นค่อนข้างต่ำ การสร้างแบทช์แบบคงที่ยังสามารถทำได้โดยการทำให้แผนผังแบบคงที่โดยการทำเครื่องหมายที่ช่องในเครื่องมือแก้ไขความเป็นเอกภาพในเกมหลัก สิ่งนี้ไม่ทำงานกับวัตถุที่เคลื่อนไหว คุณต้องการวัตถุที่จะแบ่งปันเนื้อหาเพื่อให้งานนี้
การแบตช์แบบกำหนดเองช่วยให้คุณควบคุมการเรนเดอร์โดยสร้างชิ้นส่วนของคุณเองแทนที่จะปล่อยให้ความเป็นเอกภาพจัดการมันและมันยังเปิดใช้งานการแบตช์สำหรับตาข่ายขนาดใหญ่ นี้จะกระทำได้อย่างง่ายดายโดยMesh.CombineMeshes สิ่งนี้ยังทำงานได้ไม่ดีกับวัตถุที่เคลื่อนไหว คุณต้องการวัตถุที่จะแบ่งปันเนื้อหาเพื่อให้งานนี้ คุณอาจต้องการแบ่งโลกของคุณออกเป็นชิ้น ๆ และสร้างแบทช์จากสิ่งเหล่านั้น วิธีสร้างก้อนเหล่านั้นขึ้นอยู่กับการเคลื่อนไหวของกล้องของคุณในโลก
เปิดใช้งานอินสแตนซ์บน shaders อินสแตนซ์ช่วยให้เครื่องยนต์สามารถวาดวัตถุหลาย ๆ อัน (ที่มีตาข่ายเดียวกัน) ด้วยการเรียกเพียงครั้งเดียว คุณต้องการวัตถุที่จะใช้ร่วมกันตาข่ายและแชร์ shader เพื่อให้การทำงาน วัสดุอาจแตกต่างกัน แต่ shader ต้องสนับสนุนคุณสมบัติแตกต่างกันทั้งหมด
ในการทำให้เครื่องยนต์สร้างการเรนเดอร์แบบแบตช์ที่ดีขึ้นคุณอาจต้องการจัดกลุ่มตาข่ายเดียวกันเข้าด้วยกันในฉาก การเล่นด้วยคิวการเรนเดอร์วัสดุจะให้ผลลัพธ์ที่ดีหากตาข่ายหนึ่งมีวัสดุเดียวกันเสมอ ในระหว่างการพัฒนาเกมมือถือที่ฉันกำลังทำงานอยู่ฉันใช้มันเพื่อลด drawcalls มากกว่าครึ่งในฉากทดสอบของฉัน นอกจากนี้เนื่องจาก Unity 5.6 ตรวจสอบให้แน่ใจว่าคุณได้Enable Instancing
ทำเครื่องหมายในเนื้อหา
รักษา drawcalls และ SetPass ของคุณให้เรียกใช้โดยทั่วไป สิ่งเหล่านี้เป็นการเรียกร้องให้ GPU ของคุณวาดสิ่งต่างๆและมีค่าใช้จ่ายสูง การลด drawcalls (ซึ่งเป็นสิ่งที่การแบตช์และอินสแตนซ์กำลังทำอยู่) จะเพิ่มประสิทธิภาพโดยรวมที่ CPU ของคุณสามารถให้ได้ตามที่ต้องการเพื่อรอให้น้อยลง การเรียกใช้ SetPass เป็นการเปลี่ยนแปลงของเฉดสีในปัจจุบันของคุณดังนั้นหากคุณมีวัสดุที่แตกต่างกันจำนวนมากคุณจะมีการเรียกใช้ SetPass หลายครั้งซึ่งทำให้ CPU ต้องรอสักครู่
หากฉากของคุณมีขนาดใหญ่และเวลา CPU ของคุณในการผ่านวัตถุทั้งหมดในฉากลองลดวัตถุในฉาก จัดกลุ่มต้นไม้บางต้นแทนที่จะวางไว้อย่างไม่น่าเชื่อและให้พวกมันเป็นวัตถุชิ้นเดียว นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่ได้ย้ายต้นไม้หรือวัตถุหลักเนื่องจากทำให้ Unity ยกเลิกการแปลงที่เก็บไว้ชั่วคราวและคำนวณต้นไม้ฉากทั้งหมดใหม่อีกครั้ง
หากฉากของคุณมีขนาดใหญ่และเวลา CPU ของคุณยังคงเป็นส่วนใหญ่ใน Unity ที่เดินผ่านฉากต้นไม้เพื่อสร้างรายการเพื่อแสดงวัตถุทั้งหมดสิ่งหนึ่งที่คุณสามารถทำได้คือไม่ให้ Unity จัดการกับการเรนเดอร์ หากคุณมีวิธีที่ดีกว่าในการติดตามวัตถุที่วาดได้คุณสามารถใช้CommandBuffer.DrawMeshInstancedหรือGraphics.DrawMeshInstancedเพื่อวาดวัตถุเหล่านั้นด้วยมือ ฉันจะไม่ลงรายละเอียดมากนักเกี่ยวกับเรื่องนี้เพราะมันล้ำหน้ากว่ามากและเกี่ยวข้องกับการเลือกสรรการตรวจสอบตัวเองและอะไรก็ตาม
ในกรณีถ้าแบบคงที่หรือแบบไดนามิก batching ทำงานไม่ถูกต้อง (ซึ่งคุณสามารถมองเห็นโดยการตรวจสอบดีบักกรอบ), meshRenderer.material
คุณต้องให้แน่ใจว่าคุณได้แน่นอนโดยใช้วัสดุที่ใช้ร่วมกันและไม่ได้มีการทำสำเนาของวัสดุโดยอุบัติเหตุที่มีการเรียก การโทร.material
จะทำสำเนาของวัสดุของคุณและแบ่งแบทช์ ใช้.sharedMaterial
แทน
เนื่องจาก Unity 5.6 คุณสามารถใช้ Frame Debugger เพื่อกำหนดสาเหตุที่ drawcall บางตัวไม่ได้แบตช์กับ drawcalls ก่อนหน้า สิ่งนี้จะมีประโยชน์มากในขณะที่พยายามลด drawcalls ในเกมของคุณ
การย้ายอินสแตนซ์มีข้อดีดังต่อไปนี้มากกว่าการแบทช์คงที่ / ไดนามิก / กำหนดเอง:
- ใช้หน่วยความจำน้อยลงเนื่องจากไม่จำเป็นต้องใช้ตาข่ายในการทำซ้ำ
- สามารถใช้วัสดุหลายรายการต้องใช้ shader ร่วมกันเท่านั้น
- วัตถุสามารถเคลื่อนไหวได้
เช่นเดียวกับข้อเสียมันเป็นคุณสมบัติที่ค่อนข้างใหม่ใน Unity และอาจไม่เสถียรบ้าง GPU รุ่นเก่าหรือมือถือไม่จำเป็นต้องรองรับการใช้งาน