|
Important notice: The radiosity features in POV-Ray are somewhat experimental. There is a high probability that the design and implementation of these features will be changed in future versions. We cannot guarantee that scenes using these features in this version will render identically in future releases or that full backwards compatibility of language syntax can be maintained.
Radiosity is an extra calculation that more realistically computes the diffuse interreflection of light. This diffuse interreflection can be seen if you place a white chair in a room full of blue carpet, blue walls and blue curtains. The chair will pick up a blue tint from light reflecting off of other parts of the room. Also notice that the shadowed areas of your surroundings are not totally dark even if no light source shines directly on the surface. Diffuse light reflecting off of other objects fills in the shadows. Typically ray-tracing uses a trick called ambient light to simulate such effects but it is not very accurate.
Radiosity calculations are only made when a radiosity{}
block is used
inside the global_settings{}
block.
The following sections describes how radiosity works, how to control it with various global settings and tips on trading quality vs. speed.
The problem of ray-tracing is to figure out what the light level is at each point that you can see in a scene. Traditionally, in ray tracing, this is broken into the sum of these components:
POV-Ray's radiosity system, based on a method by Greg Ward, provides a way to replace the last term - the constant ambient light value - with a light level which is based on what surfaces are nearby and how bright in turn they are.
The first thing you might notice about this definition is that it is
circular: the brightness and color of everything is dependent on everything else and vice
versa. This is true in real life but in the world of ray-tracing, we can make
an approximation. The approximation that is used is: the objects you are
looking at have their ambient
values calculated for you by
checking the other objects nearby. When those objects are checked during this
process, however, their diffuse
term is used. The brightness of
radiosity in POV-Ray is based on two things:
ambient_light
to 0 in
global_settings
, or use ambient 0
in each object's finish.
This lighting model is much more realistic, and POV-Ray will not try to adjust the
overall brightness of the radiosity to match the ambient level specified by the user.How does POV-Ray calculate the ambient term for each point? By sending out more rays, in many different directions, and averaging the results. A typical point might use 200 or more rays to calculate its ambient light level correctly.
Now this sounds like it would make the ray-tracer 200 times slower. This is true, except that the software takes advantage of the fact that ambient light levels change quite slowly (remember, shadows are calculated separately, so sharp shadow edges are not a problem). Therefore, these extra rays are sent out only once in a while (about 1 time in 50), then these calculated values are saved and reused for nearby pixels in the image when possible.
This process of saving and reusing values is what causes the need for a variety of tuning parameters, so you can get the scene to look just the way you want.
As described earlier, radiosity is turned on by using the radiosity{}
block
in global_setting
.
Radiosity has many parameters that are specified as follows:
global_settings { radiosity { [RADIOSITY_ITEMS...] } } RADIOSITY_ITEMS: adc_bailout Float | always_sample Bool | brightness Float | count Integer | error_bound Float | gray_threshold Float | load_file Filename | low_error_factor Float | max_sample Float | media Bool | minimum_reuse Float | nearest_count Integer | normal Bool | pretrace_end Float | pretrace_start Float | recursion_limit Integer | save_file Filename
Each item is optional and may appear in any order. If an item is specified more than once the last setting overrides previous values. Details on each item is given in the following sections.
Note: Considerable changes have been made to the way radiosity works in POV-Ray 3.5
compared to POV-Ray 3.1. Old scene will not render to the same result, if they render at all.
It is not possible to use the #version
directive to get backward compatibility for
radiosity.
You can specify an adc_bailout for radiosity rays.
Use adc_bailout = 0.01 / brightest_ambient_object
for good results.
Default is 0.01.
You can force POV-Ray to only use the data from the pretrace step and not gather
any new samples during the final radiosity pass. This may reduce splotchiness.
To do this, use always_sample off
, by default it is on
.
It can also be usefull when reusing previously saved radiosity data.
The brightness
keyword specifies a float value that is the
degree to which objects are brightened before being returned upwards
to the rest of the system. The default value is 1.0. In cases where you would raise the
global_settings{ambient_light value}
to increase the over all brightness
in a non-radiosity scene, you can use brightness
in a radiosity scene.
The integer number of rays that are sent out whenever a new radiosity
value has to be calculated is given by count
.
A value of 35 is the default, the maximum is 1600.
When this value is too low, the light level will tend to look a little bit
blotchy, as if the surfaces you're looking at were slightly warped. If
this is not important to your scene (as in the case that you have a bump map
or if you have a strong texture) then by all means use a lower number.
The error_bound
float value is one of the two main speed/quality tuning values (the other
is of course the number of rays shot). In an ideal world, this would be
the only
value needed. It is intended to mean the fraction of
error tolerated. For example, if it were set to 1 the algorithm would not
calculate a new value until the error on the last one was estimated at as
high as 100%. Ignoring the error introduced by rotation for the moment, on
flat surfaces this is equal to the fraction of the reuse distance, which
in turn is the distance to the closest item hit. If you have an old sample
on the floor 10 inches from a wall, an error bound of 0.5 will get you a
new sample at a distance of about 5 inches from the wall.
The default value of 1.8 is good for a smooth general lighting effect.
Using lower values is more accurate, but it will strongly increase the
danger of artifacts and therefore require higher count
. You
can use values even lower than 0.1 but both render time and memory use can
become extremely high then.
Diffusely interreflected light is a function of the objects around the
point in question. Since this is recursively defined to millions of levels of
recursion, in any real life scene, every point is illuminated at least in
part by every other part of the scene. Since we can't afford to compute
this, if we only do one bounce, the calculated ambient light is very strongly
affected by the colors of the objects near it. This is known as color bleed
and it really happens but not as much as this calculation method would have
you believe. The gray_threshold
float value grays it down a
little, to make your scene more believable. A value of .6 means to calculate
the ambient value as 60% of the equivalent gray value calculated, plus 40% of
the actual value calculated. At 0%, this feature does nothing. At 100%, you
always get white/gray ambient light, with no hue.
Note: this does not change the lightness/darkness, only the strength of hue/grayness (in HLS terms, it changes S only). The default value is 0.0
If you calculate just enough samples, but no more, you will get an image
which has slightly blotchy lighting. What you want is just a few extra
interspersed, so that the blending will be nice and smooth. The solution to
this is the mosaic preview, controled by
pretrace
:
it goes over the image one or more times
beforehand, calculating radiosity values. To ensure that you get a few extra,
the radiosity algorithm lowers the error bound during the pre-final passes,
then sets it back just before the final pass. The
low_error_factor
is a float tuning value which sets the amount that
the error bound is dropped during the preliminary image passes. If your low
error factor is 0.8 and your error bound is set to 0.4 it will really use an
error bound of 0.32 during the first passes and 0.4 on the final pass. The
default value is 0.5.
Sometimes there can be problems with splotchiness that is caused by objects
that are very bright. This can be sometimes avoided by using the max_sample
keyword. max_sample
takes a float parameter which specifies the brightest
that any gathered sample is allowed to be. Any samples brighter than this will have their
brightness decreased (without affecting color). Specifying a non-positive value for max_sample
will allow any brightness of samples (which is the default).
Radiosity estimation can be affected by media.
To enable this feature, add media on
to the radiosity{}
block.
The default is off
The minimum effective radius ratio is set by minimum_reuse
float value. This is the fraction of the screen width which sets the minimum
radius of reuse for each sample point (actually, it is the fraction of the
distance from the eye but the two are roughly equal). For example, if the
value is 0.02, the radius of maximum reuse for every sample is set to whatever
ground distance corresponds to 2% of the width of the screen. Imagine you
sent a ray off to the horizon and it hits the ground at a distance of 100
miles from your eye point. The reuse distance for that sample will be set to
2 miles. At a resolution of 300*400 this will correspond to (very roughly) 8
pixels. The theory is that you don't want to calculate values for every
pixel into every crevice everywhere in the scene, it will take too long. This
sets a minimum bound for the reuse. If this value is too low, (which it
should be in theory) rendering gets slow, and inside corners can get a little
grainy. If it is set too high, you don't get the natural darkening of
illumination near inside edges, since it reuses. At values higher than 2% you
start getting more just plain errors, like reusing the illumination of the
open table underneath the apple. Remember that this is a unit less ratio. The
default value is 0.015.
The nearest_count
integer value is the minimum number of old
ambient values blended together to create a new interpolated value. The total
number blended will vary depending on error_bound
. All previous
values that fit within the specified error_bound will be used in the average.
It will always be the n geometrically closest reusable points that get used. If you go lower than 4, things can get pretty patchy. This can be good for debugging, though. Must be no more than 20, since that is the size of the array allocated. The default value is 5.
Radiosity estimation can be affected by normals.
To enable this feature, add normal on
to the radiosity{}
block.
The default is off
To control the radiosity pre-trace gathering step, use the keywords pretrace_start
and pretrace_end
within the radiosity{}
block.
Each of these is followed by a decimal value between 0.0 and 1.0 which specifies the size of the
blocks in the mosaic preview as a percentage of the image size. The defaults are 0.08 for pretrace_start
and 0.04 for pretrace_end
The recursion_limit
is an integer value which determines how
many recursion levels are used to calculate the diffuse inter-reflection.
The default value is 3, the upper limit is 20.
You can save the radiosity data using save_file "file_name"
and
load the same data later using load_file "file_name"
. In general,
it is not a good idea to save and load radiosity data if scene objects are moving.
Even if data are loaded, more samples may be taken during rendering (which produces
a better approximation). You can disable samples from being taken during the final
rendering phase by specifying always_sample off
.
Have a look at the "Radiosity Tutorial" in the "Advanced Tutorial" section, to get a feel for what the visual result of changing radiosity parameters is.
If you want to see where your values are being calculated set radiosity
count
down to about 20, set radiosity
nearest_count
to 1 and set gray_threshold
to 0. This will
make everything maximally patchy, so you'll be able to see the borders
between patches. There will have been a radiosity calculation at the center
of most patches. As a bonus, this is quick to run. You can then change the
error_bound
up and down to see how it changes things. Likewise
modify minimum_reuse
.
One way to get extra smooth results: crank up the sample count (we've
gone as high as 1300) and drop the low_error_factor
to
something small like 0.6. Bump up the nearest_count
to 7 or 8.
This will get better values, and more of them, then interpolate among more of
them on the last pass. This is not for people with a lack of patience since
it is like a squared function. If your blotchiness is only in certain corners
or near certain objects try tuning the error bound instead. Never drop it by
more than a little at a time, since the run time will get very long.
Sometimes extra samples are taken during the final rendering pass. These newer samples can cause discontinuities in the radiosity in some scenes. To decrease these artefacts, use a pretrace_end of 0.04 (or even 0.02 if you're really patient and picky). This will cause the majority of the samples to be taken during the preview passes, and decrease the artefacts created during the final rendering pass. You can force POV-Ray to only use the data from the pretrace step and not gather any new samples during the final radiosity pass. To do this, use "always_sample no" within the radiosity block inside global_settings.
If your scene uses ambient objects (especially small ambient objects) as light sources, you should probably use a higher count (100-150 and higher). For such scenes, an error_bound of 1.0 is usually good. Higher causes too much error, but lower causes very slow rendering. And it's important to adapt adc_bailout.
|