2012-03-28 20 views
5

Cho phép nói rằng tôi có 2 loài như con người và ngựa. Chúng có các hệ xương khác nhau nên mảng xương đồng đều sẽ khác nhau đối với từng loài. Tôi có phải thực hiện hai chương trình đổ bóng riêng biệt có thể hiển thị từng mảng xương đúng cách hay có cách tự động khai báo mảng đồng nhất và lặp qua mảng động đó thay thế không?(OpenGL 3.1 - 4.2) Mảng đồng nhất động?

Giữ hiệu suất trong tâm trí (Có tất cả các trình đổ bóng hút khi phân nhánh quyết định đi xung quanh).

Trả lời

12

Cho đến OpenGL 4.3, các mảng trong GLSL phải có kích thước cố định, biên dịch. 4.3 cho phép sử dụng các đối tượng đệm lưu trữ đổ bóng, cho phép độ dài cuối cùng của chúng là "không bị chặn". Về cơ bản, bạn có thể làm điều này:

buffer BlockName 
{ 
    mat4 manyManyMatrices[]; 
}; 

OpenGL sẽ tìm ra có bao nhiêu ma trận là trong mảng này trong thời gian chạy dựa vào cách bạn sử dụng glBindBufferRange. Vì vậy, bạn vẫn có thể sử dụng manyManyMatrices.length() để nhận được độ dài, nhưng nó sẽ không phải là một hằng số biên dịch-thời gian.

Tuy nhiên, tính năng này là (tại thời điểm chỉnh sửa này) rất mới và chỉ được triển khai trong giai đoạn beta. Nó cũng yêu cầu phần cứng lớp GL 4.x (còn gọi là phần cứng Direct3D 11). Cuối cùng, vì nó sử dụng khối lưu trữ đổ bóng, việc truy cập dữ liệu có thể chậm hơn so với dữ liệu có thể hy vọng.

Vì vậy, tôi khuyên bạn chỉ nên sử dụng khối đồng nhất có số lượng ma trận lớn nhất mà bạn sẽ sử dụng. Nếu điều đó trở thành vấn đề về bộ nhớ (không chắc), thì bạn có thể tách các trình đổ bóng dựa trên kích thước mảng hoặc sử dụng các khối lưu trữ đổ bóng hoặc bất cứ thứ gì.

10

Bạn có thể sử dụng n-by-1-Textures để thay thế cho mảng. Kích thước họa tiết có thể được xác định tại thời gian chạy. Tôi sử dụng phương pháp này để truyền một số lượng ánh sáng tùy ý đến các bóng đổ của tôi. Tôi ngạc nhiên rằng nó chạy nhanh như thế nào mặc dù có nhiều vòng và nhánh. Để xem ví dụ, hãy xem tệp shader đa giác trong tệp jogl3.glsl.nontransp trong các nguồn jReality.

uniform sampler2D sys_globalLights; 
uniform int sys_numGlobalDirLights; 
uniform int sys_numGlobalPointLights; 
uniform int sys_numGlobalSpotLights; 

...

int lightTexSize = sys_numGlobalDirLights*3+sys_numGlobalPointLights*3+sys_numGlobalSpotLights*5; 

    for(int i = 0; i < numDir; i++){ 
     vec4 dir = texture(sys_globalLights, vec2((3*i+1+0.5)/lightTexSize, 0)); 

...