Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!sri-spam!ames!ucbcad!ucbvax!onfcanim.UUCP!dave From: dave@onfcanim.UUCP.UUCP Newsgroups: mod.computers.workstations Subject: Re: Graphics on SUN's; SUN tape drive operations Message-ID: <15261@onfcanim.UUCP> Date: Sun, 29-Mar-87 19:01:41 EST Article-I.D.: onfcanim.15261 Posted: Sun Mar 29 19:01:41 1987 Date-Received: Sat, 4-Apr-87 09:18:06 EST References: <14@auscso.UUCP> <8703252224.AA09472@tcgould.TN.CORNELL.EDU> <132@brandx.klinzhai.RUTGERS.EDU> Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: onfcanim!dave (Dave Martindale) Distribution: world Organization: National Film Board / Office national du film, Montreal Lines: 119 Keywords: Choosing 256 colors Approved: works@red.rutgers.edu In article <132@brandx.klinzhai.RUTGERS.EDU>, webber@KLINZHAI.RUTGERS.EDU (Webber) writes: > In article <8703252224.AA09472@tcgould.TN.CORNELL.EDU>, > cheryl@TCGOULD.TN.CORNELL.EDU (cheryl) writes: >> The 255 different levels are 255 settings on the VOLTAGES of each >> of the 3 color guns. It is a well-known principle of computer >> graphics that there is a nonlinear relationship between these >> these voltage settings and the actual intensities that are >> displayed on the screen. In fact, it is an exponential >> relationship. Standard nomenclature refers to the factor in this >> exponential relationship as GAMMA, hence the phrase "GAMMA >> correction." Since the gamma correction necessary varies from >> monitor to monitor, most manufacturers of graphics hardware leave >> it up to the on-site computer graphics wiz to do the gamma >> correction herself -- or himself as the case may be. > > The nonlinear relationship between the voltage and light energy > emitted by the phosphors is indeed GAMMA, but this is not an > exponential relation. It is a low order polynomial, roughly x to > the 2.2 (on average maxing around x to the 2.8 for some monitors). > > There is an exponential relationship between light energy and the > neuropsychological perception of brightness, but that is another > matter (i.e., you would percieve x, 1.02 * x, 1.02 * 1.02 * x, 1.02 > * 1.02 * 1.02 * x, etc. as a linear progression in brightness > although x is light energy). > > Thus GAMMA correction is a monitor hardware internal problem > whereas the exponential intensity perception is a > psychoneurological phenomenon. > > Although there are doubtless many technical references on this > material, a good introduction to this sort of thing is: Bob Webber points out that the relationship between screen intensity and video signal voltage for a CRT is really a polynomial, not exponential as Cheryl said. He's technically correct, but Cheryl's description is basically right. Writing it down as a formula, gamma screen_luminance = (signal_voltage) where '=' really means "is proportional to". Perhaps this should be called a "power law" relationship, since "exponential" isn't correct. The value of "gamma" varies with the monitor. Also, note that this is only an approximation - the response of a real monitor is more complex. This non-linearity of the monitor is usually corrected for by loading the frame buffer's colour lookup table with a table that generates the correct signal voltage for each possible pixel value. Making use of the approximation above, for a pixel intensity I in the range [0..1], and a video DAC whose inputs are in the range [0..DACMAX], the DAC input (and thus lookup table entry) should be table_entry = round_to_int(DACMAX * I ** (1/gamma)) This is referred to as "gamma correction". This ensures that the intensity of light coming off the phosphor is proportional to the intensity that you calculated for that pixel (except for errors in the "gamma" model of CRT behaviour). However, none of this really addresses the original question, which was (paraphrasing) "how do you select a representative set of intensities for each colour?". The most common method of having pixel values represent intensities in a frame buffer with 8 bits per pixel per colour is to have a pixel value of P represent an intensity of P/255. This produces the cheapest pixel encoding to calculate, but it is not the best use of the bits. The visual system responds to the ratios of brightnesses between areas, not the absolute difference - it is effectively a logarithmic measuring device. If you display a set of equal-sized objects with luminances of 1, 2, 4, 8, 16, 32, and 64 foot-Lamberts, you eye will perceive equal brightness changes between each patch. Thus, to make the best use of a small number of bits per pixel, the available pixel values should be spaced evenly in perceptual brightness, which means that the pixel codes should be the logarithm of intensity, scaled appropriately and rounded to an integer. For example, if you have 8 bits per pixel (per colour), and want to encode an intensity range of [0.01, 1], the pixel value is given by P = round_to_int(255 * (1.0 - log(I) / log(0.01))) It doesn't matter whether "log" is base-10 or base-e. Note that you have to decide in advance how much intensity range you want to encode, and that intensities below this range produce negative pixel values that you have to clamp to 0. As long as the number of DAC bits is about 2 or more greater than the number of pixel bits, log encoding is the "optimum" method of encoding intensity in pixel values. When you only have 8 bits per pixel for all colours, you have to divide them carefully. The simplest method is to use 3 bits for each of red and green, and 2 bits for blue (since blue does not appear as bright to the eye as red or green, it contributes less to overall perceived brightness). Thus you get 8 distinct values of red and green, and 4 of blue. Intensities are converted to pixel bits using the formula above (with 255 replaced by 7 or 3) and then shifted and ORed together. An alternative that provides more equal resolution in all colours is to encode red and blue as integers in the range [0-5] and green in the range [0-6]. Since 6*7*6 < 255, this will work. The pixel value is encoded by multiplying: P = (R*7 + G)*6 + B Using 7,7,5 instead of 6,7,6 will also work. Whatever way the pixels are encoded, the decoding is done by the colour lookup table. For each entry in the table, calculate the red, green, and blue intensities represented by that particular pixel code taking into account the way they were encoded (linear or logarithmic) and packed (shifts or multiplies). Then calculate the DAC input needed for each of the RGB intensities using the gamma correction formula above, and you have your colour table entry.