Bao nhiêu độ chính xác (một nửa, float, double, v.v.) là đủ cho một lớp Color?


8

Trong khi đọc một số cách các ứng dụng thời gian thực xử lý màu theo OpneGL, tôi nhận thấy rằng một số ví dụ đã triển khai Màu như một bộ sưu tập gồm 4 floats, trong khi các ứng dụng khác sử dụng 4 doubles. Tôi thậm chí đã thấy một số ví dụ nén đỉnh trong lĩnh vực phát triển trò chơi ủng hộ việc lưu màu là 4 short.

Tất cả điều này khiến tôi háo hức tìm hiểu thêm về điều này: độ chính xác giới hạn mà OpenGl (hoặc phần cứng) xử lý cho màu sắc là gì? Quan trọng hơn, mặc dù, những giới hạn về độ chính xác ở trên mà sự khác biệt màu sắc trở nên không thể nhận thấy là gì?

Tôi có ấn tượng rằng việc tìm hiểu kỹ hơn về điều đó sẽ giúp tôi suy nghĩ tốt hơn và quyết định cách triển khai lớp Màu cho các ứng dụng và kịch bản khác nhau (ví dụ: đưa ra các lựa chọn đánh đổi giữa bộ nhớ, tốc độ và đa dạng màu sắc).

Cảm ơn ý tưởng của bạn về điều này.

Câu trả lời:


6

Màu sắc hiển thị trên màn hình của bạn hoặc được lưu vào các định dạng tệp hình ảnh tiêu chuẩn sử dụng 8 bit cho mỗi thành phần. Vì vậy, để lưu trữ các màu này, nó đủ để sử dụng bốn byte ( unsigned char). Những màu này thường sử dụng không gian màu sRGB , bao gồm phép biến đổi "gamma" phi tuyến tính, phân phối lại độ chính xác để làm cho nó đồng nhất hơn về mặt nhận thức, do đó, nó thực sự khá gần với giới hạn của con người có thể cảm nhận được sự khác biệt về màu sắc. (Tuy nhiên, gam sRGB chỉ là một tập hợp con của tất cả các màu có thể nhận biết được về mặt vật lý. Các gam màu rộng hơn cần nhiều bit hơn.)

Tuy nhiên, nếu bạn đang tạo hoặc xử lý màu trong phần mềm đồ họa (và không chỉ tải / lưu trữ chúng), có nhiều lý do bạn có thể muốn sử dụng chính xác hơn.

  • Thực hiện các thao tác trên màu sắc, chẳng hạn như điều chỉnh độ sáng và độ tương phản, pha trộn alpha, hiệu chỉnh gamma, v.v ... đều có xu hướng mất độ chính xác. Bạn có thể muốn lưu trữ màu sắc từ 16 bit trở lên trong nội bộ để cung cấp cho mình khoảng không chính xác hơn. Mặt khác, làm tròn lặp lại thành 8 bit sau mỗi thao tác có thể làm giảm chất lượng dần dần.
  • Tương tự, khi làm việc với các màu tuyến tính (không phải màu được mã hóa gamma sRGB) cho toán học chiếu sáng, cần có độ chính xác cao hơn để đảm bảo bạn có đủ độ chính xác khi cuối cùng bạn chuyển đổi trở lại sRGB.
  • Có thể nhanh hơn và thuận tiện hơn khi làm việc với các màu dấu phẩy động thay vì các màu nguyên. Điều này đặc biệt đúng trên GPU, trong đó các hướng dẫn toán học số nguyên chỉ có một phần thông lượng của các hướng dẫn float. Nhưng ngay cả trên CPU, việc chuyển đổi màu sắc thành trôi nổi dễ dàng hơn và có thể nhanh hơn, thực hiện một loạt các hoạt động và sau đó chuyển đổi trở lại thành số nguyên, thay vì cố gắng thực hiện mọi thứ với toán học điểm cố định số nguyên.
  • Nếu bạn hoàn toàn hiển thị HDR thì bạn sẽ cần chính xác hơn 8 bit để xử lý dải màu và cường độ màu lớn hơn. Màn hình HDR mới chỉ bắt đầu xuất hiện chấp nhận hình ảnh với 10 hoặc 12 bit cho mỗi thành phần.

Sử dụng doublecho màu sắc là quá mức cần thiết, nhưng sử dụng floatcho đại diện bên trong của màu sắc là phổ biến cho tất cả các lý do ở trên. Khi làm việc với GPU, half(float 16 bit) cũng rất phổ biến, vì chúng hỗ trợ định dạng đó trong phần cứng.


Câu trả lời tuyệt vời, cảm ơn! Tôi chỉ không nhận được phần cuối cùng: sử dụng halfsẽ không phát sinh trong cùng một vấn đề mà bạn đã đề cập trước đó, do thiếu độ chính xác? Tôi mặc dù điều đó đặc biệt quan trọng ở GPU, do nhiều tính toán màu thường được thực hiện trong các shader
AndrewSteer

1
@AndrewSteer A halflà 16 bit, bao gồm 11 bit hiệu quả của độ chính xác mantissa, do đó, không chính xác như vậy float, nó vẫn đủ cho hầu hết các hoạt động màu. (Có thể không hoàn toàn đủ nếu bạn xuất ra màn hình HDR có gam màu cao; tôi không chắc chắn.)
Nathan Reed
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.