2011-01-26 21 views
9

Tôi đang viết một bóng đổ (HLSL) và tôi cần đóng gói một giá trị màu vào định dạng R32. Tôi đã tìm thấy các đoạn mã khác nhau để đóng gói một phao vào định dạng R8G8B8A8, nhưng không có mã nào trong số chúng dường như hoạt động ngược lại. Tôi đang nhắm mục tiêu SM3.0, do đó (afaik) bit hoạt động không phải là một lựa chọn.Đóng gói bốn byte trong phao

Nói tóm lại, tôi cần để có thể làm điều này:

float4 color = ...; // Where color ranges from 0 -> 1 
float packedValue = pack(color); 

ai biết làm thế nào để làm điều này?

CẬP NHẬT
Tôi đã nhận được một số tiến triển ... có lẽ điều này sẽ giúp làm rõ câu hỏi.
giải pháp tạm thời của tôi là như vậy:

const int PRECISION = 64; 

float4 unpack(float value) 
{ 
    float4 color; 

    color.a = value % PRECISION; 
    value = floor(value/PRECISION); 

    color.b = value % PRECISION; 
    value = floor(value/PRECISION); 

    color.g = value % PRECISION; 
    value = floor(value/PRECISION); 

    color.r = value; 

    return color/(PRECISION - 1); 
} 

float pack(float4 color) 
{ 
    int4 iVal = floor(color * (PRECISION - 1)); 

    float output = 0; 

    output += iVal.r * PRECISION * PRECISION * PRECISION; 
    output += iVal.g * PRECISION * PRECISION; 
    output += iVal.b * PRECISION; 
    output += iVal.a; 

    return output; 
} 

tôi về cơ bản ... giả vờ Tôi đang sử dụng các loại nguyên: s
Qua đoán và kiểm tra, 64 là con số cao nhất tôi có thể sử dụng trong khi vẫn duy trì phạm vi [0 ... 1]. Thật không may, điều đó cũng có nghĩa là tôi đang mất một số chính xác - 6 bit thay vì 8.

+2

Nó sẽ được hỏi cuối cùng, vì vậy bạn cũng có thể nhận được nó hơn với :) tại sao bạn phải sử dụng R32 thay vì một định dạng số nguyên? – eodabash

+0

Heh ... Tôi biết nó đã đến, nhưng vẫn ... Trong thực tế, tôi đang sử dụng R32G32B32A32, tôi chỉ nói R32 để đơn giản hóa. Tôi chỉ cố gắng tìm ra cách tôi có thể đẩy càng nhiều thông tin càng tốt vào một mục tiêu render đơn. Tất nhiên, tôi vẫn cần phải làm một số phép đo, nhưng tôi tưởng tượng đẩy tất cả dữ liệu của tôi vào một mục tiêu render đơn là rẻ hơn một chút so với sử dụng bốn thông qua tàu điện ngầm. – YellPika

+0

Tôi rất mong được thấy những câu trả lời mà mọi người có thể nghĩ ra cho câu hỏi này. – Olhovsky

Trả lời

1

Có một cái nhìn tại địa chỉ: http://diaryofagraphicsprogrammer.blogspot.com/2009/10/bitmasks-packing-data-into-fp-render.html

Câu trả lời ngắn gọn là rằng nó không thể làm một bao bì lossless của 4 nổi vào 1 phao.

Thậm chí nếu bạn tìm cách đóng gói 4 phao, lưu trữ số mũ và độ dài của chúng, quy trình đóng gói và giải nén có thể cực kỳ tốn kém.

+1

Vâng, trong thực tế (và như tiêu đề nói) Tôi đang cố gắng để đóng gói bốn byte, không bốn nổi. Tôi đã thấy bài đăng đó trước đó. Thật không may, mã sử dụng các toán tử bit - sẽ không xảy ra khi sử dụng SM3.0 ...: ( – YellPika

+0

Bạn có thể thay thế bithifts bằng số nhân. Ví dụ: 'x << 16' giống với' x * = 2^16' – Olhovsky

+0

Oh Mặc dù anh ta sử dụng bitmask và bạn không thể sử dụng chúng trong SM3.0. – Olhovsky

1

Làm như mã mẫu của bạn cho 3 thành phần để gói chúng vào trong s = significand và làm exp2 (color.g) (1 + s) để đóng thành phần khác vào số mũ. Bạn vẫn sẽ mất đi độ chính xác, nhưng nó sẽ không tệ như thể bạn cố gắng đóng gói mọi thứ vào những điều như bạn đang làm. Không may là không có cách nào để tránh mất độ chính xác, vì có rất nhiều giá trị float NaN và Inf không thể phân biệt lẫn nhau và khó làm việc với (và thậm chí không được hỗ trợ bởi GPU của bạn, tùy thuộc vào độ tuổi nó là).

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