CS465 Fall 2006 Homework 1 Solution ------------------- 1. 1680 x 1050 x 3 x 8 bytes = 40.4 MB 2. 1680 x 1050 x 3 x 1 byte = 5.05 MB for (a) and (b) 1680 x 1050 x 3 x 2 bytes = 10.1 MB for (c) 3. 1680 x 1050 x 3 x 8 bits x 60 frames/sec = 2.37 Gb/sec 4a. fbPixel[i] = round(min(255, max(0, 255 * imgPixel[i]))) 4b. fbPixel[i] = round(min(255, max(0, 255 * pow(imgPixel[i], 0.45)))) 4c. fbPixel[i] = round(min(65535, max(0, 65535 * imgPixel[i]))) 5a. 0, 21, 28, 34, 39 5b. 0, 1, 2, 3, 4 5c. 0, 2, 2, 3, 3 6a. first 4 steps: 41%; 26%; 23%; 19% 6b. first 4 steps: .05%; .2%; .3%; .5% 6c. first 4 steps: .2%; 0 ; .3%; 0 All steps are visible for (a). All steps are invisible for (b) and (c). 7. It would look too dark. ---- The morals of the story: - Pixel format (a) is not a good plan; it will lead to very visible bands in the dark tones. - Gamma can be considered a memory and bandwidth saving trick, since we can use 8 bits with gamma quantization where we need 16 bits if we use linear quantization. ---- 4: For (a) and (c) We just need to scale the range [0,1] to the range [0,N]. For (b) we apply gamma correction, since the framebuffer is supposed to contain gamma-quantized values. In all cases we clip values that are too high or too low to the maximum or minimum allowable pixel value. 5b: We are storing gamma-quantized values, and the monitor expects gamma-quantized values, so the LUT should do nothing. 5a and 5c: You can get very close to the right answer (and to the full score) with a simple computation. Expressed in C/Java syntax: 5a: lut[k] = round(255 * pow(k / 255, 0.45)) 5b: lut[k] = round(255 * pow(k / 65535, 0.45)) or, equivalently, by the MATLAB expressions: round(255 * ((0:4) / 255).^0.45) round(255 * ((0:4) / 65535).^0.45) but this doesn't quite guarantee you have the best approximation to the desired luminance level -- instead you have the pixel value closest to the fractional pixel value that would give the desired luminance level. I didn't really expect many students to catch this subtlety. To get this last point, you could compute all the displayable luminances and explicitly find the closest one to each desired luminance, for instance by using the MATLAB code: disp = ([0:255]/255).^2.2; for k = 0:4, [y,i] = min(abs(disp-k/255)); i-1, end for k = 0:4, [y,i] = min(abs(disp-k/65535)); i-1, end 6: Once you have the answer to 5, 6 follows simply by mapping the contents of the LUT through the monitor's transfer function. The ouput (with flare) for pixel value k is: output_k = ((lut[k] / 255)^2.2 + 0.01) * I_max and the answers are output_k / output_(k-1) for k = 1,2,3,4, expressed as percentages. I computed the answer in MATLAB this way: v = [0, 21, 28, 34, 39 0, 1, 2, 3, 4 0, 2, 2, 3, 3]; d = 0.01 + (v/255).^2.2; d(:,2:5) ./ d(:,1:4) Piti's addition: application: 0:1 0:1 0:1 framebuffer: 255*(0:1) 255*(0:1).^0.45 65535*(0:1) lookup table entries: round(255 * ((0:255) / 255).^0.45) 0:255 round(255 * ((0:255) / 65535).^0.45) observed intensities: 0.01 + ((0:255)/255).^2.2 0.01 + ((0:255)/255).^2.2 0.01 + ((0:255)/255).^2.2