2013-07-01 57 views
11

Tôi đang xem nguồn của ứng dụng OpenGL sử dụng trình đổ bóng. Một trình đổ bóng cụ thể trông giống như sau:Giá trị float không đổi trong trình đổ bóng GLSL - bất kỳ lý do nào để sử dụng đồng phục?

uniform float someConstantValue; 
void main() 
{ 
    // Use someConstantValue 
} 

Đồng phục được đặt một lần từ mã và không bao giờ thay đổi trong suốt thời gian chạy ứng dụng.

Trong trường hợp nào tôi muốn khai báo someConstantValue dưới dạng uniform và không phải là const float?

Chỉnh sửa: Chỉ cần làm rõ, giá trị không đổi là hằng số vật lý.

Trả lời

7

Trước hết, hiệu suất khác biệt giữa việc sử dụng đồng phục hoặc hằng số có thể không đáng kể. Thứ hai, chỉ vì một giá trị luôn luôn liên tục trong tự nhiên không có nghĩa là bạn sẽ luôn luôn muốn nó được liên tục trong chương trình của bạn. Các lập trình viên thường sẽ điều chỉnh các giá trị vật lý để tạo ra kết quả tìm kiếm tốt nhất, ngay cả khi không phù hợp với thực tế. Ví dụ, gia tốc do trọng lực thường tăng lên trong một số loại trò chơi nhất định để làm cho chúng tăng nhịp độ nhanh hơn.

Nếu bạn không muốn phải cài đặt đồng phục trong mã của bạn, bạn có thể cung cấp một giá trị mặc định trong GLSL:

uniform float someConstantValue = 12.5; 

Điều đó nói rằng, không có lý do để không sử dụng const cho một cái gì đó giống như pi nơi sẽ có ít giá trị trong việc sửa đổi nó ....

+3

"chênh lệch hiệu suất giữa sử dụng đồng phục hoặc hằng số ** có thể ** không đáng kể" Không tốt để đoán. Khai báo một giá trị không đổi cho phép trình biên dịch GLSL thực hiện các tối ưu hóa nếu không sẽ không thể thực hiện được. Nhưng các trình biên dịch GLSL đáng buồn có xu hướng có lỗi và hành xử theo những cách không thể đoán trước. Vì vậy, một câu trả lời chung thực sự là không thể. Tôi đã gặp phải sự khác biệt về hiệu suất nghiêm trọng giữa việc sử dụng các mảng const và non-const (tùy thuộc vào độ dài của chúng) mặc dù giá trị của chúng sẽ không bao giờ được sửa đổi. Tôi cho rằng đây là lỗi trình biên dịch. – Tara

+0

Mặc dù nhận xét trước đó có khả năng chính xác vào thời điểm đó, loại biên dịch vừa kịp này có thể được mong đợi. Các giá trị thống nhất có thể được tối ưu hóa như thể chúng là hằng số. Xem [this] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression) để biết thêm thông tin. –

1

tôi có thể nghĩ ra hai lý do:

  1. Các nhà phát triển tái sử dụng một thư viện các shaders trong nhiều ứng dụng. Vì vậy, thay vì tùy chỉnh từng trình đổ bóng cho mỗi ứng dụng, nhà phát triển cố gắng giữ cho chúng chung chung.

  2. Nhà phát triển dự đoán biến này sau đó sẽ là cài đặt do người dùng kiểm soát. Vì vậy, tuyên bố nó là thống nhất là chuẩn bị cho tính năng sắp tới đó.

Nếu tôi là nhà phát triển và không áp dụng điều nào ở trên thì tôi sẽ tuyên bố là "const" thay vì nó có thể mang lại lợi ích hiệu suất và tôi sẽ không phải đặt đồng phục từ mã của mình.

15

lý do lớn:

Error: Loop index cannot be compared with non-constant expression.

Nếu tôi sử dụng:

uniform float myfloat; 
... 
for (float i = 0.0; i < myfloat; i++) 

tôi nhận được một lỗimyfloat không phải là một constant expression.


Tuy nhiên này là hoàn toàn hợp lệ:

const float myfloat = 10.0; 
... 
for (float i = 0.0; i < myfloat; i++) 

Tại sao?

When GLSL (and HLSL for that matter) are compiled to GPU assembly instructions, loops are unrolled in a very verbose (yet optimized using jumps, etc) way. Meaning the myfloat value is used during compile time to unroll the loop; if that value is a uniform (ie. can change each render call) then that loop cannot be unrolled until run time (and GPUs don't do that kind of JustInTime compilation, at least not in WebGL).

+1

Những trường hợp này rất hiếm, và bật lên trong bóng đổ tính toán hơn bất cứ điều gì (và một số hệ thống hoạt hình xương). –

+1

Những ngày này, bạn có thể mong đợi OpenGL và D3D hiện đại để thực hiện biên dịch just-in-time cho các giá trị thống nhất (bất kỳ giá trị nào không thay đổi trong khoảng thời gian * one * render call). Ví dụ, một câu lệnh if kiểm tra một biến thống nhất boolean sẽ được biên dịch đi khi cuộc gọi kết xuất được khởi tạo - không có kiểm tra thời gian chạy nào được thực hiện trên GPU. Xem [wiki này] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression) để biết thêm thông tin. –

+0

Điều này trả lời ngược lại câu hỏi - OP muốn biết lý do tại sao bạn sẽ sử dụng đồng phục thay vì một const, không phải là cách khác. – Karu