[BACK]Return to README CVS log [TXT][DIR] Up to [Development] / performer / src / lib / libpfdb / libpfspherepatch3

File: [Development] / performer / src / lib / libpfdb / libpfspherepatch3 / README (download)

Revision 1.1, Tue Nov 21 21:39:35 2000 UTC (16 years, 11 months ago) by flynnt
Branch: MAIN
CVS Tags: HEAD

Initial check-in based on OpenGL Performer 2.4 tree.
-flynnt

This directory contains the source for the new improved .spherepatch loader.

IMPROVEMENTS AND BUGS FIXED since Performer 2.2's .spherepatch loader:
=====================================================================

    - Adaptive morphing tessellation-- when the eye is sufficiently close
      to the surface, only a 30x30 square grid is rendered, covering
      only the area above the horizon.  When the eye is sufficiently
      far away, the tesselation is static, thereby avoiding
      annoying "texture swimming" artifacts inherent when morphing
      large primitives under a very non-linear texture mapping.
        (The 2.2 version used static geometry, requiring
	the application to work around the very inexact
	surface approximation when the eye was very close to the surface.)

    - Full use of virtual clip textures (up to 31 levels, i.e. 1 billion
      by 1 billion) without ever showing garbage on the horizon.
      Geometry for rendering is divided into concentric
      "clip rings" according to distance from the clip center
      in texture space; each clip ring sets its own
      value of virtualLODOffset and numEffectiveLevels
      (see /usr/share/Performer/doc/clipmap/HowToDoVirtual.{html,txt}
      for details of this technique).
        (The 2.2 version used static geometry so this was infeasible.)

    - No cracks between adjacent patches, regardless
      of relative patch sizes or alignment.
        (The 2.2 version's stitching algorithm required one patch's
        segment length to be a multiple of the other adjacent ones,
        and that the two patches be aligned perfectly).
      This is accomplished by draping all the patches over a single
      common geometry (recalculated each frame), so that all incident patches
      will get the same coordinates at T-vertices.

    - Input file format allows later patches to "overlap"
      earlier ones; subdivision of the remaining visible
      area of the occluded patch is done automatically
      during input processing.
        (The 2.2 version required the user to manually
        divide the remaining visible area of a partially occluded
	patch into rectangular pieces and express the pieces
	explicitly in the input file).

    - Uses a pfDoubleDCS to express a local origin at the eye (changes
      every frame) so that vertices can be calculated and expressed
      as single precision floats (as required by OpenGL) without
      loss of precision.
	 (NOTE:  This is only implemented when compiled with
	  a Performer library which defines the pfDoubleDCS type.
	  This will be in a future Performer release (later than 2.2.2)).

FILE FORMAT CHANGES:
===================

    Old .spherepatch files are still understood.

    The file format is the same except that
    the old parameters "lonsegs" and "latsegs" are ignored;
    now only a pair of global values are used for the whole sphere
    (see the description of _PFSPHEREPATCH_MAXSEGSLON
    and _PFSPHEREPATCH_MAXSEGSLAT below).

    A special texture name "NULL" (without quotes) is allowed when
    specifying a patch; this means the patch is not to be rendered,
    but its extent is used to occlude (cut a hole in)
    all previously defined patches.

