Re: Methods for generating shadows in vissims

New Message Reply Date view Thread view Subject view Author view

Angus Dorbie (angus++at++division.demon.co.uk)
Wed, 25 Jan 1995 20:35:42 +0000


Hi Evan, there are lots of methods for producing the sort of cheap shadow you
seem to require. I'll describe one which addresses your concerns about the
correct decaling of complex shadows intersecting with a complex ground plane,
including terrain, buildings and other aircraft. It uses stencil buffer
techniques described in an old issue of IRIS Universe from many moons ago. I
have since lost the issue and forgotten the authors name & bibliography
(sorry).

o The technique involves generating a 2D shape in the stencil buffer
   which corresponds to the intersection of the shadow with the ground
   geometry then writing some shadow colour exclusively to this region.
   Similar but more complex multi-pass techniques exist but they are
   probably to costly for most vis sim.

o Firstly you require some stencil planes as part of your framebuffer
   configuration. This is only possible with some graphics options.

   The third argument in mssize() will give you stencil planes on REs and
   the call stensize() with other options. I think performer configures
   with stencil planes in pfInitGfx().

   If your shadow shape is convex you will need a single stencil plane
   if it's concave you will need more than one. How many depends on how
   many overlaps the plane extrusion will generate when drawn but 2
   bitplanes should do for a single aircraft.

o The generation of the 2D intersection shape is performed after the
   rendering of the entire scene to the framebuffer. This leaves the
   depth in the zbuffer.
   You can draw the aircrafts shadow geometry to the stencil buffer
   while performing a zbuffer check against the scene geometry. This
   works because you can draw the planes shadow geometry backfacing
   (culling frontfacing polys) with a stencil increment operation, then
   draw the planes shadow geometry frontfacing (culling backfacing polys)
   with a stencil decrement operation. The net effect is that you are
   left with non-zero values in the stencil buffer where there are
   shadows.

   The shadow geometry can be a vertical extrusion of the aircraft
   positioned through the ground, make sure that it extends through the
   entire geometry you want to intersect with. You can keep this geometry
   quite short to limit the number of pixels you have to write but you
   then have to place a top on the extrusion.
   Better results can be obtained by extruding the shadow through the
   light vector for the sun, and/or calculating the correct aircraft
   outline (not always that simple).

   In your pre draw for the backface shadow you should call:

   stencil(TRUE, 0, SF_ALWAYS, 0x00, ST_KEEP, ST_KEEP, ST_INCR);
   zwritemask(0x00000000);
   RGBwritemask(0x00, 0x00, 0x00);

   and in your post draw call:

   stencil(FALSE, 0, SF_ALWAYS, 0x00, ST_KEEP, ST_KEEP, ST_INCR);
   zwritemask(0xFFFFFFFF);
   RGBwritemask(0xFF, 0xFF, 0xFF);

   For your front face pre draw you need to call:

   stencil(TRUE, 0, SF_ALWAYS, 0x00, ST_KEEP, ST_KEEP, ST_DECR);
   zwritemask(0x00000000);
   RGBwritemask(0x00, 0x00, 0x00);

   and in your post draw call:

   stencil(FALSE, 0, SF_ALWAYS, 0x00, ST_KEEP, ST_KEEP, ST_DECR);
   zwritemask(0xFFFFFFFF);
   RGBwritemask(0xFF, 0xFF, 0xFF);

   These mode changes may conflict with some performer voo-doo but
   hopefully not under most circumstances.

o You then need to draw a shadow to the stencil area you've just created.
   A simple way is to draw the frontfacing shadow geometry again but keep
   it transparent and don't disable writes to the colourbuffer. This will
   work with screendoor transparency but may cause problems when blending
   with concave outlines. When blending, only convex geometry which
   covers the entire shadow should be used for this stage.

   The shadow geometry should be suitably coloured and requires pre draw:

   stencil(TRUE, 0, SF_GREATER, 0xFF, ST_KEEP, ST_KEEP, ST_ZERO);
   zwritemask(0x00000000);

   and post draw:

   stencil(FALSE, 0, SF_GREATER, 0xFF, ST_KEEP, ST_KEEP, ST_ZERO);
   zwritemask(0xFFFFFFFF);

o The ST_ZERO argument above should save you having to perform an sclear(0)
   every frame but I've never tried this. You should still clear the stencil
   planes first time in.

Have fun and good luck. Sorry if there are any mistakes in the stencil calls.

-- 
 Angus Dorbie                Division Ltd,
 Software Engineer           19 Apex Court,
 Tel: (01454)615554          Woodlands,
 Fax: (01454)615532          Bristol BS12 4JT,
 angus++at++division.demon.co.uk  UK

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:50:53 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.