Sử dụng nhiều shader


53

Tôi hiện đang nghiên cứu các shader opengl nhưng tôi không thể tìm ra một điều: làm thế nào để áp dụng các shader khác nhau cho các đối tượng, ví dụ, một ấm trà được sử dụng shader toon và một cái khác trong cùng một cảnh sử dụng bề mặt rất phản chiếu và bị biến dạng khác từ một chức năng tiếng ồn, như trong video này

http://www.youtube.com/watch?v=1ogg4ZfdBqU

Một số khác đang áp dụng một shader nở trong một cảnh và một shader mờ chuyển động sau đó. Làm thế nào để đạt được những hiệu ứng đó khi bạn chỉ có thể có một shader đỉnh và một shader mảnh? Có mẹo nào như sử dụng nhiều hơn một chương trình đổ bóng không?


Câu trả lời hay của Re và David, đây là lý do tại sao bạn thấy thuật ngữ render pass hoặc shader pass ; có nhiều lượt cần thiết để soạn ảnh / khung cuối cùng. Một trong những lý do khiến việc xử lý GPU trở nên quá tệ song song và do đó rất nhanh là cần nhiều lượt đi trên mỗi khung hình. Quay trở lại trình kết xuất phần mềm Quake II hoặc Half Life để nhắc nhở bản thân bạn biết bao nhiêu shader tình yêu vượt qua thêm vào toàn bộ trải nghiệm đồ họa 3D.
Kỹ sư

Câu trả lời:


59

Câu trả lời đơn giản là bạn thay đổi chúng giữa mỗi lần gọi rút thăm. Đặt một shader, vẽ một ấm trà, đặt một shader khác, vẽ một ấm trà khác.

Đối với những thứ phức tạp hơn, nơi bạn cần áp dụng nhiều shader cho chỉ một đối tượng như mờ, phát sáng và vân vân. Về cơ bản, bạn có mọi thứ được kết xuất thành kết cấu. Sau đó, bạn kết xuất một hình tứ giác trên toàn bộ màn hình của bạn với kết cấu đó được áp dụng trong khi sử dụng một shader khác.

Ví dụ: nếu bạn muốn tạo hiệu ứng phát sáng, trước tiên bạn cần kết xuất cảnh không phát sáng thông thường của mình, sau đó chỉ hiển thị hình bóng màu của thứ bạn muốn phát sáng trên họa tiết sau đó bạn chuyển sang trình tạo bóng mờ và kết xuất quad với kết cấu đó gắn liền với cảnh không phát sáng của bạn.

Có một kỹ thuật khác gọi là Trì hoãn bóng trong đó bạn kết xuất cảnh mà không cần chiếu sáng và áp dụng nó sau trong không gian màn hình. Mục tiêu cốt lõi là giảm chi phí cho mỗi pixel chiếu sáng.

Thông thường bạn kết xuất bộ đệm màu được đặt trên màn hình. Thay vào đó, bạn sẽ hiển thị bộ đệm màu cũng như bộ đệm bình thường và độ sâu trong một lần đổ bóng (bạn có thể lưu trữ các vectơ bình thường và độ sâu trong kết cấu như với ánh xạ bình thường và chiều cao).

Điều này có nghĩa là, đối với mỗi pixel, bạn biết vị trí của mảnh hình học không trong suốt gần nhất (độ sâu hoặc khoảng cách từ mắt) màu sắc và bình thường. Do đó, bạn có thể áp dụng ánh sáng cho từng pixel trên màn hình thay vì cho từng pixel hiển thị của mọi đối tượng bạn hiển thị. Hãy nhớ rằng một số đối tượng sẽ được vẽ trên đầu của các đối tượng khác nếu cảnh không được hiển thị hoàn hảo ở phía trước để quay lại.

Đối với bóng bạn thực sự chỉ hiển thị bộ đệm độ sâu theo quan điểm của ánh sáng, sau đó sử dụng thông tin độ sâu đó để tìm ra nơi ánh sáng chiếu vào. Đó gọi là ánh xạ bóng (cũng có một cách tiếp cận khác gọi là thể tích bóng tạo ra hình bóng của hình học và đùn nó, nhưng bạn vẫn sẽ sử dụng các shader.).

