|
|
Christian Froeschlin wrote:
> Nice. I suppose only the trees are billboards?
Thank you; yes.
> Can this technique produce shadows as well?
Yes, but the shadows look increasingly wrong when the lightsource is at
right angles to the viewing direction. The light "sees" the billboards
from the side instead of face-on. Ground-level renders fare better
because shadows get thin anyway, but overall I prefer to leave shadows off.
Shadows could probably be rendered in a separate pass by facing the
billboards at the light and then compositing them back, but there's a
point where the complexity of setting that up weighs against the
simplicity of just using actual geometry (and it defeats the point of a
raytracer to employ scanline-style workarounds). You could use cross
billboards too.
The savings in memory and bounding-tree traversal are probably not high
enough (or perhaps don't matter in these days of powerful hardware) to
use billboards primarily, but I find them very helpful when prototyping
because it's usually easier to get a picture than a model, and pictures
are more portable between different renderers, gallery building is easy,
etc. It's nice to have the option of dropping in billboards for any
models that I don't have available yet -- I can quickly storyboard a
scene, play with ideas, etc. before committing to making or finding the
real geometry.
Joerg Schrammel's (Genesis Toolkit) work with textured cones is a neat
in-between approach, which requires less (or no) camera-facing of trees
and can cast reasonable shadows. The downside is that the textures are a
little trickier to set up.
Mixing geometry with billboards is done to good effect for some trees.
Trunk and branches are 3D but leaf clusters are billboards. They are
rotated fully to camera-face (not just around the Y axis), and it's easy
to sway them in animations to simulate wind. They also light better.
Some script code to experiment with:
// Some arrays go here, e.g., to define textures, texture lookup,
// billboard size/position, etc.
// The texture below is an example of one texture declaration.
#declare App_rect_texture[0] =
texture
{
pigment
{
image_map
{
png "tree.png" map_type 0 interpolate 2 once
}
translate x * -0.5
}
finish { ambient 0.5 }
}
// App_cam_pos is normally assigned from an array of camera positions
// defined for an animation, e.g.,
#declare App_cam_pos = App_cam_positions[Current_frame_index];
#declare I = 0;
#while(I < App_number_of_objects)
// I use a quad poly, but a two-tri mesh would work too.
// I specified five instead of four points because otherwise
// one gets a lot of "open poly; closing" warnings.
polygon
{
5, <-0.5, 0>, <-0.5, 1>, <0.5, 1>, <0.5, 0>, <-0.5, 0>
no_shadow // At your discretion. One could compute
// a per-object lightsource angle and selectively
// enable shadows for a threshold, or dupe the billboard
// at right angles to itself (e.g., cross billboard).
texture { App_texture[App_texture_index[I]] }
// If you have several textures, put them in an
// App_texture array, and then use an
// App_texture_index array to translate object IDs
// to textures.
scale App_rect_size[I]
// XY scale from unit square.
// App_rect_size[I].z should always be 1.0
#if(App_rect_billboard[I])
// Cam-facing logic; rotates billboard only
// around the Y axis.
#declare App_v = App_cam_pos - App_rect_pos[I];
#declare App_v = vnormalize(<App_v.x, 0, App_v.z>);
#declare App_a = degrees(acos(vdot(App_v, <0,0,-1>)));
#if(App_v.x > 0)
#declare App_a = App_a * -1;
#end
rotate y * App_a
#end
translate App_rect_pos[I]
}
#declare I = I + 1;
#end
Ray
Post a reply to this message
|
|