|
|
I want to have a large landscape in my next IRTC entry.
I played with isosurfaces for a while, but the learning curve is a bit
steep for me.
Then I decided to go with a function height field.
I found that this is fairly easy to construct, and I can adjust the
resolution of the height field so that it doesn't look blocky when I do
close-ups. In fact, the HF in the short clip here isn't smoothed; if I
can boost the resolution high enough and use anti-aliasing, it doesn't
need smoothing.
I also found that it's not hard to use several smaller heightfields, put
together, to duplicate one large height field. I developed a macro to
detect if the height field is entirely off-camera or at least partially
on-camera, and not putting it into the scene if it's not viewable. The
attached clip shows how the different tiles are switched on and off as
they pass into a viewing area with a smaller viewing angle than the one
used for rendering. The view angle used for clipping is represented by
the watermark rectangle.
I also found that I have to use non-smoothed height fields for this,
because the smoothing is not continuous at the joint between adjoining
height fields. I could probably make each HF slightly larger, and clip
them at the edges, however.
So now I basically have a height field of infinite size and resolution,
without having to worry about how much RAM it takes up in memory: Peak
memory used in this clip was only 5.6 Megs. The only difficulty is
developing an HF function that makes the landscape I want.
The height field seen here is based on this pigment:
#local myHF = pigment { average
turbulence <.5,.5,.5> lambda 2.5 octaves 8
scale .4 translate <-.1,-.1,0>
pigment_map {
[1 bumps ]
[.5 bumps scale .5 ]
[.25 bumps scale .25 ]
[.125 bumps scale .125 ]
[4 spherical cubic_wave color_map { [0 rgb 1][1 rgb 0] } ]
}
}
The individual height fields are made and placed with this code:
height_field {
function 256,256 {
pigment { myHF scale <7,7,1> translate <-iI,iJ,0> }
}
translate <-.5,-1,-.5>
pigment { gradient y
color_map {
[.25 rgb 1 ]
[.251 rgb <.75,.667,.583> ]
[.75 rgb <.75,.667,.583> ]
[.77 rgb <.9,.8,.7> ]
}
}
translate <iI,0,iJ>
scale <5000,2000,5000>
translate z*1000
}
The variables iI and iJ specify the specific tile to be created. The
translate statements that use iI and iJ do the work of properly aligning
the heightfields into one large height field; the other scales and
translations aren't important to the technique.
Now I need to throw together some code to put dead trees and abandoned
buildings on this desert landscape; those can also be clipped if they
fall out of the camera view, so that I can keep memory requirements
down. I will probably also throw in some mountains so that I don't have
to extend the tiles out to the horizon.
Regards,
John
Post a reply to this message
Attachments:
Download 'test.mpg' (571 KB)
|
|
|
|
Anthony D'Agostino wrote:
> That's an excellent teqnique to save RAM. And the on-and-off effect is very
> neat, even thought it isn't intended.
It's intended as a demonstration of what's going on, and how the memory
savings work. For a final rendering, I'd set the zoom value for
clipping to the same value as the zoom value for the camera; when I do
that, the clipping takes place entirely off-camera, and is not seen in
the final frames.
I used a similar technique in the Sports round of the IRTC. I modeled a
stadium full of robots, which took far more memory than I have installed
on my machine; a simple bit of code allows me to check for robots that
are entirely off-screen (bounding sphere versus viewing frustrum), and
when that happened that robot wasn't parsed. This reduced memory
requirements by ninety percent.
The main weakness of the technique is that if there is a reflective
surface, the reflection in that surface may show objects blinking into
and out of existence. For a small, curved reflective surface, this is
not a problem, but for a flat or gently curved large surface, the
blinking may be too painfully obvious.
Regards,
John
Post a reply to this message
|
|