วิธีจัดการกับวัสดุในระบบ Entity / Component


13

การปรับใช้ E / C ของฉันเป็นสิ่งพื้นฐานที่หน่วยงานเป็นเพียง ID ของคอมโพเนนต์คือข้อมูลและระบบดำเนินการกับข้อมูล ตอนนี้ฉันมีปัญหากับวัสดุวัตถุและการแสดงผลโดยทั่วไป สำหรับ objetcs ธรรมดาที่ฉันมี a ModelComponent, เชื่อมโยงกับ a RenderSystem, ModelComponentจะมีรหัสจุดสุดยอดบัฟเฟอร์ที่ระบบการเรนเดอร์ใช้ ง่ายMaterialComponentอาจจะมีสีหรือความแข็งแรง specular ฯลฯ แต่ผมอยากให้มันเป็นพอมีความยืดหยุ่นเพื่อให้สามารถมากกว่าหนึ่งทำให้ผ่านและ "ผลกระทบ" MaterialComponentทั่วไปที่ไม่ได้เป็นเรื่องง่ายเป็นตัวแปรที่เรียบง่ายใน

พยายามแก้ไขปัญหาเหล่านี้ฉันหาวิธีแก้ไขสองวิธี:

1 - ส่วนประกอบวัสดุที่มีความพิเศษมาก

บางสิ่งเช่นนี้

struct Material : public Component
{
    ShaderData* shader;
    std::vector<std::pair<std::string, boost::any>> uniforms;
    [...]
};

และในระบบเรนเดอร์ฉันจะวนซ้ำและส่งชุดไปที่ shader ฉันคิดว่านี่จะช้า แต่เร็วพอสำหรับจุดประสงค์ของฉัน

2 - อีกชั้นหนึ่งของนามธรรม, MaterialData

การมีคลาสเพื่อห่อวัสดุเฉพาะที่สามารถสืบทอดได้โดยวัสดุพิเศษอะไรก็ตามคลาสพื้นฐานจะมีบางอย่างเช่นvoid set_shader_constants(ShaderData* d)แต่การติดตั้งจะขึ้นอยู่กับแต่ละคลาสและMaterialComponentจะมีตัวชี้ไปยังวัตถุ MaterialData

ฉันไม่แน่ใจว่าวิธีการใดที่ฉันต้องการ แต่สิ่งเหล่านี้ไม่ได้สัมผัสเรื่องของการผ่านหลายครั้งหรือเทคนิคการเรนเดอร์ที่ซับซ้อนอื่น ๆ

มีความคิดเกี่ยวกับวิธีการทำสิ่งนี้ให้สำเร็จหรือไม่?

คำตอบ:


26

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

ดังนั้นฉันขอแนะนำให้คุณใช้แนวทางอื่น:

  • เนื้อหาเป็นเพียงประเภทอื่นในโหมดแสดงภาพของคุณ
  • โปรแกรมแสดงภาพของคุณมีประเภทที่แสดงถึง "สิ่งที่จะดึงดูดไปยังหน้าจอ" บ่อยครั้งที่สิ่งเหล่านี้เรียกว่า "การแสดงผลอินสแตนซ์" หรือ "การแสดงผล" หรือแม้แต่ "แบบจำลอง" ประเภทนี้มีการอ้างอิงถึงเนื้อหาที่จะใช้เมื่อวาดและจัดทำ API สาธารณะเพื่อให้ผู้บริโภคของ renderer สามารถตั้งค่าวัสดุนั้นตามที่ต้องการ

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

จากนั้นคุณทำสิ่งนี้:

  • ในเลเยอร์ที่เป็นนามธรรมของส่วนประกอบอื่น ๆ ของคุณคุณมี "องค์ประกอบมุมมอง" ซึ่งแสดงถึงการนำเสนอแบบภาพของเอนทิตี ส่วนประกอบนี้มีการอ้างอิงถึงสิ่งที่สามารถแสดงผลได้ (ตามที่อธิบายไว้ข้างต้น) ซึ่งจะมีการอ้างอิงไปยังวัสดุ คอมโพเนนต์อาจจัดเตรียม API เพื่อเปิดเผยการแสดงผล (ดังนั้นการอนุญาตให้ไคลเอ็นต์จัดการกับมัน) หรืออาจห่อ API ของ renderable เพื่อควบคุมการเปิดเผย ขึ้นอยู่กับคุณ

สิ่งนี้ระบุถึงปัญหาการพึ่งพาซึ่งกันและกันของส่วนประกอบที่คุณกำลังประสบอยู่โดยการมีแบบจำลองและวัสดุเป็นทั้งส่วนประกอบ กิจการควรมีแง่มุมหรือไม่และด้านนั้นควรเข้ารหัสทุกอย่างเกี่ยวกับการนำเสนอของกิจการรวมถึงวัสดุ

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

ปัญหาของคุณในการอนุญาตให้มีเอฟเฟกต์ที่ซับซ้อนมากขึ้นและการส่งผ่านหลายครั้งเป็นสิ่งที่สามารถแก้ไขได้ในเนื้อหาเป็นหลักโดยการแสดงฟังก์ชั่นในการสืบค้นและตั้งค่าคงที่ชื่อ shader ที่เปิดเผยโดยไฟล์ shader ของวัสดุ โดยเฉพาะอย่างยิ่งหากคุณใช้ไฟล์เอฟเฟกต์ (ใน D3D) ซึ่งรองรับการส่งข้อมูลหลายครั้งและไม่ชอบ แม้ว่าคุณจะไม่ได้ใช้ไฟล์เอฟเฟกต์ แต่คุณสามารถแสดงความคิดเห็นเกี่ยวกับการส่งหลายครั้งจากวัสดุแต่ละรายการที่มีเฉดสีที่แตกต่างกันและอนุญาตให้ API วัสดุเพื่อจัดหาเครื่องมือจัดการสำหรับสิ่งนั้น มันจะง่ายขึ้นและสะอาดขึ้นเมื่อรวมเข้ากับ API การแสดงผลที่น่าจะเป็นไปได้มากที่สุดเนื่องจากเนื้อหาอยู่ในระดับเดียวกับสิ่งที่เป็นนามธรรม


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