Với OpenGL hiện đại hơn (3.0+), bạn sử dụng Đối tượng Framebuffer với các Đối tượng Renderbuffers được đính kèm. Vì renderbuffers có thể được coi như một kết cấu. Bạn có thể làm những việc như có 1 shader kết xuất với nhiều trình kết xuất khác nhau (vì vậy bạn không phải kết xuất kết cấu của mình sau đó các quy tắc sau đó là các thành phần phát sáng) nhưng thực tế cơ bản vẫn giống nhau.

Ngoài ra, mong muốn giảm thiểu số lượng công tắc đổ bóng càng nhiều càng tốt để tiết kiệm chi phí. Vì vậy, một số động cơ sẽ nhóm mọi thứ với cùng một vật liệu lại với nhau để tất cả có thể được rút ra cùng một lúc.


16

Bạn chỉ cần liên kết một shader, kết xuất tất cả các đối tượng bằng cách sử dụng shader đó, sau đó liên kết shader tiếp theo, kết xuất các đối tượng bằng cách sử dụng cái đó, v.v.

Bạn có thể có bao nhiêu đối tượng shader (shader được tải vào bộ nhớ và được biên dịch) như bạn muốn; mỗi lần chỉ có thể bị ràng buộc (hoạt động).


5
Về mặt triển khai, trong mỗi khung hình tôi sử dụng glUseProgram (1) và glUseProgram (2) để thay đổi shader? Làm thế nào tốn kém cho hiệu suất đó là?
ibrabeicker

4
Đó là một chi phí không cần thiết (mặc dù ít hơn trên các GPU gần đây so với các GPU trước đó). Đó là lý do tại sao hầu hết mọi người sắp xếp các đối tượng của họ theo vật liệu, kết xuất tất cả các đối tượng với cùng một vật liệu. Nhưng bạn chắc chắn có thể đủ khả năng để thay đổi chương trình hàng chục đến hàng trăm lần mỗi khung hình, nếu không muốn nói là nhiều hơn.
Nathan Reed

9

Sử dụng nhiều hơn một shader trong một cảnh khá đơn giản; thay đổi shader, đặt các giá trị cho nó, sau đó kết xuất đối tượng.

Tuy nhiên, hãy cẩn thận, chuyển đổi shader có thể tốn kém, vì vậy chuyển đổi shader nên được giữ ở mức tối thiểu. Có một số cách để giảm tác động này trong khi nhận được tất cả các hiệu ứng bạn muốn.

Phương pháp đầu tiên, và thường là mong muốn nhất, là thêm chức năng cho tất cả các kỹ thuật đổ bóng của bạn vào chỉ một shader và sử dụng các điều kiện bạn đặt để hiển thị mỗi đối tượng theo một cách khác nhau với cùng một shader. Tôi không biết về trình tạo bóng OpenGL và GLSL nhưng với trình tạo bóng HLSL và DirectX, chúng có thể được nhóm lại thành một "kỹ thuật" và bạn có thể đặt kỹ thuật thay vì thay đổi trình đổ bóng. Điều này cho phép bạn thực sự có một số pixel shader và đỉnh khác nhau trong cùng một tệp.

Cách thứ hai để giảm tác động hiệu suất là thiết lập trình đổ bóng, kết xuất mọi đối tượng sử dụng trình tạo bóng đó, sau đó lặp lại. Nói cách khác, tạo khối kết xuất của bạn.

Nếu bạn muốn áp dụng hai hiệu ứng khác nhau cho cùng một đối tượng (nghĩa là áp dụng một shon toon thì một số ánh sáng) bạn có thể thực hiện theo hai cách khác nhau. Đầu tiên là viết một shader áp dụng nhiều hiệu ứng trong cùng một chức năng. Cách thứ hai là kết xuất mô hình một lần với mỗi shader và trộn kết quả bằng cách đặt các tùy chọn hòa trộn khác nhau. Tuy nhiên, đây là một công việc nhiều hơn, và không thể đạt được trong mọi trường hợp. Do đó, lựa chọn tốt nhất là kết hợp tất cả các hiệu ứng của bạn vào một shader.


7

Một cách khác mà tôi đã phát hiện ra là thông qua một thứ gọi là chương trình con glsl, trong đó mỗi loại trình đổ bóng được xác định trong một hàm và trong ứng dụng OpenGL, chúng ta có thể định nghĩa chương trình con hiện tại, vẽ đỉnh của bộ đệm, thay đổi chương trình con và kết xuất bộ đệm khác


4
Điều này đòi hỏi phần cứng có khả năng GL 4.x, là phần cứng lớp DX11.
Nicol Bolas
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.