POV-Ray : Newsgroups : povray.general : Possible solution for speeding up Povray's radiosity? : Possible solution for speeding up Povray's radiosity? Server Time
11 Aug 2024 15:16:30 EDT (-0400)
  Possible solution for speeding up Povray's radiosity?  
From: Equiprawn
Date: 30 Jun 1999 14:06:10
Message: <377a5c92@news.povray.org>
Hi,

I've just thought of a way of calculating radiosity that in my mind should
be able to speed up Povray's radiosity pass greatly. Now, I'm no programmer
or expert in this field, so Povray may already calculate radiosity in this
way, or there could be something that I'm not seeing that would greatly slow
down the process, so please bear with me. To help explain the stuff below, I
have mocked up some images in a graphics package, and posted them to
povray.binaries.images in the message "Faster radiosity images (don't get
excited)". Below, I will also be talking about frame rates. I am not talking
about generating Povray images with radiosity at faster than 1 a second! I
will be talking about vector graphics, much like many of the arcade machines
in the early 80s produced. Don't worry, this is still relevant to Povray - I
will be transferring the process below in different ways until I reach
Povray.

Before I get flames over this, read the WHOLE post carefully. First I am
going to describe how I think Povray calculates radiosity, and then I will
build on it to describe what I feel would be a faster and more efficient
system.

For a minute just imagine a 2D vector line world. You have a point that
emits light, three vector line surfaces, and a non-physical line along which
you are going to calculate final radiosity values. (step01.jpg)

Now imagine that our light source emits a single vector line ray of light.
(step02.jpg)

Where this ray of light hits the red vector line, a normal to the red
surface is calculated. Because our original light colour was rgb <1.0, 1.0,
1.0>, and the red surface has a Colour_change property of 0.4, a new light
beam is calculated that had a colour of rgb <1.0, 0.6, 0.6> (i.e. 40% of the
change from rgb <1.0, 1.0, 1.0> to rgb <1.0, 0.6, 0.6>). This new beam
travels away from the red surface at the same angle as the original beam
was, relative to the red surface. The new beam strikes the green
surface.(step03.jpg)

A new normal is calculated, and for similar reasons as above, a new beam
leaves the green surface with a colour of rgb <0.8, 0.678, 0.12>. The new
beam hits the blue surface. (step 4.jpg)

Again a normal is calculated, and a new beam is shot, with a colour of rgb
<0.4, 0.624, 0.561>. Where this beam crosses our final calculation field,
the radiosity colour at that point is displayed. (step05.jpg)

(If my colour calculations as above were a little dodgy, it's because I was
using a graphics package that uses numbers between 0 and 255 to represent
colours, which doesn't translate too well to Povray's 0 to 1 system)

Now, because of the speed of modern computers, I can imagine that such
calculations with 2D vector lines can be done very quickly, giving a few
frames a second of such radiosity calculations, should our line surfaces be
rotating or moving. The reason that our colours stayed relatively bright was
because our light source brightness didn't fade over distance. Such a
darkening of the lines shouldn't slow down the calculation process too much.

Now imagine the same vector setup as above, except in 3D. Instead of line
surfaces, we have three coloured vector rectangles, that can be rotated and
moved in any of the three dimensions. Now, while there should be a hit in
the frame rate at this point as calculating normals in three dimensions is
more complicated that calculating them in two (I'm sure, though I don't know
for certain. Any programmers out there back me up on this one?), I would
still think that a few frames a second could be managed.

Now imagine that our 3D light source shoots out two rays, in slightly
different directions. They each bounce in different ways, depending on what
surfaces they hit or miss. Eventually, they hit our final calculation field,
which is now a rectangle. We now have two different points of two (probably)
different colours. A stripe of interpolated colours fading between our two
colour spots could be drawn.

If four rays are shot from the light source, we end up with four points on
our final calculation field. Interpolating the colours between them gives us
a four sided shape of colour, which is the start of our radiosity system.
However, with each new ray shot from the light source, the whole process
slows dramatically, until eventually, for a complex scene, the radiosity
calculations alone for three light bounces like we have above could take
over half an hour or more! This is, as far as I know, more or less how
Povray operates. If it isn't, would this not be a much better way to
calculate radiosity? It certainly seems like it would be faster to me, for
simple scenes anyway. If that is however how Povray calculates radiosity,
keep reading.

What I propose as a change to this system is the following: instead of
having one count variable that sets how many radiosity samples are
calculated per light, why not let each object have a count variable, and not
let lights have one?

The main problem with giving light sources a count variable, is that in many
scenes, a lot of time is spent calculating radiosity samples that are
wasted; either because the light beam shoots off to somewhere where its
effects will never be seen, or because the object is too small or only
partially in the light. All these useless samples all increase the time it
takes for radiosity to calculate and to trace.

Now, trying to Program Povray with some intelligence as to what to bother
calculating radiosity for, and how high a count to give each object would be
very difficult I imagine. Artificial intelligence today is still pretty new
stuff, especially artistic artificial intelligence :) . It would also lead
to problems with Povray making decisions about the radiosity that the person
making the scene wouldn't agree with.

But by letting the Pov user have control themselves over what count each
object should have, greater artistic control is given to the user, while at
the same time decreasing the amount of time the render takes.

Here is how I envision the system would work. There is a light source, a
sphere and a simple closed, square room. The sphere has a count of 100. The
walls of the room have a count of 50. If the light does not hit the sphere,
then only radiosity for the walls is calculated. This is calculated by
determining what portions of the walls are in the light. Then, 50 points
spread out evenly over the surface of the walls are chosen, and using
normals determined from the angle of the original light, new beams are shot
much like the ones in my 3D vector example above. When these beams hit
objects, radiosity points are found, and a radiosity map is interpolated. If
the sphere is also hit by the light, then 100 points on the surface of the
sphere where it is hit by light are selected (probably also evenly
distributed), and normals and new beams shot also.

Each object could also be given a number_of_bounces variable, that would set
the number of light bounces off the object that would be calculated. If for
example the sphere had a number_of_bounces 2, this would mean that two
generations of radiosity would be allowed to be calculated on its surface,
but no more than that. This could give greater control to the Povray user,
as they could give faraway objects a low number_of_bounces, while giving
closer objects a higher number_of_bounces.

Indeed, faraway objects such as distant trees could be given a count of
zero, meaning that they wouldn't cause radiosity to calculated in the scene
because of them. As standard Povray would calculate this, and it would have
very little effect on the final image anyway, this would be a great time
saver.

One point I can see being raised against this new radiosity system is that
it would remove the possibility of using high ambient objects in a lightless
environment as a light source. For this reason, I propose adding another
variable, ambient_count. This would act much like the per-object radiosity
count as above, except the ambient_count would shoot rays from the entire
surface of the object. The brightness and colour of these rays would depend
on the colour and ambient value of the object at the point where each ray
was calculated. Indeed, this system would have a further use, as the
ambient_count would act like a new type of light source, giving a light that
would depend on the shape of the object. This would make true area_lights
from spheres, cylinders, blobs, meshes etc. possible. I have seen a lot of
requests for this feature posted on the various newsgroups at different
times in the last few years.

Another point I can see being raised is that this new radiosity system is
much more complicated than the old system, and would only end up confusing
people. To that, all I can suggest is that the old radiosity system should
be kept, with this new system implemented *as well*, giving people the
chance to decide which system to use.

I don't profess to have thought of all eventualities. I am sure there are
lots of problems with this system that I have not thought of. But maybe if
we discuss this system, we could work out enough of the problems to begin
designing a working version of the system. Possibly somebody out there who
has experience with creating Povray patches could start experimenting to see
if any of this would be possible. I know that Mr. Nathan Kopp was looking at
the radiosity system when he was working on his excellent Photon Patch. I
also know that in the Povray SuperPatch, there is a feature that allows ray
intersection tests, a feature that would be very important in the above
proposed radiosity system.


I look forward to comments and suggestions.


Yours hopefully,

Equiprawn


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.