------------------------------------------------------------------------------- Automatic Light System for POV-Ray ------------------------------------------------------------------------------- 1) INTRODUCTION Here is a set of macros and predefined constants to allow manipulating light sources for common luminaries, in a easy, automated way. This implementation does not tries to be an accurate or "physically correct" model of real luminaries, but a handy approximation with convincing and consistent results, by "muddling along" with some real data. 2) EXPLANATION Since I joined the povray.org newsgroups, I always followed with great interest the posts from Kari Kivisalo about realistic lighting. Some of his posts about realistic intensities and attenuations, and others about light spectrums have started some urgency on my mind to learn more about that subjects... that is: about the light itself. Of course, with no previous knowledge except lossy remembrances from the school, this was not an easy task. The information on the net about light is endless but very diffuse, and it's difficult to decide which information is correct and which not, where to start or what to learn the next, etc.. anyhow, I expend several months reading all kind of texts (light physics, photography basics, specs from manufacturers, realistic 3D lighting, etc..) and making annotations. Finally, I decided to put all my "conclusions" together, trying to make a decent and handy simulation for POV-Ray. These conclusions, which I used as assumptions for my macros, are the following: * First of all, light must follow the famous inverse square law. So, fade_power must be set to 2. The fade_distance is very difficult to understand for me, so I decided to have a very small one for my usual scene scale: 1 pov unit (1cm). Also, the formula on the POV-Ray manual seems to suggest to me this (don't ask exactly why, tough...). * Light color is really an spectrum, but for practical, non-scientific purposes, it can be averaged into a single rgb color, weighting several samples. A realistic relation between colors is more important than to have exact colors. For fine-tune I used a global variable to act as a "color correction filter". * Light intensity must be very high, specially which such low fade_distance. Again, the actual value is not that important, but to have realistic proportions between different, well known luminaries. So, I decided to use the "real" lumens value as light color multiplier. Also, the macro uses a global variable to increase/decrease "exposure" proportionally for all lights on the scene. * Film temperature is also something to take into account. I generalized it to the concept of "reference white", where a given temperature is used to balance the overall color of all the lights by simple arithmetic (which is surely wrong, but works fine). As this permits to take as "white" any given temperature, I decided to not implement a "color balancing filter" global variable, which seems unnecessary. All these assumptions were coded into a set of macros and predefined data to use together. On the scene, all the lights must be used trough the "light()" macro, and 3 control variables must be set prior to use it. The predefined values for spectrums, intensities and films can be used to feed the "light()" macro and the global variables with typical, well-known values. 3) EXAMPLE CODE This is only an example to illustrate the usage, not ready for rendering (see better the test scene on the zip): // lightsys includes #include "i_lights.inc" // light macro #include "i_spectra.inc" // spectrum sampling macros #include "i_light_const.inc" // useful constants // declare global control variables #declare REF_WHITE=ft_daylight; // daylight film #declare MAX_LUMENS=lm_incandescent_60w; // max intensity allowed #declare COLOR_FILTER=0; // no color correction // create a light_source for a typical 60 watt incandescent bulb #declare cl_incandescent=SpectrumToRGB(sp_incandescent_60w); #declare my_light=light(cl_incandescent,lm_incandescent_60w) light_source{my_light} On this example, "ft_daylight","lm_incandescent_60W" and "sp_incandescent_60w" are actual predefined constants from "i_light_const.inc", which contains several constants based on (or converted from) data found on the net (photography sites, lighting manufacturers, scientific papers, etc...). The macro "SpectrumToRGB()" is used to obtain the weighted rgb value for a given array of spectral samples, and then "light()" is called to create the proper light_source. The example call to the "ligth()" macro is simplified to only the two relevant parameters for this explanation, altought it has some other parameters to control other light_source features, as area_light or spotlight (with Kari cosine falloff trick support), since you cannot add these keywords latter to the returned object. See the code for more details. 4) EXAMPLE IMAGES Please visit http://www.ignorancia.org/lightsys for some example images. 5) TO-DO There are several thing to improve or add, appart from correcting possible (and probable) mistakes: * Add support for all the light_source keywords * Search for more spectral distributions to sample (sort of library). Comments and criticism are as usual welcome (specially from lighting engineers!). ------------------------------------------------------------------------------- Jaime Vives Piqueres, Jan-2002.