Phương pháp tốt nhất để cập nhật đồng phục shader là gì?


10

Cách được chấp nhận nhất để giữ cho ma trận của shader cập nhật là gì, và tại sao?

Ví dụ, tại thời điểm này, tôi có một Shaderlớp lưu trữ các tay cầm cho chương trình & đồng phục shader GLSL. Mỗi lần tôi di chuyển máy ảnh, sau đó tôi phải truyền ma trận chế độ xem mới cho trình đổ bóng, sau đó mỗi đối tượng thế giới khác nhau tôi phải chuyển ma trận mô hình của nó cho trình tạo bóng.

Điều này hạn chế nghiêm trọng tôi vì tôi không thể làm bất cứ điều gì mà không có quyền truy cập vào đối tượng đổ bóng đó.

Tôi đã nghĩ đến việc tạo ra một ShaderManagerlớp singleton chịu trách nhiệm tổ chức tất cả các shader hoạt động. Sau đó tôi có thể truy cập nó từ bất cứ đâu và một đối tượng thế giới sẽ không phải biết về những gì các shader đang hoạt động chỉ là nó cần cho các ShaderManagerma trận mong muốn nhưng tôi không chắc đây là cách tốt nhất và có thể có một số vấn đề sẽ phát sinh từ cách tiếp cận này.


Tại sao không truyền dữ liệu cho các shader khi đến lúc kết xuất?
Nick Caplinger

Đó là những gì tôi dự định nhưng làm thế nào? Nếu một đối tượng tạo ra một shader thì làm thế nào các đối tượng thế giới có nghĩa là biết về sự tồn tại của shader đó và để vượt qua nó các ma trận cần thiết?
Lerp

Câu trả lời:


11

Sử dụng bộ đệm đồng nhất (nghĩa là bộ đệm không đổi trong biệt ngữ D3D).

Miễn là tất cả các shader của bạn đồng ý về bố cục và điểm ràng buộc của từng bộ đệm như vậy thì việc cập nhật sẽ trở nên dễ dàng. Người mẫu không cần biết gì về shader cả. Họ chỉ cần cập nhật ma trận khung nhìn mô hình trong bộ đệm liên tục của họ và đường ống kết xuất sẽ tự động sử dụng nó.

Tối thiểu tôi sẽ tranh luận bạn nên có hai bộ đệm như vậy. Đầu tiên nên lưu trữ ma trận chiếu, ma trận camera, ma trận chiếu camera được nối, thông tin khung nhìn, chi tiết bực bội và nghịch đảo ma trận. Bạn chỉ cần cập nhật bộ đệm này một lần cho mỗi cảnh.

Sau đó cung cấp cho mỗi mô hình một bộ đệm khác để lưu trữ ma trận xem mô hình, ma trận bình thường, nghịch đảo và các thuộc tính vật liệu. Điều này được cập nhật một lần cho mỗi mô hình và có thể được thực hiện trong một lần cập nhật khác nhau (nếu / khi thích hợp). Thông tin vật liệu có thể / nên được chuyển đến bộ đệm dành riêng cho vật liệu thứ ba nếu bạn có khả năng chia sẻ vật liệu giữa nhiều đối tượng.

Trong thiết lập chiếu sáng phía trước, sẽ rất hợp lý khi đặt tất cả các đèn vào một bộ đệm khác và trong bóng mờ bị trì hoãn, nó cũng có ý nghĩa khi sử dụng bộ đệm cho ánh sáng cho đèn đi qua (thay cho bộ đệm mô hình / vật liệu được sử dụng trong vượt qua hình học).

Lưu ý rằng bạn cần một phiên bản GL cập nhật vừa phải để sử dụng bộ đệm đồng nhất (3.1 hoặc tiện ích mở rộng; đủ phổ biến hiện nay ngoại trừ một số máy tính xách tay cũ nhưng vẫn còn hoạt động) và bạn cần có phiên bản khá gần đây có thể liên kết bộ đệm thống nhất với các vị trí liên kết cụ thể từ bên trong mã shader (4.2; vẫn không phổ biến nhưng sẽ tốt hơn) nếu không bạn phải thực hiện nhiều công việc hơn trong mã phía CPU của mình để thiết lập mọi thứ (mã CPU của bạn cần biết ràng buộc đúng dù sao đi nữa, do đó, nó có mùi API hơn là một vấn đề nghiêm trọng). Thật không may, OpenGL | ES đã không thêm bộ đệm thống nhất cho đến 3.0, vẫn không được hỗ trợ trên hầu hết các nền tảng di động phổ biến.

Nếu bộ đệm không phải là một tùy chọn thì bạn sẽ cần một số vị trí toàn cầu để lưu trữ các vị trí chỉ mục cho trình đổ bóng hoạt động. Bạn có thể sử dụng glGetUniformLocationsau khi tải shader của mình để tìm các chỉ mục cho các tên nổi tiếng (thích ModelViewMatrixhoặc tương tự) sau đó lưu trữ các chỉ mục này. Kết xuất của bạn có thể ánh xạ các giá trị enum như MODEL_VIEWđược chuyển đến một SetUniformhàm bao bọc để xem xét trình đổ bóng bị ràng buộc, tìm chỉ mục và gọi glUniformđúng. Đây không phải là một thay đổi lớn trong việc sử dụng mã máy khách từ các bộ đệm ngoài việc cần thiết lập từng bộ đồng phục nếu bạn có được tất cả các gói độc đáo.

Xem Khối Inteface GLSLĐối tượng bộ đệm thống nhất .


Tôi biết họ sẽ là một cách tích hợp. Cảm ơn!
Lerp

4

Cách đơn giản nhất để làm điều này là chỉ cần chuẩn hóa tên thống nhất giữa các shader của bạn và chỉ cần gửi tất cả dữ liệu ngay trước khi bạn vẽ. Chi phí không phải là điên rồ, nhưng bạn có thể tối ưu hóa nó sau này để không phải lúc nào cũng gửi đồng phục cập nhật ít hơn.

Cách tôi làm điều này trong trò chơi của mình là tôi có một Materiallớp trừu tượng . Vật liệu đóng vai trò là cầu nối giữa trò chơi và shader. Mỗi Materialcó một Shadervà các thuộc tính khác nhau có thể được thiết lập, bao gồm cả kết cấu. Khi đến lúc vẽ một vật thể, nó Materialbị ràng buộc. Các Bindphương pháp có một GraphicsStatetham số có chứa tất cả các trạng thái đồ họa hiện nay - ma trận, đèn, vv Bindphương pháp liên kết với các shader và kết cấu và bộ tất cả các trang phục, sử dụng bất cứ điều gì nó cần từ GraphicsState.

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.