Cách xử lý vật liệu trong hệ thống Thực thể / Thành phần


13

Việc triển khai E / C của tôi là cơ bản trong đó Thực thể chỉ là ID, Thành phần là dữ liệu và Hệ thống hoạt động trên Dữ liệu. Ngay bây giờ tôi đang gặp rắc rối với các vật liệu đối tượng và kết xuất nói chung. Đối với objetcs đơn giản, tôi có a ModelComponent, gắn với a RenderSystem, ModelComponentcó id bộ đệm đỉnh mà hệ thống kết xuất sử dụng. Một đơn giản MaterialComponentcó thể có màu sắc hoặc cường độ đặc biệt, v.v., nhưng tôi muốn nó đủ linh hoạt để cho phép nhiều hơn một kết xuất và "hiệu ứng" chung không dễ như một biến đơn giản trong MaterialComponent.

Cố gắng giải quyết những vấn đề này tôi đã đưa ra hai giải pháp:

1 - Thành phần vật liệu siêu chung

Một cái gì đó như thế này:

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

và trong hệ thống kết xuất, tôi sẽ lặp và chuyển đồng phục cho shader. Tôi cho rằng điều này sẽ chậm, nhưng đủ nhanh cho mục đích của tôi.

2 - Một lớp trừu tượng khác, MaterialData

Có một lớp để bọc các vật liệu cụ thể, có thể được kế thừa bởi bất kỳ vật liệu chuyên dụng nào, lớp cơ sở sẽ có thứ gì đó giống như void set_shader_constants(ShaderData* d)nhưng việc triển khai tùy thuộc vào từng lớp và MaterialComponentsẽ có một con trỏ tới một đối tượng MaterialData.

Tôi không chắc chắn cách tiếp cận nào tôi thích, nhưng cả hai đều không chạm vào chủ đề của nhiều đường chuyền hoặc các kỹ thuật kết xuất phức tạp khác.

Bất kỳ ý tưởng về làm thế nào để thực hiện điều này?

Câu trả lời:


26

Vật liệu là một khái niệm đồ họa và thuộc về trình kết xuất của bạn. Một trình kết xuất quá thấp là một phần kiến ​​trúc được xây dựng trên đỉnh của một hệ thống thực thể. Hệ thống thực thể nên dành cho các đối tượng trò chơi cấp cao hơn. Không phải tất cả mọi thứ cần phải là một thành phần, và trên thực tế, nói chung, đó là một ý tưởng tồi để cố gắng buộc mọi thứ vào một mô hình như thế. Nó tạo ra một giải pháp mẫu số ít phổ biến nhất.

Do đó, tôi sẽ khuyên bạn nên thực hiện một cách tiếp cận khác:

  • Một vật liệu chỉ là một loại khác trong trình kết xuất của bạn.
  • Trình kết xuất của bạn có một loại đại diện cho "một thứ sẽ được vẽ lên màn hình." Thường thì chúng được gọi là "phiên bản kết xuất" hoặc "kết xuất" hoặc thậm chí là "mô hình". Loại này có tham chiếu đến tài liệu mà nó sẽ sử dụng khi vẽ và cung cấp API công khai để cho phép người tiêu dùng trình kết xuất đặt tài liệu đó thành bất cứ điều gì mong muốn.

Điều này về cơ bản là yêu cầu bạn lấy ModelComponentvà đổi tên nó Model, loại bỏ sự phụ thuộc vào lớp thực thể / thành phần và do đó chuyển nó sang lớp trừu tượng thấp hơn, cùng với phần còn lại của trình kết xuất.

Sau đó, bạn làm điều này:

  • Trong cùng một lớp trừu tượng như các thành phần khác của bạn, bạn có một loại "thành phần khía cạnh" đại diện cho sự trình bày trực quan của một thực thể. Thành phần này chỉ chứa một tham chiếu đến một số kết xuất (như được mô tả ở trên), trong đó lần lượt chứa tham chiếu đến một vật liệu. Thành phần này có thể cung cấp API để hiển thị kết xuất được (do đó cho phép khách hàng thao tác với nó) hoặc nó có thể bao bọc API của kết xuất để kiểm soát phơi sáng. Tùy bạn.

Điều này giải quyết vấn đề phụ thuộc lẫn nhau về thành phần mà bạn gặp phải bằng cách có cả mô hình và vật liệu đều là thành phần; một thực thể nên có một khía cạnh hoặc không, và khía cạnh đó sẽ có thể mã hóa mọi thứ về cách trình bày của thực thể, bao gồm cả vật liệu.

Điều này cũng cho phép bạn linh hoạt thực hiện các cách tiếp cận khác với đối tượng vật chất sẽ khó thực hiện hơn với đối tượng đó như là một thành phần vì thiếu tương đương với phần còn lại của hệ thống kết xuất.

Vấn đề của bạn về việc cho phép các hiệu ứng phức tạp hơn và nhiều lần vượt qua là vấn đề có thể được giải quyết chủ yếu trong tài liệu, bằng cách hiển thị các hàm để truy vấn và đặt các hằng số shader có tên được hiển thị bởi tệp shader của vật liệu. Điều này đặc biệt đúng nếu bạn sử dụng các tệp hiệu ứng (trong D3D) hỗ trợ nhiều lượt đi và tương tự. Ngay cả khi bạn không sử dụng các tệp hiệu ứng, bạn có thể đưa ra ý tưởng về nhiều đường chuyền từ vật liệu, mỗi đường dẫn có các shader riêng biệt và cho phép API vật liệu cung cấp các thao tác cho điều đó. Sẽ dễ dàng và dễ dàng hơn để tích hợp vào API kết xuất rất có thể, vì hiện tại vật liệu có cùng mức độ trừu tượng.


1
Cảm ơn câu trả lời của bạn, vấn đề này đã gây khó chịu cho tôi trong một thời gian, nhưng việc tạo một trình kết xuất mà không có sự ràng buộc của E / C thì dễ dàng hơn nhiều.
Luke B.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.