Class GlobalIllumination

java.lang.Object
eu.svjatoslav.sixth.e3d.renderer.raster.gi.GlobalIllumination
All Implemented Interfaces:
GiLightProvider

public class GlobalIllumination extends Object implements GiLightProvider
Progressive CPU global illumination, running on dedicated low-priority threads (never on the render ForkJoinPool).

Two sampling resolutions:

  • Lightmapped triangles (LightmappedShape, e.g. BSP fragments of a lightmapping-enabled BspCompositeShape): per-texel sampling. Shadows and gradients live INSIDE the polygon surface; the painted texture is the premultiplied composite (baseColor x ambient+direct+indirect), regenerated on GI threads and swapped in double-buffered — painters never see a half-updated texture.
  • Plain solid polygons: per-polygon sampling; the result feeds the flat-shading path through GiLightProvider (shadow tests + indirect add). Polygons stay single-colored.

Estimator: each sample casts one cosine-weighted hemisphere ray from the surface. At the hit it evaluates direct light with cached shadow tests (next-event estimation) plus the hit surface's current indirect estimate, so bounce light propagates deeper over sweeps without an explicit recursion limit. Two nested exponential moving averages shape what the user sees: the inner per-sample EMA smooths Monte Carlo noise in the indirect term, and the outer per-composite-update EMA wraps the complete sum ambient+direct+indirect with a fixed alpha — lightmaps start at a uniform medium irradiance and glide to the traced solution (lit areas brighten, unlit areas sink to darkness), so no black-to-lit flash or shadow pop is possible. Scene or light changes rebuild the snapshot and restart convergence. When converged, workers idle at a low cadence instead of burning CPU.

Render-side cost: zero ray casting. Lightmapped triangles paint from their current composite texture; the flat-shading path only reads cached per-polygon values. Frame rate is unaffected by GI quality.

Limitations: diffuse light only; polygon vertices are used in composite-local space, so scenes combining composites with non-identity transforms are traced incorrectly.

Usage:


 GlobalIllumination gi = viewPanel.enableGlobalIllumination(); // 2 threads
 
  • Constructor Summary

    Constructors
    Constructor
    Description
    GlobalIllumination(ShapeCollection shapes, LightingManager lightingManager, int threadCount)
    Creates the GI system.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    addIndirectLight(SolidPolygon polygon, Color baseColor, Color result)
    Adds the polygon's indirect (bounced light) contribution to an already computed direct-lighting color, in place.
    int
    Returns the number of work items in the current scene snapshot (one per lightmap texel plus one per plain polygon), or 0 when no snapshot has been built yet.
    boolean
    Returns whether the solution has converged (workers idling at a low duty cycle).
    boolean
    Tells whether a light source currently has an unobstructed path to the polygon.
    boolean
    Returns whether the GI worker threads are running.
    void
    Registers the GI provider and starts the worker threads.
    void
    Stops the worker threads and unregisters the provider.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • GlobalIllumination

      public GlobalIllumination(ShapeCollection shapes, LightingManager lightingManager, int threadCount)
      Creates the GI system. Call start() to begin tracing.
      Parameters:
      shapes - the scene to trace
      lightingManager - the lights to sample
      threadCount - dedicated worker threads (2 is a good default)
  • Method Details

    • start

      public void start()
      Registers the GI provider and starts the worker threads.
    • stop

      public void stop()
      Stops the worker threads and unregisters the provider.
    • isRunning

      public boolean isRunning()
      Returns whether the GI worker threads are running.
      Returns:
      true after start() and before stop()
    • isConverged

      public boolean isConverged()
      Returns whether the solution has converged (workers idling at a low duty cycle). Convergence is declared after five consecutive composite updates whose average per-texel estimate movement is below e3d.gi.calmThreshold (default 1.0 light unit).
      Returns:
      true when converged
    • getWorkItemCount

      public int getWorkItemCount()
      Returns the number of work items in the current scene snapshot (one per lightmap texel plus one per plain polygon), or 0 when no snapshot has been built yet.
      Returns:
      the work item count
    • isLightVisible

      public boolean isLightVisible(SolidPolygon polygon, LightSource light)
      Description copied from interface: GiLightProvider
      Tells whether a light source currently has an unobstructed path to the polygon. Until the provider has computed the answer, it should return true (light visible): shadows then fade in gradually instead of popping out.
      Specified by:
      isLightVisible in interface GiLightProvider
      Parameters:
      polygon - the shaded polygon
      light - the light source being evaluated
      Returns:
      true if the light reaches the polygon
    • addIndirectLight

      public void addIndirectLight(SolidPolygon polygon, Color baseColor, Color result)
      Description copied from interface: GiLightProvider
      Adds the polygon's indirect (bounced light) contribution to an already computed direct-lighting color, in place.
      Specified by:
      addIndirectLight in interface GiLightProvider
      Parameters:
      polygon - the shaded polygon
      baseColor - the polygon's unlit color (for albedo scaling)
      result - the direct-lighted color to augment (modified in place)