THE TESSELLATION ALGORITHM:
=========================

    The algorithm depends on four parameters
    which can be set via environment variables (see below for the names)
    or at runtime:
	MAXSEGSLON (default 72, i.e. 5 degree increments)
	MAXSEGSLAT (default 36, i.e. 5 degree increments)
	MINSEGSLON (default 30)
	MINSEGSLAT (default 30)
    MAXSEGSLON,MAXSEGSLAT specifies the finest subdivision
    to which the whole sphere will ever be tessellated.
    MINSEGSLON,MINSEGSLAT determines the smallest number
    of subdivisions that will ever be used to cover the bounding rectangle
    (in lon,lat space) of the currently visible (above-horizon) disk.
    Every frame, a new tessellation is calculated based on
    the current eye point.  The tessellation is always a quad mesh
    covering the bounding rectangle of the currently visible spherical disk;
    the fineness of this mesh is always chosen to be the finer
    of the two choices:
	(1) Subdivide the whole sphere into MAXSEGSLON,MAXSEGSLAT parts
	(2) Subdivide the visible disk's bounding rectangle
	    into MINSEGSLON,MINSEGSLAT parts.
    I.e. when the eye is sufficiently far away, method (1)
    will be used and the tessellation will seem static;
    but when the eye gets sufficiently close, method (2) will
    be used and the mesh will appear to morph (the grid squares
    get smaller as you zoom in).

    Note that even with the above algorithm using MINSEGSLON,MINSEGSLAT,
    the grid squares don't get small enough "fast enough"
    to allow partitioning into usable clip rings--
    the smallest clip ring *must* be less than 24K texels at the
    finest texture LOD that will be used for it,
    but it is desirable to make that size even smaller,
    even less than 4K texels, to combat the "Jello" effect
    (see /usr/share/Performer/doc/clipmap/IRClipmapBugs.{html,txt}).
    Therefore a minimum grid square size in screen space is enforced;
    this is currently hard coded to be about 2Kx2K pixels
      (NOTE: this assumes an FOV of about 45 degrees; the minimum size
      will be less or more than 2Kx2K pixels depending on whether
      the FOV is set to more or less than 45 degrees respectively; this means
      it will do wrong bad things if you set the FOV to be very small!)

    So if both methods (1) and (2) would produce quads that are too big
    by this criterion, a third method is used:
	(3) Subdivide the visible disk's bounding rectangle
	    by MINSEGSLON,MINSEGSLAT with nonuniform grid spacing,
	    so that the grid spacing is uniform and of the
	    required minimum size near the center
	    (closest point to the eye), but smoothly becomes an
	    exponential expansion further out near the edges
	    of the rectangle.
    This nonuniform grid spacing is described by a smooth increasing
    "linear-exponential" function mapping [0..1] to [0..1]
    (where 0 denotes the center, 1 denotes the outer edge of the visible disk)
    i.e. a function that is linear on [0..k] and exponential on [k..1]
    for some k, and is smooth (i.e. derivative is continuous).
    Given any desired slope for the linear part (i.e. the desired
    grid spacing at the center) there is a unique linear-exponential
    function whose initial linear part has the desired slope.
    The file spherepatchwarp.h defines a class which implements
    such a warp (the tricky part is finding the parameters of the exponential
    part given the slope of the linear part).

    If you zoom in slowly from outer space and pay attention,
    you can see the transition between methods (1), (2), and (3):
    (1) looks like a static tessellation, (2) looks like
    the grid squares are slowly shrinking with the zoom
    (but not enough to keep pace with it), and (3) looks
    like the shrinking near the center has
    accelerated to exactly keep pace with the zoom (i.e.
    the grid squares stay the constant minimum size in screen space),
    but the grid squares out on the horizon are expanding
    to compensate, to keep the total number of grid squares constant.

    Theoretically even method (3) would be inadequate for *really*
    big clipmaps (the exponential warp would become too extreme,
    making the ratio between consecutive clip ring sizes
    too big for the clip rings to be effective).
    However it is quite adequate for the largest clipmaps currently
    available, which have 32 levels (1 billion texels squared).
    

