2012-03-27 27 views
19

Tôi đang cố nghiên cứu bản đồ bóng trong WebGL. Tôi thấy cùng một đoạn mã đổ bóng được sao chép trong nhiều thư viện và ví dụ khác nhau để đạt được điều này. Tuy nhiên không nơi nào tôi tìm thấy lời giải thích về cách nó hoạt động.Đóng gói float vào vec4 - mã này hoạt động như thế nào?

Ý tưởng là lưu giá trị độ sâu (một phao đơn) vào bộ đệm màu (vec4). Có một chức năng gói tiết kiệm nổi đến vec4 và giải nén chức năng lấy nổi từ vec4.

vec4 pack_depth(const in float depth) 
{ 
    const vec4 bit_shift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0); 
    const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0); 
    vec4 res = fract(depth * bit_shift); 
    res -= res.xxyz * bit_mask; 
    return res; 
} 

float unpack_depth(const in vec4 rgba_depth) 
{ 
    const vec4 bit_shift = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0); 
    float depth = dot(rgba_depth, bit_shift); 
    return depth; 
} 

tôi sẽ tưởng tượng rằng đóng gói một phao vào vec4 phải là một vấn đề tầm thường, chỉ cần sao chép nó vào một trong 4 vị trí của vec4 và để người khác sử dụng. Đó là lý do tại sao logic chuyển bit trong đoạn mã trên lại khó hiểu với tôi.

Có ai có thể làm sáng tỏ không?

Trả lời

12

Nó không lưu trữ GLSL float trong GLSL vec4. Những gì nó đang làm là lưu trữ một giá trị trong một số vec4, khi được ghi vào bộ đệm khung RGBA8 (giá trị 32 bit) có thể được đọc là vec4 và sau đó được hoàn lại vào cùng một float đã được đưa ra trước đó.

Nếu bạn đã làm những gì bạn đề xuất, chỉ cần viết giá trị dấu phẩy động vào kênh màu đỏ của bộ đệm khung, bạn chỉ nhận được 8 bit chính xác. Với phương pháp này, bạn nhận được tất cả 32 bit làm việc cho bạn.

+0

Tôi hiểu. Nó không phải là rõ ràng với tôi rằng bộ đệm màu trong nội bộ lưu trữ các giá trị màu sắc như 4 số nguyên mặc dù chúng tôi ăn nó một vec4. Nếu đó là như vậy, thì mã trên có ý nghĩa. Cảm ơn. – Jayesh

+0

Nói đúng là chuyển đổi là số điểm cố định 32 bit - không phải là số dấu phẩy động. – Mortennobel

3

Ngoài các câu trả lời ở trên, bạn có thể quan tâm mở rộng kết cấu điểm nổi được mô tả ở đây:

http://www.khronos.org/registry/webgl/extensions/OES_texture_float/

Lưu ý rằng có những phần cứng/phần mềm thiết lập ra có nơi mở rộng này không tồn tại/chạy, nhưng nếu nó chắc chắn là một phần mở rộng tốt. Kinh nghiệm của tôi là nó cũng nhanh. Nếu bạn sử dụng điều này, bạn có thể sử dụng ba kênh còn lại để lưu trữ thông tin khác, chẳng hạn như màu từ kết cấu chiếu.

2

Nếu bạn quan tâm đến chi tiết nitty-gritty về cách thức hoạt động thường xuyên này, tôi khuyên bạn nên đọc my blog post. Tôi đang thêm một số chi tiết ở đây về cách mã hoạt động và để giải quyết một số trường hợp sử dụng có thể.

Như bạn có thể đã tìm ra, mã đó đang mã hóa giá trị float chuẩn hóa thành vec4. OpenGL ES 2.0 hoặc WebGL (tại thời điểm viết), có thể tận dụng các gói/giải nén thường trình này để cung cấp các điểm nổi chính xác 32 bit qua các họa tiết RGBA8 (more on this in the spec).

Ngay cả với phần mở rộng đăng bởi Mikael (OES_texture_float) nó có thể là cần thiết (cho mục đích gỡ lỗi chẳng hạn) để đổ đầy 32 bit chính xác bình thường điểm nổi và như mô tả trong spec readPixels hiện đang bị hạn chế bởi những điều sau

Chỉ chấp nhận hai kết hợp định dạng và loại. Đầu tiên là định dạng RGBA và gõ UNSIGNED_BYTE. Thứ hai là một định dạng được lựa chọn thực hiện.

Các vấn đề liên quan