The human eye has 3 receptors sensitive to color rho receptors (red) - long wavelengths gamma receptors (green) - medium wavelengths beta receptors (blue) - short wavelengths LED and OLED displays use linear combinations of red,green,blue wavelengths alpha_rho * rho + alpha_gamma*gamma + alpha_beta * beta Because a linear combination of wavelengths are used, there are colors you can't display with a LCD/OLED that we can see in real life. Definition: lumina (also called the luma) - the brightness or achromatic part of an RGB image Accounting for sensitivity of rho, gamma, and beta receptors, the lumina is computed as lumina = 0.2126*R + 0.7152*G + 0.0722*B If R,G,B values are gamma corrected, so is the lumina An increase in brightness implies that you are scaling each channel by some scalar alpha To increase/decrease the contrast in an image, there are 3 steps 1. compute the average luma - call it L* 2. for each pixel, compute: beta_i = L_i - L* // L_i is the luma at one specific pixel 3. scale each channel R_i, G_i, B_i R_i = alpha * beta_i * R_i G_i = alpha * beta_i * G_i B_i = alpha * beta_i * B_i HDR images - High Dynamic Range LDR images - Low Dynamic Range HDR Range Sensors 1) combine photos taken at multiple exposures (many algorithms) 2) CCD sensors on the camera measure and returns light directly at high dynamic range 3) during rendering, use the same model for light raytracing or rasterization - more realistic light and dark regions - light bloom - feathers of light extending from bright regions Definition: Tone Mapping - the process of converting HDR images to LDR images HDR images have floating point values [0,infinity) LDR images have 8-bit values [0,255] * There are many way to do this, including per-pixel approaches One popular tone mapping algorithm was created by Erik Reinhard (SIGGRAPH 2002) input parameter key value "a" scale to key value - analagous to setting exposure - a=0.18 - 0.36 (a can very from 0-1) for each pixel: calculate the pixel luma by the formula L_I = 0.2126*R + 0.7152*G + 0.0722*B compute the log average by L_avg = exp[ 1/N * sum_{xy}( log(delta + L_I(x,y) )) ] where delta=0.00001 and L_I(x,y)=pixel luma Scale each luma as follows L*(x,y) = (a / L_avg) * L(x,y) where "a" is the input paramter key value Now get the max luma L_max = max_{xy}(L*(x,y)) L'(x,y) = \frac{ L*(x,y) * (1+ L*(x,y)/L_max^2 )}{ 1 + L*(x,y) } Let alpha = L' / L_I(x,y) where L_I(x,y) is the original luma pixel value Then scale the channels R' = alpha * R G' = alpha * G B' = alpha * B The last step is to adjust for gamma correction R' = R^(1/gamma) G' = G^(1/gamma) B' = B^(1/gamma) and clamp R', G', and B' to be between [0,1] R' = clamp(0,1) G' = clamp(0,1) B' = clamp(0,1)