Màn hình máy tính phát ra một hỗn hợp của ánh sáng đỏ, xanh lá cây, và màu xanh dương qua từng pixel. Khi hỗn hợp ánh sáng đi vào mắt và chạm một khu vực của võng mạc, các tế bào thụ cảm hình nón được kích thích và xung thần kinh được gửi xuống các dây thần kinh thị giác đối với não. Bộ não nhận tín hiệu và tạo ra một màu sắc. Khi hỗn hợp ánh sáng khác nhau, các tế bào được kích thích khác nhau, do đó tạo ra một màu sắc khác nhau trong tâm trí. Hình bên dưới cho thấy cách pha trộn màu đỏ, xanh lá cây, và màu xanh tạo ra các màu khác nhau; nó cũng cho thấy cường độ khác nhau của màu đỏ. Bằng cách sử dụng cường độ khác nhau cho mỗi thành phần màu và trộn chúng lại với nhau, chúng ta có thể mô tả tất cả các màu sắc chúng ta cần để hiển thị hình ảnh trung thực.

rgb_model

Một màn hình có cường độ tối đa ánh sáng đỏ, xanh lá cây, và màu xanh nó có thể phát ra. Để mô tả cường độ của ánh sáng, nó rất hữu ích để sử dụng một phạm vi chuẩn hoá từ 0 đến 1. 0 biểu thị không có cường độ và 1 biểu thị đầy đủ cường độ. giá trị trung gian biểu thị cường độ trung bình. Ví dụ, các giá trị (0.25, 0.67, 1.0) có nghĩa là các hỗn hợp ánh sáng bao gồm 25% cường độ của ánh sáng màu đỏ, 67% cường độ của ánh sáng màu xanh lá cây, và 100% cường độ của ánh sáng màu xanh dương. Như ví dụ này, chúng ta có thể đại diện cho một màu bằng một vector màu 3D (r, g, b), trong đó 0 ≤ r, g, b ≤ 1, và mỗi thành phần màu sắc mô tả cường độ của ánh sáng đỏ, xanh lá cây, và màu xanh, tương ứng, trong hỗn hợp.

Tính toán trên màu sắc

Một số phép tính trên vector cũng được áp dụng cho việc tính toán màu sắc. Ví dụ chúng ta có thể cộng 2 màu sắc để được màu mới:

( 0.0,0.5,0.25) + (0.5, 0.0, 0.5) = (0.5, 0.5, 0.75)

Hoặc trừ với nhau để tạo màu mới:

(1,1,0) – (1,0,0) = (0,1,0)

Có thể nhân với một số thực để làm màu trở nên sáng hơn hoặc tối hơn chẳng hạn.

0.5 * (1,1,1) = (0.5, 0.5, 0.5)

Lưu ý là nếu các phép toán làm các thành phần của vector vượt ra ngoài [0, 1] thì nó sẽ được tự đưa về giá trị 0 hoặc 1. Ví dụ (1, 0.1, 0.6) + (0.1, 0.5, 0.2) = (1.1, 0.6, 0.8) ta thấy có 1.1 > 1 nên nó sẽ được gán lại là 1.

Màu 128-bit

Ngoài 3 thành phần kể trên thì còn một thành phần khá phổ biến nữa đó là alpha. Thành phần này biểu thị cho độ trong suốt của màu sắc: 0 là trong suốt và 1 là không trong suốt. Thành phần này khá hữu ích trong việc blending sẽ được học ở phần sau. Ở đây ta không dùng nó nên sẽ được gán bằng 1.

Thêm thành phần alpha có nghĩa là chúng ta có thể đại diện cho một màu bằng một vector màu 4D (r, g, b, a) trong đó 0 ≤ r, g, b, a ≤ 1. Đại diện cho một màu sắc với 128 bit, chúng ta sử dụng kiểu float cho mỗi thành phần. Thư viện D3DX cung cấp các cấu trúc dưới đây, hoàn chỉnh với hàm nạp chồng hữu ích:


typedef struct D3DXCOLOR
{
#ifdef __cplusplus
public:
D3DXCOLOR() {};
D3DXCOLOR(UINT argb);
D3DXCOLOR(CONST FLOAT *);
D3DXCOLOR(CONST D3DXFLOAT16 *);
D3DXCOLOR(FLOAT r, FLOAT g, FLOAT b, FLOAT a);

// casting
operator UINT () const;

operator FLOAT* ();
operator CONST FLOAT* () const;

// assignment operators
D3DXCOLOR& operator += (CONST D3DXCOLOR&);
D3DXCOLOR& operator -= (CONST D3DXCOLOR&);
D3DXCOLOR& operator *= (FLOAT);
D3DXCOLOR& operator /= (FLOAT);

// unary operators
D3DXCOLOR operator + () const;
D3DXCOLOR operator - () const;

// binary operators
D3DXCOLOR operator + (CONST D3DXCOLOR&) const;
D3DXCOLOR operator - (CONST D3DXCOLOR&) const;
D3DXCOLOR operator * (FLOAT) const;
D3DXCOLOR operator / (FLOAT) const;

friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR&);

BOOL operator == (CONST D3DXCOLOR&) const;
BOOL operator != (CONST D3DXCOLOR&) const;

#endif //__cplusplus
FLOAT r, g, b, a;
} D3DXCOLOR, *LPD3DXCOLOR;

Đối với phép nhân từng thành phần. D3DX cung cấp hàm sau:


D3DXCOLOR* D3DXColorModulate(
D3DXCOLOR* pOut, // Returns (cr, cg, cb, ca) x (kr, kg, kb, ka)
CONST D3DXCOLOR* pC1, // (cr, cg, cb, ca)
CONST D3DXCOLOR* pC2 // (kr, kg, kb, ka)
);

Màu 32-bit

Để biễu diễn màu với 32 bit thì mỗi thành phần có một byte. Một byte có 256 giá trị. Như thế chúng ta có 3 byte RGB tổng cộng sẽ có 256*256*256 = 16,777,216 màu. Nhiêu đó màu sẽ đủ dùng cho chúng ta.

Một màu 32bit có thể được chuyển sang màu 128bit tức là đưa [0, 255] sang [0, 1]. Bằng việc chia cho 255. Nếu 0≤ n ≤ 255 thì 0≤ n/255 ≤ 1. Ví dụ ScreenShot_20160624152149.png

Mặt khác, một màu sắc 128-bit  có thể được chuyển đổi sang một màu 32-bit bằng cách nhân mỗi thành phần 255 và làm tròn đến số nguyên gần nhất. Ví dụ:

ScreenShot_20160624152149.png

Thông thường, 128-bit, giá trị màu được sử dụng khi nhiều thao tác tính toán trên màu sắc sẽ diễn ra (ví dụ, trong một pixel shader); theo cách này, chúng tôi có nhiều bit chính xác cho các tính toán nên lỗi số học không tích lũy quá nhiều. Các màu của điểm ảnh cuối cùng, tuy nhiên, thường được lưu trữ trong một giá trị màu 32-bit trong back buffer; thiết bị hiển thị vật lý hiện tại không thể tận dụng lợi thế của màu độ phân giải cao hơn.