ENVIRONMENT VARIABLES:
=====================

  Setting a variable to the empty string is the same as setting it to "1".

  Environment variables that are static for the life of the program:

    int _PFSPHEREPATCH_MAXSEGSLON (default 72, i.e. 5 degree increments)
    int _PFSPHEREPATCH_MAXSEGSLAT (default 36; i.e. 5 degree increments)
	These are the MAXSEGSLON,MAXSEGSLAT parameters
	of the tessellation algorithm, as described above.
	When the eye is sufficiently far away,
	the geometry will appear to be a static
	tessellation by these amounts.

    int _PFSPHEREPATCH_MINSEGSLON (default 30)
    int _PFSPHEREPATCH_MINSEGSLAT (default 30)
	These are the MINSEGSLON,MINSEGSLAT parameters
	of the tessellation algorithm, as described above.
	The lon,lat bounding box of the visible disk
	is always covered by a rectangular grid
	with at least this many quads.

    double _PFSPHEREPATCH_RADIUS (default 1.)
	The radius of the entire sphere.

    float _PFSPHEREPATCH_RINGRATIO (default 2.)
	This is the ratio between the sizes of adjacent
	concentric square clip rings in texture space.
	A smaller value may increase the effectiveness
	of the clip rings, at the expense of more memory.
	I think about 4 or 8 is about as high as you can go before
	you will definitely see artifacts (excessive blurriness
	in the foreground or garbage on the horizon, depending
	on the value of _PFSPHEREPATCH_TRADEOFF, see below).

    int _PFSPHEREPATCH_NRINGS (default -1, i.e. automatically calculate it)
	If set, this many square clip rings are used, starting
	with a radius of 1 (in texture space), and decreasing
	in size geometrically by increments of _PFSPHEREPATCH_RINGRATIO.
	When left at the default value -1,
	the number of rings is calculated
	(based on _PFSPHEREPATCH_RINGRATIO) so that
	the smallest ring is approximately twice the size of
	as the centermost grid square
	(so that it will cover that grid square regardless of how
	the grid is currently offset with respect to the clip rings, which
	are centered exactly at the eye).

    int _PFSPHEREPATCH_TTYINPUT (default 0)
	If this variable is set, then the remaining variables
	listed below can be changed at runtime
	by issuing commands to the program's stdin,
	which is polled and read by an APP callback function every frame.
	Type "help" or "?" for a list of abbreviated
	names for these variables.
	Note that this variable is *NOT* set by default,
	since it will behave badly if the calling application does any
	input processing of its own (perfly and clipfly don't,
	so you can set this variable when you use them).

  Environment variables that can be changed via stdin
  at runtime if env _PFSPHEREPATCH_TTYINPUT is set:

    int _PFSPHEREPATCH_DEBUG (default 0)
	If set, debugging messages
	will be issued via pfNotify() at the PFNFY_NOTICE level
	every frame, describing each clip ring,
	the virtual clip texture parameters used for that ring,
	and how those parameters were chosen.

    double _PFSPHEREPATCH_PATCHSHRINK (default 1.)
	If set to a positive value < 1, each rectangular patch
	(after dividing the input patches as necessary due to occlusion)
	will be shrunk around its center in lon,lat space by this amount.
	A value of about .99 is useful to show the separation between the
	patches.

    double _PFSPHEREPATCH_GLOBALSHRINK (default 1.)
	If set to a positive value < 1, the lon,lat coordinates
	of all the patches are shrunk by this amount.
	This is useful for viewing all the patches at once
	in a more planar-like space
	(i.e. without having to rotate the model to see patches that are
	on the far side).
	(XXX BUG: Values of .2 or less have been known to
	result in assertion failures.  I usually use .3)

    int _PFSPHEREPATCH_NO_TRANSLATE (default 0)
	If set, the pfDoubleDCS is not used (its
	translation is always set to 0).
	You can turn this variable on and off at runtime
	to demonstrate the instability caused by using
	single precision vertex coords in a single global coordinate space.

    int _PFSPHEREPATCH_NO_PRECISION_HACK (default 0)
	By default, all texture coordinates for virtual clipmaps
	are translated as far as possible towards 0,0
	by a multiple of the "good area" size
	determined by the current choice of the
	virtualLODOffet,numEffectiveLevels parameters.
	These parameters and the translated tex coords
	are calculated in a node CULL callback.
	You can turn this variable on and off at runtime
	to demonstrate the instability caused by using
	single precision texture coords in a single global texture space.

     float _PFSPHEREPATCH_TRADEOFF (default 1, i.e. blurry rather than garbage)
	This is the "tradeoff" parameter passed to
	the pfuCalcVirtualClipTexParams() function for each clip ring.
	This parameter specifies what should be done when
	the required range of texture LODs for the clip ring is bigger
	than the maximum numEffectiveLevels (16 on InfiniteReality graphics);
	i.e. when there is no possible value of virtualLODOffset
	that gives the necessary high resolution in the foreground
	while covering the entire area of the clip ring.
	A tradeoff value of 0. means "go fine", i.e.  always choose
	a virtualLODOffset which gives the desired high resolution,
	at the expense of area (possibly showing garbage on the horizon).
	A tradeoff value of 1. means "go coarse" i.e.
	always show the full area at the expense of resolution
	(i.e. the foreground may appear excessively blurry).
	A tradeoff value between 0 and 1 means choose
	virtualLODOffset somewhere between these two extremes,
	roughly proportional to the value given.
	NOTE:  This variable should not make any difference
	   unless you have explicitly changed the values of the variables
	   _PFSPHEREPATCH_MINSEGS{LAT,LON},
	   _PFSPHEREPATCH_RINGRATIO or _PFSPHEREPATCH_NRINGS.
	   With the default values of those variables,
	   the clip rings will be evenly spaced and numerous
	   enough to keep any tradeoff from being necessary.