|
![](/i/fill.gif) |
Hi all,
Here is the sponge fractal as promised in p.b.i. It is mostly
uncommented but pretty straightforward. Change the iterations and
iterationsB variables to adjust the level of detail. Everything else should
probably stay the same as it is unless you want to play with the code.
Here are some explanations of how the speed was achieved.
1. There are no differences. The previous algorithms were 1 cube with the
holes differenced out of it. This is the obvious way to do it from looking
at the fractal but it makes rendering very slow on POV. My code, instead,
creates the blocks where they need to exist and does not create them where
the holes are. Much faster render.
2. The fractal in general is mirrored on the X, Y, and Z axis. That means
you only need to create 1/8th of the whole thing and just replicate that for
each corner.
3. The shape of the fractal as a whole at iteration level N is the same as
the shape of each Block (more on these in a minute) at iteration level N+1.
This means that if you calculate a fractal as some iteration level (e.g., 4)
and then use it as the Blocks for another fractal at another iteration level
(e.g., 3) you get a total fractal at iteration level 7 (4 + 3). Basically
the second fractal is made up of many, many, many of the smaller first
fractal. Given this realization I designed it so that the first fractal was
created as a mesh and then used many times by the second. This was a HUGE
time and memory savings.
In the above a Block is this. Think of the fractal at just 1 iteration.
You can think of it as a large cube made up of 3 X 3 X 3 smaller cubes with
7 particular cubes missing. Those 7 are the center 1 and the center of each
face (6 faces + center = 7). In this case my Block from the above paragraph
is each of these remaining 20 cubes (3 X 3 X 3 = 27 - 7 = 20).
The down side to using meshes is that you can't take a cutout of the
whole shape. Someone said that taking a cross-section of the shape would be
interesting. I agree but the meshes are not solid shapes so this won't look
too good.
4. Although it is in the scene now it is commented out now, another
optimization did have a pretty large effect when I tested it before
implementing meshes. This one was reducing the number of Blocks as defined
above. I noticed that on a iteration 1 fractal there are 20 Blocks. BUT,
many of those Blocks are in a row. If a 3 X 1 X 1 Block was created as a
single box with dimensions of 3 X 1 X 1 then this would reduce the total
number of objects. This is one thing I want to put back into the mesh code
and reduce the total number of vertices in the mesh.
5. Another optimization I might work on is reducing the amount of memory
used by the array. Although with the 2 pass method now this is already
reduced a lot. What I was thinking was that since I am currently only using
the array for on or off values I could do bit manipulation and use bits
instead of integers. This would reduce the array memory usage by 32 (on 32
it INT machines anyway). The problem here is it would also greatly slow down
access to those values since multiple calculation would need to be done when
reading or setting one.
6. One last thing was that I noticed in one of the previous sponge/cheese
scenes the check for escaping the iteration was done after the next level
was called. This meant countless unnecessary calls that were almost
immediately escaped. What I mean is at iteration level N all of the level
N - 1 calls were made but when those macros were entered they immediately
fell through and did nothing. Instead I make sure it is ok to call those N -
1 level before I make the call therefore reducing the number of checks
greatly.
I guess that's about it. I know that the mesh code could be optimized
some more and I'll work on it. Even so I'm pretty happy that 7 iterations is
doable and 8 and maybe 9 as well. Comments and suggestions are welcome.
--Rainer
Post a reply to this message
Attachments:
Download 'us-ascii' (7 KB)
|
![](/i/fill.gif) |