 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
(A)
For all of you out there waiting for radiosity to get fixed, a short status
report:
Let me put it this way - let's be happy that radiosity does *something* in the
beta at all :) There's a hell lot of work to do, as the code has been
"amputated" in many places, obviously to get the other code to compile at all.
So it's basically a re-integration job.
(B)
I think I have an idea how to use SMP to speed up radiosity pretrace as well,
without too much modification to the existing architecture.
Obviously, the problem with thread synchronization during radiosity pretrace is
that the sample octree needs to be accessed from multiple threads. The worst
case scenario is that multiple threads might find it necessary to build a new
root at the same time.
However, tasks traversing the tree in search for samples, while another is
actually updating the tree, should not be a problem, if tree modification is
performed carefully.
Competing writes to the same sample tree node can be avoided, if instead of
using a single linked list of sample blocks each node contains as many such
lists as there are threads. The overhead for retrieving blocks should be
insignificant.
Competing writes to the tree hierarchy can be avoided - without all-too-frequent
messing with locks - as follows:
- Each thread keeps a small private list of samples it wasn't able to hook in
yet, because the corresponding nodes didn't exist yet and fast tree
modifications would have been too unsafe.
- Whenever a thread's private sample list reaches a certain size, it attempts to
lock the sample tree; however, if it doesn't get the lock immediately it just
continues to do its job, and retries when its private list of samples has
increased by another certaing amount.
- If the thread does acquire a lock on the tree, it hooks in the samples it has
accumulated by now, then releases the lock and resumes tracing.
This way the threads will not block if they need to do a modification.
A few more considerations regarding this idea:
- Deadlocks are not possible, because if threads can't acquire the lock they
will just do something else.
- Livelocks are unlikely, because the time until a certain number of samples in
non-existing nodes has been taken will have significant jitter.
- Starvation of a single thread is unlikely for similar reasons; plus, it can be
further reduced by having a task try for a lock more frequently the longer its
list of un-hooked samples gets.
- The list of un-hooked samples could include a reference to the node below
which a new sub-tree is needed, to speed up the actual tree modification.
- If a thread cannot acquire a lock, it can still check its list of un-hooked
samples to see if another thread has already built the required nodes by now.
- Separate locks could be used for "root growth" and "leaf growth", as building
a new root will not interfere with the rest of the tree.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Competing writes to the tree hierarchy can be avoided - without all-too-frequent
> messing with locks - as follows:
Please note that finding a locking algorithm is not the problem. The issue
at hand is significantly more complex: The heuristic deciding to reuse a
sample or take a new sample simply breaks with multiple threads because it
depends on the order threads retrieve samples and decide to add samples.
This order in turn will lead to similar, but yet different trees each time
the same scene is rendered because thread execution order is never
predictable, let along controllable. As such, the image will look different
unless very high sample qualities are used.
The solution here is either to only pretrace (single threaded then), order
sample insertion (only feasible in a multithreaded pretrace), or come up
with some other division of the tree avoiding insertion data race conditions.
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> The solution here is either to only pretrace (single threaded then), order
> sample insertion (only feasible in a multithreaded pretrace), or come up
> with some other division of the tree avoiding insertion data race conditions.
Also note that since the radiosity data tree is probably accessed millions
of times per second (for both reading and writing), mutexing each access would
be prohibitively slow, as mutexes (especially those provided by Boost) are
very inefficient. Mutexes are only feasible for functions which are called
relatively infrequently.
(If a function would otherwise be very fast, eg. take just a few dozens
of clock cycles, adding a mutex lock to it can make it hundreds of times
slower at worst. If the function in question is called very frequently,
eg. millions of times per second, that can have a catastrophical effect
on performance.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> Also note that since the radiosity data tree is probably accessed millions
> of times per second (for both reading and writing), mutexing each access would
> be prohibitively slow, as mutexes (especially those provided by Boost) are
> very inefficient. Mutexes are only feasible for functions which are called
> relatively infrequently.
Of this issue I was aware, which is why I suggested to basically cache some
intended tree writes before paying the cost of locking.
If 100% reproducability of shots is an issue though, another approach is indeed
needed.
(BTW, why is Boost used if it is so slow?)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> -----Original Message-----
> From: clipka [mailto:nomail@nomail]
> (BTW, why is Boost used if it is so slow?)
Boost isn't slow. Mutexing is slow (relatively). Using mutexes adds
some few dozen cycles to a function's run time, meaning that for rather
fast functions (which are only a few dozen cycles, or even less) it can
reduce speed dramatically.
Of course, if you're looking at functions that typically take hundreds
or thousands of cycles to complete, the cost of using mutexes is
trivial.
...Ben Chambers
www.pacificwebguy.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> The solution here is either to only pretrace (single threaded then), order
> sample insertion (only feasible in a multithreaded pretrace), or come up
> with some other division of the tree avoiding insertion data race conditions.
If 100% reproducability of output is an issue, then other divisions of the tree
will not help either.
Presuming that having more samples than actually required is not an issue, then
how about this one:
On each pretrace pass (and likewise in the main render), subdivide the image
into some tiles of standard size. Have each of these tiles processed
separately, with its own copy of the radiosity sample tree (or, rather, with
read access to the already existing tree, plus another tree to store new
samples in). At the end of each pretrace, have a single task merge the forests
together to one new tree.
If having a too many samples would be an issue, the same approach could still
work, provided that the merging task would check again for redundancy of
samples.
I'm also thinking about totally different approaches, although I can't see yet
how they could be put to good use. One basic idea would be to have a single
main pretracer thread that would find out what samples are needed, and have
other threads actually collect them.
One way this could be done would be as follows:
- A single thread takes care of the pretrace, doing all the things needed -
except for actually taking samples.
- Instead, whenever it decides that a new sample is needed, it inserts a sample
block into the tree, marks it as "incomplete", and enqueues it in a special
queue. It then takes a fantasy value instead, and goes on minding its own
business. The picture will look crazy, but it's a pretrace after all, so no
need for beauty.
- Some other task polls the queue, and does the actual sample-collecting,
shooting rays as usual. It will probably need samples from a deeper "radiosity
bounce" level, too - in that case it will not collect those itself either, but
instead just build skeleton sample blocks and enqueue them for yet another
thread to work on them; of course its sample is incomplete now, so it marks it
accordingly (or, rather, leave it marked that way). In addition, it will
memorize which own sample it is currently working on and for which direction it
needed that new sample (maybe by adding this info to some linked list in the new
sampling block skeleton), and then go on as if everything was perfectly fine (it
will even trace the current ray to full completion, just in case it needs to
"order" more samples).
As the lower-level thread performs its sampling, it will fill in the sampling
block it had received to work on, and when it is finished, it will mark the
block as "completed". It will also insert it into another queue.
A thread that has "ordered" sample blocks will check its queue periodically
(e.g. whenever it has finished work on a sample), and re-visits its own "sample
jobs" for which it originally ordered that deeper-bounce sample, re-tracing the
incomplete ray(s) if it now has all necessary samples for that particular ray.
If it finds that it has completed all rays successfully now, it will report the
sample as finished to its own "boss".
So we would have the threads kind of not running in parallel but "layered", with
one thread per radiosity "bounce" depth.
In an environment with insufficinent threads to fully realize this approach,
some threads would compute two or even more bounces, calculating the
intermediate-bounce samples itself as they become needed.
A crucial question would be, of course, whether this approach would actually
fact speed up anything. Obviously, we may trace some rays twice with this
setup: Once to find that we need certain samples, and then another time when
they have actually arrived.
If we look at a 1-bounce scenario, this is a non-issue: The top level tracer
does not need to re-do the pretrace picture. This would cost us the ability to
use the pretrace as a preview, but that's it. So we would have some overhead
here, but no complicated math.
The same goes for any multi-bounce scenario on a dual-core system (as I guess we
would not want to have more than one task running per core): However the bounce
levels would be distributed among the tasks, the "bottom-level" task would not
have to wait for lower-bounce samples to be computed, while the "top-level"
task would not have to re-render.
In a 2-bounce triple-core scenario, the worst thing that could happen would be
that all samples of the first bounce need totally different second-bounce
samples. But in this case we'd be screwed anyway (unless we have a very low
sample count) as it would mean that for some reason the 2nd-level bounce would
require count times as many samples as the 1st-level bounce.
In reality, I'd expect a first-bounce sample to require a roughly random cut of
second-bounce samples. So as the 1st-bounce worker is traversing its sample
jobs, more and more results will come in from the 2nd-bounce worker (which in a
2-bounce scenario does not need any further samples, so will deliver results in
sequential order), and therefore more and more rays will trace fine without
requiring a re-trace.
So effectively this can be expected to result in an about 1.5-fold workload for
the 1st-bounce worker (maybe something like 1.25-fold workload in total?), at
the benefit of having three or more tasks working on it simultaneously.
In a 3-bounce scenario, things probably get some deal messier. If for example we
had 1000 2nd-level-bounce samples and each required all 1000 3rd-level-bounce
samples, all the 1st-level-bounce samples would be rendered twice.
So the workload would be about 1.5-fold again for the 2st-bounce worker, but
probably close to double for the 1st-bounce worker.
So it seems that with this approach, going beyond three simultaneous tasks
during pretrace might not be worth the pain after all. On the other hand, with
enough spare computing power and a particularly deep bounce level it would
still reduce the total running time.
Anyway, I'll try to set up a simulation to get an estimate of how this aproach
might scale.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Chambers <ben### [at] pacificwebguy com> wrote:
> > -----Original Message-----
> > From: clipka [mailto:nomail@nomail]
> > (BTW, why is Boost used if it is so slow?)
> Boost isn't slow. Mutexing is slow (relatively).
Boost mutexes are actually the slowest I have tried, although not by a
very large margin.
Using Pthreads mutexes directly is (at least in my system) slightly
faster, and using OpenMP mutexes still slightly faster.
The reason why Boost is used is that it's portable to most systems.
Pthreads can only be used in posix systems which implement it (if I'm
not mistaken, most Windows compilers don't). OpenMP is a rather new
standard and few compilers support it.
As a curiosity, I tested the actual slowdown caused by Boost mutexes.
Consider this function:
void incrementCounter()
{
boost::mutex::scoped_lock lock(mutex);
++someCounter;
}
I tested calling this function (from a different compilation unit, so
that the compiler cannot inline it, in order to better give a true notion
of its speed) 500000000 times in a loop (compiler options -O3 -march=native)
and in my system it takes 47 seconds. If I comment out the locking, it
takes 1.8 seconds.
Mutexing is a rather hard problem. Not only is it enough to lock access
from more than one thread at the same time, you also have to prioritize
the accesses. In other words, assume you have this situation using a
naive mutex:
- Thread 1 accesses the mutexed resource and gets the lock to itself.
- Now thread 2 gets scheduled and tries to access the same resource, but
the mutex blocks it, so for now it has to wait.
- Thread 1 gets done and frees the lock. However, it needs the resource
immediately again, and locks it again.
- Thread 2 gets scheduled and tries again to access the resource, but
it's locked, so it can't get it.
- Repeat.
Thread 2 may be locked out of the resource by thread 1 if the former
never gets scheduled when the lock would be free.
For this reason the mutex must prioritize: When thread 1 tries to
immediately lock the resource again, after freeing it, the mutex should
not give it, but instead it should prioritize thread 2, who requested it
earlier.
If a naive mutex would be enough, then this would be by far the most
efficient way of locking I know of:
void incrementCounter()
{
static int lockFlag = 0;
while(!__sync_bool_compare_and_swap(&lockFlag, 0, 1)) sched_yield();
++someCounter;
lockFlag = 0;
}
This runs in 15 seconds in my system. OTOH it requires the gcc extension
__sync_bool_compare_and_swap as well as the posix <sched.h> library. So
it's not really a viable option for portable code.
(And of course it has the problem that it doesn't prioritize requests.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> -----Original Message-----
> From: Warp [mailto:war### [at] tag povray org]
> Chambers <ben### [at] pacificwebguy com> wrote:
> > Boost isn't slow. Mutexing is slow (relatively).
>
> Boost mutexes are actually the slowest I have tried, although not by
> a
> very large margin.
> (interesting stuff about mutexing snipped)
Yes, I'm aware of different designs for mutexes. In fact, the fastest
way to deal with them is to design your container such that they aren't
even needed. However, the only paper I've seen that said such a thing
advocated using immutable state instead.
That is, once a variable is created it cannot be modified. In the case
of a container, you don't actually change the container; you make a
copy, set the reference to point to the modified data, and dump the
original data.
I was so impressed that I implemented a few tests of the idea just to
get a feel for it. It CAN be extremely fast, and threading CAN work
effectively with it, but generally it's a pain in the a** and, if done
wrong, you can screw up your data or get a big slowdown. And you're
still faced with the race conditions when radiosity samples depend on
other radiosity samples (that is, the result of sampling depends on what
other samples are taken - but in a threaded environment, we don't know
what samples will be taken first).
Would it be faster if different threads rarely accessed the same locked
data? We could split the sample tree into several smaller trees
(sub-trees, if you will) based on scene geography (grouping close
samples in the same tree). Then, when performing sampling, a thread
would be most likely to only need access to a few of the sub-trees
(those nearest), and rarely the sub-trees further away. If you only
have a few threads, then the chances of multiple threads needing the
same sub-tree at the same time are minimized. Having more threads would
add more overhead, of course, because thread collision is more likely.
Or, depending on the implementation of the tree, you wouldn't need to
lock the whole tree, just one particular node and all it's sub-nodes.
Of course, I don't even know if such a thing would speed things up at
all, or if it's a pointless optimization.
...Ben Chambers
www.pacificwebguy.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> - Thread 1 gets done and frees the lock. However, it needs the resource
> immediately again, and locks it again.
> - Thread 2 gets scheduled and tries again to access the resource, but
> it's locked, so it can't get it.
I don't know the pthread library well, but are you sure its
lock function works by polling? I'd have expected it to wait
for a signal sent by the unlock function and Thread 1 to
get awakened before Thread 2 can lock again.
Also, why should Thread 2 have a higher priority anyway? It
may feel unfair for it to have to wait all the time, but if
both threads lock the resource too frequently one of them
is bound to be waiting all the time, so the throughput
is not helped by fairness.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> As a curiosity, I tested the actual slowdown caused by Boost mutexes.
Sorry, but this is a fairly baseless claim because there are no "Boost"
mutexes. Boost provides nothing more than a very low-overhead (zero overhead
if using an optimizing compiler) wrapper over Posix mutexes on Unix and
Win32 mutexes on Windows. As such, "Boost mutexes" cannot be slower than the
native operating system's mutexes because they *are* nothing more than the
native operating system's mutexes!
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Chambers wrote:
> Yes, I'm aware of different designs for mutexes. In fact, the fastest
> way to deal with them is to design your container such that they aren't
> even needed. However, the only paper I've seen that said such a thing
> advocated using immutable state instead.
Look for papers on lock-free containers.
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Chambers <ben### [at] pacificwebguy com> wrote:
> That is, once a variable is created it cannot be modified. In the case
> of a container, you don't actually change the container; you make a
> copy, set the reference to point to the modified data, and dump the
> original data.
How exactly does that help? You still have to mutex the copying to
avoid two threads doing it simultaneously. You also have to mutex reading
the data container because you have to avoid reading it while another
thread is copying it (ie. effectively changing its contents, which would
mean that the first thread would get old data, even assuming it won't
access freed memory at any point).
> Would it be faster if different threads rarely accessed the same locked
> data?
AFAIK the problem with POV-Ray's radiosity is that if all threads don't
have the exact same data, you may get different lighting in different
threads (effectively, you will get squares with slightly different
lightning). If one thread adds samples to the container, other threads
must see it immediately.
That, of course, introduces another problem: If two threads would want
to sample the same location, only one of them should do it. The other one
should wait for it to finish it (it wouldn't make too much sense for two
threads to calculate the exact same thing), and then they can both use the
same samples. This adds an additional level of complexity.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christian Froeschlin <chr### [at] chrfr de> wrote:
> I don't know the pthread library well, but are you sure its
> lock function works by polling? I'd have expected it to wait
> for a signal sent by the unlock function and Thread 1 to
> get awakened before Thread 2 can lock again.
You still need a list of threads waiting for the lock to become available.
You might have several threads waiting in line for the lock, and you can't
send a signal to all of them. You should send the signal to the one which
has been waiting the longest. IOW, you need a FIFO.
> Also, why should Thread 2 have a higher priority anyway? It
> may feel unfair for it to have to wait all the time, but if
> both threads lock the resource too frequently one of them
> is bound to be waiting all the time, so the throughput
> is not helped by fairness.
Because if you don't distribute the lock evenly, you may get uneven load,
and the benefit of multithreading will suffer.
For example, suppose you have a memory pool from which threads can
allocate and deallocate objects for whatever task they are performing.
If one thread is constantly obstructing another thread from allocating
objects from the pool (as might in theory happen in the way I described),
you will effectively have a single-threaded program rather than a
two-threaded one, because one of the threads will be idle (or seriously
underutilized) because its access to the memory pool is constantly being
blocked by the other thread.
If the second thread happens to get access to the memory pool by chance,
the situation may reverse itself (iow. now it's the first thread who can't
get to the memory pool), but the end result is the same.
(Granted, in practice it would be quite unlikely for a situation like
this to happen even with a naive mutex, especially if the threads
allocate and deallocate objects from the memory pool relatively
infrequently. However, the more frequently they do it, the more likely
it is that they will start obstructing each other, decreasing the overall
performance of the program.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> Warp wrote:
> > As a curiosity, I tested the actual slowdown caused by Boost mutexes.
> Sorry, but this is a fairly baseless claim because there are no "Boost"
> mutexes. Boost provides nothing more than a very low-overhead (zero overhead
> if using an optimizing compiler) wrapper over Posix mutexes on Unix and
> Win32 mutexes on Windows. As such, "Boost mutexes" cannot be slower than the
> native operating system's mutexes because they *are* nothing more than the
> native operating system's mutexes!
One would think so, but one would be wrong.
If in the example program I mentioned I change the Boost mutex to a
Pthreads mutex, the running time of the program decreases from 47 seconds
to 41 seconds. I measured both versions several times, and the times were
completely consistent, with negligible variation (in the order of plus/minus
0.1 seconds).
The difference is small, but it exists. The "thin" wrapper in Boost does
cause its small overhead.
(I read somewhere that newer versions of Boost fix this small problem
by resorting to more inlining. It might be that I have a version of boost
which does not inline as much.)
OpenMP mutexes are slightly faster than Pthreads mutexes, at least here.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> allocate and deallocate objects from the memory pool relatively
> infrequently. However, the more frequently they do it, the more likely
> it is that they will start obstructing each other, decreasing the overall
> performance of the program
However, if they do it frequently, one of the threads will always
be blocked. Using priorities will therefore prevent the situation
that thread 1 works at 100% and thread2 at 0%, and transform it
into thread 1 works at 50% and thread2 at 50%. While this is
better for responsiveness if one of the thread handles GUI
events or similar, it doesn't help overall performance for
parallelized number crunching as in POV-Ray.
An exception would be if thread 1 needs the lock often but
thread 2 only rarely. But I expect both threads to be doing
essentially the same task in parallel for speedup, so they
will also habe the same locking requirements.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christian Froeschlin <chr### [at] chrfr de> wrote:
> However, if they do it frequently, one of the threads will always
> be blocked. Using priorities will therefore prevent the situation
> that thread 1 works at 100% and thread2 at 0%, and transform it
> into thread 1 works at 50% and thread2 at 50%.
Only in a 1-processor/single-core system.
In a dual-core system the goal is to get as close to 100% and 100% as
possible. If the threads block each other from the resource, you'll get
100% and 0% (on the very extreme), so one of the cores will just sit
idle while the other does all the work.
(Yes, it's quite unlikely to get to this extreme even with naive
mutexes, but in theory it's still possible. In practice you may still
get reduced efficiency in certain situations, and a FIFO would mostly
solve the problem.)
> An exception would be if thread 1 needs the lock often but
> thread 2 only rarely. But I expect both threads to be doing
> essentially the same task in parallel for speedup, so they
> will also habe the same locking requirements.
Which is why it's important to distribute the resources to all
threads evenly.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> The reason why Boost is used is that it's portable to most systems.
> Pthreads can only be used in posix systems which implement it (if I'm
> not mistaken, most Windows compilers don't). OpenMP is a rather new
> standard and few compilers support it.
So maybe on Posix systems boost just wraps the Pthreads mutexes, thereby adding
some more overhead? Or is the difference much worse?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Chambers" <ben### [at] pacificwebguy com> wrote:
> Would it be faster if different threads rarely accessed the same locked
> data? We could split the sample tree into several smaller trees
> (sub-trees, if you will) based on scene geography (grouping close
> samples in the same tree). Then, when performing sampling, a thread
> would be most likely to only need access to a few of the sub-trees
> (those nearest), and rarely the sub-trees further away. If you only
> have a few threads, then the chances of multiple threads needing the
> same sub-tree at the same time are minimized. Having more threads would
> add more overhead, of course, because thread collision is more likely.
Doesn't work I guess. Think of an ordinary room: For most samples, you will need
samples from all across the room, not just a particular corner.
There may be scenes where your idea might speed up things, but in general
radiosity interaction between different parts of the scene can be expected to
be quite high.
The approach of subdividing an image, and feeding each part to a separate task,
works with regular raytracing only because even if parts of the scene interact
through reflection, there is no data cache being built and re-used - because
the chances of two mirrors showing exactly the same points are minimal (let
alone that even then the incident angles would be different) and so caching
wouldn't be worth the pain anyway.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Chambers" <ben### [at] pacificwebguy com> wrote:
> > -----Original Message-----
> > From: Warp [mailto:war### [at] tag povray org]
> > Chambers <ben### [at] pacificwebguy com> wrote:
> > > Boost isn't slow. Mutexing is slow (relatively).
> >
> > Boost mutexes are actually the slowest I have tried, although not by
> > a
> > very large margin.
>
> > (interesting stuff about mutexing snipped)
Indeed. :)
> Yes, I'm aware of different designs for mutexes. In fact, the fastest
> way to deal with them is to design your container such that they aren't
> even needed. However, the only paper I've seen that said such a thing
> advocated using immutable state instead.
>
> That is, once a variable is created it cannot be modified. In the case
> of a container, you don't actually change the container; you make a
> copy, set the reference to point to the modified data, and dump the
> original data.
>
> I was so impressed that I implemented a few tests of the idea just to
> get a feel for it. It CAN be extremely fast, and threading CAN work
> effectively with it, but generally it's a pain in the a** and, if done
> wrong, you can screw up your data or get a big slowdown.
It's a pain in the ass to try to replicate functional programming in heavily
imperative languages, yes. I'm sure Haskell would deal with it much more
gracefully. ;)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"nemesis" <nam### [at] gmail com> wrote:
> It's a pain in the ass to try to replicate functional programming in heavily
> imperative languages, yes. I'm sure Haskell would deal with it much more
> gracefully. ;)
As POV-ray is unfortunately(???) *not* programmed in Haskell, and most likely
will not be in near future, your point is a bit moot ;)
(I'd be a bit curious though to see how a Haskell-based raytracer would perform
overall, compared with POV 3.6 (C), or the current beta (C/C++ in every sense
of the slash)...)
I heard tell that Erlang is a good language to write distributed code, too...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> Presuming that having more samples than actually required is not an issue, then
> how about this one:
>
> [...]
>
> I'm also thinking about totally different approaches, although I can't see yet
> how they could be put to good use. One basic idea would be to have a single
> main pretracer thread that would find out what samples are needed, and have
> other threads actually collect them.
>
> One way this could be done would be as follows:
>
> [...]
Some serious feedback on this anyone, before it gets swamped in posts about
mutexes?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
>>However, if they do it frequently, one of the threads will always
>>be blocked. Using priorities will therefore prevent the situation
>>that thread 1 works at 100% and thread2 at 0%, and transform it
>>into thread 1 works at 50% and thread2 at 50%.
>
> Only in a 1-processor/single-core system.
Also on a dual-core system on worst-case locking (both threads
continually lock and unlock mutexes without doing anything else).
Admittedly not useful but also the only scenario when you get
thread 2 to really starve, which you initally worried about.
The only way to get both cores close to 100% is to minimize
the time spent in locked mutexes, so it becomes the exception
rather than the rule that on thread waits for the other. But
that works equally well with unprioritized mutexes.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <nomail@nomail> wrote:
> So maybe on Posix systems boost just wraps the Pthreads mutexes, thereby adding
> some more overhead? Or is the difference much worse?
While Boost uses Pthreads in posix-compliant systems, according to my
tests its thin layer over it adds a tiny amount of overhead.
OTOH I have also read somewhere that this small problem is (or is going
to be) fixed in newer versions of Boost by moving more code into inline
functions (thus effectively removing any overhead over calling Pthreads
directly).
Anyways, overall it doesn't make too much of a difference. The basic
slowness of mutexes is the same.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> I heard tell that Erlang is a good language to write distributed code, too...
It's interpreted and dynamically typed, so it's certainly not something you
want to try to write *fast* distributed code in. Erlang is distributed for
reliability, not speed. (And, FWIW, it's known to suck at floating point
ops, too.)
--
Darren New, San Diego CA, USA (PST)
The NFL should go international. I'd pay to
see the Detroit Lions vs the Roman Catholics.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> The approach of subdividing an image, and feeding each part to a separate task,
> works with regular raytracing only because even if parts of the scene interact
> through reflection, there is no data cache being built and re-used - because
> the chances of two mirrors showing exactly the same points are minimal (let
> alone that even then the incident angles would be different) and so caching
> wouldn't be worth the pain anyway.
An alternative approach would be to simply give each thread its
own cache. The threads will redo work done by other threads but it
may actually be less costly than locking stuff. It will be simple
to implement and faster than single-threaded pretrace unless
building the cache takes 100% of pretrace time. It removes
race conditions at least for individual pixels.
The problem remains that the image may look different on each
render if the assignment of image blocks to threads is dynamic
(load-balanced). This could be fixed by using a static block
assignment pattern for radiosity scenes (not too terrible, it
is rather unlikely that one thread gets all the slow blocks).
Unfortunately, the resulting image would then still depend
on the number of threads which were actually used, so anyone
who whished to exactly reproduce a scene would have to use
the same thread count.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> wrote:
> It's interpreted and dynamically typed, so it's certainly not something you
> want to try to write *fast* distributed code in. Erlang is distributed for
> reliability, not speed. (And, FWIW, it's known to suck at floating point
> ops, too.)
Interestingly though, someone actually wrote a 3D modeller in that language.
However, this explains why Wings3D goes down to its knees when handling larger
models... which is a pity, because the user interface is exceptionally good.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Darren New <dne### [at] san rr com> wrote:
>> It's interpreted and dynamically typed, so it's certainly not something you
>> want to try to write *fast* distributed code in. Erlang is distributed for
>> reliability, not speed. (And, FWIW, it's known to suck at floating point
>> ops, too.)
>
> Interestingly though, someone actually wrote a 3D modeller in that language.
Yep. And it's not distributed, either. It uses all one thread, too. Although
there are features for recompiling it and restarting it without actually
closing the model you're working on.
> However, this explains why Wings3D goes down to its knees when handling larger
> models...
That and being "functional" (rather than functional without the quotes, like
Haskell), meaning in Erlang you have to copy any data structure you want to
change, without actually being functional enough to make it possible for the
compiler to optimize based on immutability of variables.
--
Darren New, San Diego CA, USA (PST)
The NFL should go international. I'd pay to
see the Detroit Lions vs the Roman Catholics.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> -----Original Message-----
> From: clipka [mailto:nomail@nomail]
> Some serious feedback on this anyone, before it gets swamped in posts
> about
> mutexes?
Yeah.
From what I understand, POV does a pre-trace to precompute a sample
tree. Then, during the actual, render, POV creates any additional
samples needed.
What if there were a way, during the pretrace, to predict where
additional samples would be needed? If so, then all the samples could
be taken during the pretrace, with no additional sampling during the
final render, with no loss in quality.
...Ben Chambers
www.pacificwebguy.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Chambers" <ben### [at] pacificwebguy com> wrote:
> From what I understand, POV does a pre-trace to precompute a sample
> tree. Then, during the actual, render, POV creates any additional
> samples needed.
>
> What if there were a way, during the pretrace, to predict where
> additional samples would be needed? If so, then all the samples could
> be taken during the pretrace, with no additional sampling during the
> final render, with no loss in quality.
Yes, this would solve the multitasking issues (talking about 100%
reproducibility of shots) during main render.
Unfortunately, I know of only two approaches to collect all the samples needed
before the main render:
(1) Just plain stupidly cover all the surfaces in the whole scene with samples -
which will be a problem for scenes that stretch into infinity.
(2) Perform the full render twice.
The problem is that unless you really *do* the final render, you never know
which regions of the shot may ultimately be reached by some stray ray.
To give a trivial example: If you turn on focal blur, you will find that the
final render will take more radiosity samples - especially in the very first
and very last lines. That's because regions normally just outside the visible
region now need to be mixed in.
Another example are small or strongly-curved reflecting details that pretrace
may not have encountered.
So if we want to really do a complete pretrace, we end up taking the full-detail
shot twice - once with radiosity sampling on, and once without further sampling.
And what's worse: The first pass will be the more expensive one. And it seems we
want to do it in a single task to avoid the trouble already mentioned.
And what on earth are we doing the final render for then?
I don't really think this gets us anywhere :)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christian Froeschlin <chr### [at] chrfr de> wrote:
> An alternative approach would be to simply give each thread its
> own cache. The threads will redo work done by other threads but it
> may actually be less costly than locking stuff. It will be simple
> to implement and faster than single-threaded pretrace unless
> building the cache takes 100% of pretrace time. It removes
> race conditions at least for individual pixels.
Yup, thought of it too.
> Unfortunately, the resulting image would then still depend
> on the number of threads which were actually used, so anyone
> who whished to exactly reproduce a scene would have to use
> the same thread count.
Not necessarily so. If the image is *always* divided into the same number of
blocks, *always* using separate trees for any two blocks even if they are
processed by the same thread, and *always* merging the trees in the same order,
then we do have 100% reproducibility regardless of thread count.
If in addition we have each thread render only one pretrace pass at a time, then
consolidate all collected samples into one tree before proceeding with the next
pretrace pass, we also reduce the number of surplus samples taken.
In the first pretrace pass, the probability is quite low that two tasks need
samples so close together that one of them would actually be not needed.
In the second pretrace pass however, the first pass will already have generated
quite a number of "deeper-bounce" samples to start with.
This brings me to some *GOOD* idea... hey, thanks for the inspiration!
(I'll go into detail in a separat thread... this one has accumulated too much
"spin-offs" for my taste.)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Some serious feedback on this anyone, before it gets swamped in posts about
> mutexes?
I think one of the best ways to start is to get the tree building and
re-sampling working again in the single-render thread case. From there you
can make progress towards multithreading.
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> I think one of the best ways to start is to get the tree building and
> re-sampling working again in the single-render thread case. From there you
> can make progress towards multithreading.
I think it doesn't make sense to put any work into POV's radiosity without
having at least some rough idea how it will be operating.
And making a POV-version that will support SMP only for non-radiosity scenes
isn't worth the hassle in my eyes: To get my quad-cores working simultaneously
on a non-radiosity scene, I can always start four full-fledged render processes
to crunch away on the same scene, forcing them to produce different jittering
and merging the results later - so I can get away with less antialias / focal
blur samples and lower area light resolution to get the whole thing speed up.
Ah, speaking of it: 100% reproducibility seems a holy cow in POV, but there are
situations where one might deliberately want variations in jitter effects from
shot to shot. So it would be nice to have a command line / ini parameter that
basically says "add X to all jitter-related random generator seeds" (where X
may even be something derived from current system time).
Setting a different antialias jitter value helps in practice, but I think it's
not the cleanest approach.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Thorsten Froehlich <tho### [at] trf de> wrote:
>> I think one of the best ways to start is to get the tree building and
>> re-sampling working again in the single-render thread case. From there you
>> can make progress towards multithreading.
>
> I think it doesn't make sense to put any work into POV's radiosity without
> having at least some rough idea how it will be operating.
Well, given the code mostly works, it is just a matter of fixing a few bugs
and then having a working reference implementation does make quite a bit of
sense...
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> Well, given the code mostly works, it is just a matter of fixing a few bugs
> and then having a working reference implementation does make quite a bit of
> sense...
As it seems to me, the problem with the code, as it is now, is that it was
attempted to change too many things at once:
- Migrating from C to C++
- Introducing Multithreading
- Introducing some optimizations
- Changing some features
- Doing all of this at different paces for different components
In addition, the refactoring approach wasn't ideal. "TODO FIXME" is never a good
solution to problems that arise during refactoring, because you effectively
break the code and have to re-assemble it later. So you have a time in between
when you cannot do any regression testing on the "amputated" code, and when you
are able to do it again, the code may have changed too much overall to do any
sensible regression testing.
In the case of POV 3.7.0 beta, some parts of the radiosity code have been
amputated to ease the transition from C code (global data) to C++ code
(object-internal data storage). If that would have been the only changes for
now, things would be much easier for me: I could be sure that the beta must
produce exactly the same output as the 3.6.1c, up to the very last pixel.
Now I don't know: I get different output, but is it really wrong?. After all, as
a first step towards multithreading the picture is now pretraced in a different
order (block by block, instead of line by line), which changes the choice of
samples taken; even if I would change the processing order back, the main
render would still be done block by block now. I can't possibly change *all*
the code back to 3.6.1c.
Then there is the Gamma thing: The beta.29 seems to produce a higher contrast in
radiosity shots, but is that a radiosity bug, or do I see some effect of the
Gamma stuff here?
In addition, I find code that seems to do things differently than the 3.6.1 -
not on an overall design level, but in small details. Some are obviously
intended as features - but they reduce my ability even further to assess
whether the output I get is good or bad.
Of course, last not least there is the problem that 3.6.1c radiosity was bad as
well. I actually think that what I currently have produces significantly better
results not only compared to beta.29, but also to 3.6.1c.
The most perplexing thing is that I get these results at very low costs (for
reasons I don't even understand; at the moment I'm just skimming through the
radiosity code, leveling out everything that seems to have changed from 3.6.1c
and beta.29).
For example, a 640x512 pixel version of my radiosity-based "Claustrophobia" shot
for the TINA-CHeP competitiontakes 7830 seconds of CPU time with the beta.29 on
my machine, but just 2370 seconds with my modifications - less than a third of
the time. Both versions were running at full throttle. Both produced images
that seem to differ only in random details.
(see http://www.tc-rtc.co.uk/imagenewdisplay/stills/index151.html what kind of
scene I'm talking about)
The 3.6.1c still hasn't finished more than 60% of the shot after ~8000 seconds
of CPU time; I'm curious how the results will compare.
You mention that it's "just a matter of fixing a few bugs" - if that is so, it
would be helpful to get some description of them.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Thorsten Froehlich <tho### [at] trf de> wrote:
>> Well, given the code mostly works, it is just a matter of fixing a few bugs
>> and then having a working reference implementation does make quite a bit of
>> sense...
>
> As it seems to me, the problem with the code, as it is now, is that it was
> attempted to change too many things at once:
The code is not generating images remotely right. Just compare to 3.6
output. Quality is much worse in 3.7 because something is missing. I never
had the time to track it down though. It is a fairly simple problem for
certain, but radiosity tests do take a real lot of time.
All this has nothing to do with multithreading or the use of C++ because the
code was never changed for it. In fact, very little was changed in the
radiosity code at all (and the lighting code has only been changed a bit).
In short, a simple problem exists, it is just very time consuming to debug.
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka wrote:
> Of course, last not least there is the problem that 3.6.1c radiosity was bad as
> well. I actually think that what I currently have produces significantly better
> results not only compared to beta.29, but also to 3.6.1c.
It isn't bad or broken at all in 3.6. It is just difficult to use <sigh>
> You mention that it's "just a matter of fixing a few bugs" - if that is so, it
> would be helpful to get some description of them.
Use the included sample scenes, and you will quickly notice the problems: In
particular the darkness problems and similar artifacts. The sample scenes,
which are very simple geometries, do make the issue very clear quickly. I
would recommend trying them as the issue is not easy to track down in
complex scenes with already complex non-radiosity lighting.
Thorsten
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> It isn't bad or broken at all in 3.6. It is just difficult to use <sigh>
I tell you it *is* bad (although it's not all the radiosity code's fault).
One example: Smooth meshes. If you set recursion_limit to some higher value,
light "leaks through" them like a leaky bucket if they aren't heavily
subdivided. This is because with smooth mesh objects the "raw" normal isn't
actually "raw" at all.
For some strange reason, it seems that this "leaky bucket" effect isn't limited
to meshes, but also appears with CSG object (albeit less strongly).
It also seems to me that the 3.6.1 radiosity implementation makes bright light
"flow" along e.g. corners of a room in an unnatural way.
Another thing is that it seems to me as if the 3.6.1 radiosity code would pick
up object colours too strongly.
The beta.29 seems to pick up colour to less extent, but does have the "flow"
effect as well; my most recent version of the code doesn't have it, for some
reason I don't understand because I think I should actually be closing in on
3.6.1 status.
> Use the included sample scenes, and you will quickly notice the problems: In
> particular the darkness problems and similar artifacts. The sample scenes,
> which are very simple geometries, do make the issue very clear quickly. I
> would recommend trying them as the issue is not easy to track down in
> complex scenes with already complex non-radiosity lighting.
I'm currently using quite simple, radiosity-only scenes (well, the
"Claustrophobia" shot uses a *bit* of conventional lighting as an add-on, but
primarily it's radiosity based).
They're possibly a bit unusual in their radiosity use - for example, one is a
simple, unlit room that *should* be illuminated only by light seeping through
an almost-closed door (the light source itself is just an excessively bright
white background). But it makes a formidable scene to show that 3.6.1 radiosity
is messed up already.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
One possibility would be to rewrite the whole radiosity code from scratch.
Read the original paper by Greg Ward about the subject, and if possible,
study how Radiance does it "properly", and learn from that before the
rewrite.
Of course this is a huge amount of work, and it would be perfectly
understandable if nobody would be ready to do it. (There might also be
some minor surprising issues, eg. something intrinsic in POV-Ray not being
completely compatible, for whatever reason, with Ward's algorithm, or
something else.)
Radiance is a proof that the algorithm can be made to work well. It's just
a question of somebody doing it... :/
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> One possibility would be to rewrite the whole radiosity code from scratch.
> Read the original paper by Greg Ward about the subject, and if possible,
> study how Radiance does it "properly", and learn from that before the
> rewrite.
Heh! I want it to be in the beta *soon*...!
When I look at the code, I'm indeed tempted to do a complete rewrite - too many
tiny little screws tweaked for unexplained reasons; but I'm not sure whether
that is desired by the POV team at all, despite the old warning that "The
design and implementation of [radiosity] is LIKELY to change in future versions
of POV-Ray" (emphasis added).
Oh, speaking of "the original paper", here's a quote from the sources:
"(This does not work the way that most radiosity programs do, but it
accomplishes the diffuse interreflection integral the hard way and produces
similar results. It is CALLED RADIOSITY here TO AVOID CONFUSION WITH AMBIENT
AND DIFFUSE, which already have well established meanings within POV).
INSPIRED by the paper "A Ray Tracing Solution for Diffuse Interreflection" by
Ward, Rubinstein, and Clear, in Siggraph '88 proceedings."
(again, emphasis added)
So it was never actually intended to be true radiosity, but just a thing that
did something similar. Therefore when refering to "the original paper" we
shouldn't be talking about a *re-write* but a completely new feature...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> Oh, speaking of "the original paper", here's a quote from the sources:
>
> "(This does not work the way that most radiosity programs do, but it
> accomplishes the diffuse interreflection integral the hard way and produces
> similar results. It is CALLED RADIOSITY here TO AVOID CONFUSION WITH AMBIENT
> AND DIFFUSE, which already have well established meanings within POV).
>
> INSPIRED by the paper "A Ray Tracing Solution for Diffuse Interreflection" by
> Ward, Rubinstein, and Clear, in Siggraph '88 proceedings."
>
> (again, emphasis added)
>
>
> So it was never actually intended to be true radiosity, but just a thing that
> did something similar.
The original paper is not about radiosity either.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> So it was never actually intended to be true radiosity, but just a thing that
> did something similar. Therefore when refering to "the original paper" we
> shouldn't be talking about a *re-write* but a completely new feature...
Having just taken the time to read the original paper by Greg Ward et al., I'll
have to correct myself:
- The algorithm described by Ward et al. is NOT radiosity either.
- The algorithm used by POV-Ray DOES come very close to that described by Ward
et al.; there are a few differences, but none that would justify a complete
rewrite. The core of the implementation is plain Ward et al.
So I guess most people complaining that Radiosity works much better in other
programs than in POV, and then maintain that it should be re-implemented
according to Ward et al.'s paper, haven't read the paper themselves (or have no
idea whatsoever about the internal workings of POV's implementation).
This misconception may have arisen due to some people rightly claiming that
"what POV-ray does is NOT radiosity", referring to Ward's paper as a witness to
their claim - which other people understood as that Ward's paper would describe
true radiosity. Well, it doesn't.
For all those who still ask for TRUE Radiosity to be implemented in POV, I can
give you one clear statement:
This will never happen.
From what I gather from Ward's paper, true radiosity requires the geometry to be
subdivided in - roughly - equally sized patches. This is easy to do with mesh
based geometry, but infeasible with the mathematical representation POV-ray
uses for objects.
That's the bottom line of it.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"nemesis" <nam### [at] gmail com> wrote:
> The original paper is not about radiosity either.
Ward's paper was a few minutes faster at telling me that than you were :)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> "nemesis" <nam### [at] gmail com> wrote:
> > The original paper is not about radiosity either.
>
> Ward's paper was a few minutes faster at telling me that than you were :)
Seems like we were both reading at the same time, but I just got to page 2 until
realizing it and posting here first. ;)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"nemesis" <nam### [at] gmail com> wrote:
> Seems like we were both reading at the same time, but I just got to page 2 until
> realizing it and posting here first. ;)
Found a good version with all diagrams and formulae in it? I could only dig up a
PDF lacking the diagrams & formulae, or a series of .tif files of the scanned
document. Or a set of PostScript files.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <nomail@nomail> wrote:
> - The algorithm described by Ward et al. is NOT radiosity either.
The problem is that there are two things which have the name "radiosity":
1) By far the most widely accepted definition of the word "radiosity" in the
computer graphics industry and community is to refer to a very specific
algorithm, which is used to achieve diffuse inter-reflection of light between
surfaces. This algorithm is heavily based on using lightmaps, and usually
can only be feasibly implemented in a scanline renderer.
2) A much less widely used meaning is to use "radiosity" as the generic term
for any diffuse light inter-reflection algorithm. In POV-Ray the term is used
in this second meaning. However, most commonly in the computer graphics
industry the term "global illumination" is used instead. (Although GI can
refer to more complex lighting than simply *diffuse* inter-reflection.)
A much more accurate name for Ward's algorithm (a variation of which is
used in POV-Ray) is "stochastic global illumination method" (or alternatively
"monte-carlo global illumination method", although I'm not 100% sure if
it really *is* monte-carlo sampling technically). However, people use
"radiosity" for historical reasons, because it's short, and because the
documentation uses it (and because it's the SDL keyword). The documenation
and the SDL keyword are technically wrong, but I suppose there's little
that can be done about that. (Although with a full rewrite perhaps a name
change could be fitting.)
> - The algorithm used by POV-Ray DOES come very close to that described by Ward
> et al.; there are a few differences, but none that would justify a complete
> rewrite. The core of the implementation is plain Ward et al.
> So I guess most people complaining that Radiosity works much better in other
> programs than in POV, and then maintain that it should be re-implemented
> according to Ward et al.'s paper, haven't read the paper themselves (or have no
> idea whatsoever about the internal workings of POV's implementation).
In that case it would be interesting to know why it seems that Radiance
gets superb-looking, accurate and smooth radiosity with (apparently) no or
minimal tweaking, while in POV-Ray it seems to be a constant struggle to
get artifact-free radiosity which looks good and realistic.
I have the impression that Radiance does something which POV-Ray doesn't
(or the other way around).
> For all those who still ask for TRUE Radiosity to be implemented in POV, I can
> give you one clear statement:
> This will never happen.
What do you mean by "TRUE Radiosity"? If you are referring to the
lightmapping precalculation technique, the only limitation to implementing
it in POV-Ray would be that it's more or less limited to polygons. It could
be conceivably be implemented in POV-Ray, assuming it's limited to work with
meshes only (for both the illuminated surfaces and surfaces which illuminate
other surfaces). Given how widely used meshes are, it wouldn't be all that
far-fetched to think that it could be useful even with this limitation.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> In that case it would be interesting to know why it seems that Radiance
> gets superb-looking, accurate and smooth radiosity with (apparently) no or
> minimal tweaking, while in POV-Ray it seems to be a constant struggle to
> get artifact-free radiosity which looks good and realistic.
http://radsite.lbl.gov/radiance/gallery/electric.html
Don't look any better than the best images in POV's HOF. In fact, their focus
on technical correctness and lack of any artistic aesthetic makes them
downright ugly and aseptic to most povray users, I guess.
I've also seen scenes by Gilles Tran that used quite standard settings for
"radiosity" and still produced sublime results. I wonder how much tweaking
he'd save on radiance's "radiosity" settings but instead call a long
command-line pipe with all the little radiance utilities needed to "compile" a
single image... it's a huge advantage of povray over radiance. That and the
SDL.
> What do you mean by "TRUE Radiosity"? If you are referring to the
> lightmapping precalculation technique, the only limitation to implementing
> it in POV-Ray would be that it's more or less limited to polygons. It could
> be conceivably be implemented in POV-Ray, assuming it's limited to work with
> meshes only (for both the illuminated surfaces and surfaces which illuminate
> other surfaces). Given how widely used meshes are, it wouldn't be all that
> far-fetched to think that it could be useful even with this limitation.
Yes. I also wonder if photon mapping is not useful as a general GI method in
povray for the same reason of lightmapped radiosity...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> In that case it would be interesting to know why it seems that Radiance
> gets superb-looking, accurate and smooth radiosity with (apparently) no or
> minimal tweaking, while in POV-Ray it seems to be a constant struggle to
> get artifact-free radiosity which looks good and realistic.
- Does Radiance actually use the "Ward algorithm" to achieve "radiosity"?
- How does the speed of Radiance compare to POV? If you invest enough computing
power, you don't have to do much tweaking either to get superb-looking,
accurate and smooth results.
I have no experience with Radiance whatsoever, so I can't make any statements
about this.
> I have the impression that Radiance does something which POV-Ray doesn't
> (or the other way around).
Well, I already found some things that POV does differently from Ward et al.; no
really dramatic changes so far - just a few screws to tweak the algorithm. But
they're not exposed to the user, and they're possibly not well-chosen.
From those settings, I guess POV should perform well with scenes that have an
overall reflectivity (specular + diffuse) of 0.25 or below - which is probably
not realistic...
> It could
> be conceivably be implemented in POV-Ray, assuming it's limited to work with
> meshes only (for both the illuminated surfaces and surfaces which illuminate
> other surfaces). Given how widely used meshes are, it wouldn't be all that
> far-fetched to think that it could be useful even with this limitation.
Given how many people use isosurfaces or blobs...: No deal.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> - Does Radiance actually use the "Ward algorithm" to achieve "radiosity"?
Yes, it was its proof of concept and Radiance too is the brainchild of Ward.
> - How does the speed of Radiance compare to POV? If you invest enough computing
> power, you don't have to do much tweaking either to get superb-looking,
> accurate and smooth results.
Don't really know, but while POV-Ray was always more of a hobbyist program,
Radiance was being pushed by a well respected reseacher in the area, as well as
being used by companies in arch viz.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> -----Original Message-----
> From: nemesis [mailto:nam### [at] gmail com]
> Yes. I also wonder if photon mapping is not useful as a general GI
> method in
> povray for the same reason of lightmapped radiosity...
I did some tests last year to that effect, and liked the results. I
just never got around to doing anything with the source to make that
aspect easier, but I would love to see someone else pursue that.
...Ben Chambers
www.pacificwebguy.com
A render isn't slow unless it won't finish until after your next
birthday.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <nomail@nomail> wrote:
> > It could
> > be conceivably be implemented in POV-Ray, assuming it's limited to work with
> > meshes only (for both the illuminated surfaces and surfaces which illuminate
> > other surfaces). Given how widely used meshes are, it wouldn't be all that
> > far-fetched to think that it could be useful even with this limitation.
> Given how many people use isosurfaces or blobs...: No deal.
So in your opinion, because many people use something else than meshes,
we should not offer those who do use exclusively meshes for their scenes
any additional tools?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |