de.grogra.rgg
Class FluxLightModel

java.lang.Object
  extended by de.grogra.persistence.ShareableBase
      extended by de.grogra.rgg.LightModelBase
          extended by de.grogra.rgg.FluxLightModel
All Implemented Interfaces:
Manageable, Shareable

public class FluxLightModel
extends LightModelBase


The FluxLightModel class provides a spectral light model, used to compute the spectral light distribution in the current graph. The light model is created with one of its constructors.

FluxLightModel lm = new FluxLightModel();

The light model computes the light distribution by simulating many photons through the scene. The total emitted light power is distributed over all photons. The user can specify the maximum number of simulated photons using setRayCount(int). The user can also specify a maximum variance for some given power quantum using setTargetVariance(double, double). The simulation will compute the appropriate sample count to achieve the target variance. Note that this sample count is an overestimation. The light model will select the minimum of both methods as the actual sample count.

Each photon bounces through the scene and any absorbed power is recorded with the objects the photon visits. Besides absorbed power, the simulation also computes sensed irradiance for sensors. Simulating many sensors can be quite costly and can be disabled using setEnableSensors(boolean). The user may specify a maximum path depth to limit the duration of the simulation using setDepth(int). When a simulated photon is almost completely absorbed, further simulation adds little value. Therefore, the user can specify a cutoff power using setCutoffPower(double); As soon as the photon power drops below this threshold, the photon is killed off.

The light model supports three different modes of measuring spectral power. Either it computes regular RGB, a full discretized spectrum or a few weighted integrals over the spectrum. The measure mode is set using #lm.setMeasureMode.

The following code sets the measure mode to RGB. No further settings are required for this mode. RGB is the default measure mode. The computed measurements are 3 dimensional vectors with channels r,g and b.

lm.setMeasureMode(RGB);

The following code sets the measure mode to full discretized spectral measurements. The spectral domain [l,h] is divided into n buckets of equal sized intervals [l + i * (h-l) / n, l + (i + 1) * (h-l) / n]. The simulation computes the absorbed power in each bucket for each measurement. The dimension of the computed measurements equals the number of buckets. The user has to specify the spectral domain using setSpectralDomain(int, int) and the discretization resolution using setSpectralBuckets(int). The user may also supply a continuous spectral importance curve. The curve indicates importance and is used for importance sampling over the continuous spectral domain. Regions of high importance will receive more samples and get a more accurate estimate. The spectral importance curve applies to both the discretized measurement mode and the weighted integral mode discussed next. The curve is defined continuously over the whole spectral domain, even though in discrete spectral mode the measured spectra themselves are not continuous. In the following example, the spectral importance curve shows a peak around 500 nm, resulting in improved measuring accuracy around this wavelength. Note that the importance curve does not alter the expected outcome of the simulation, only the distribution of variance over the spectral domain.

lm.setMeasureMode(FULL_SPECTRUM);

lm.setSpectralDomain(350,720);
lm.setSpectralBuckets(5);

SpectralCurve importanceCurve = new IrregularSpectralCurve( {350,400,450,500,550,720} , {2,2,5,8,4,2} );
lm.setSpectralImportanceCurve( importanceCurve );

The following code sets the measurement mode to weighted integration. The simulation computes weighted integrals over the absorbed power for each measurement. The user has to specify the spectral domain using setSpectralDomain(int, int) and the weight functions using setSpectralWeightCurves(de.grogra.imp3d.spectral.SpectralCurve[]). The user may again specify a spectral importance function. Note however that in weighted integration mode the light model already uses the weight functions for spectral importance sampling.

lm.setMeasureMode(INTEGRATED_SPECTRUM);
lm.setSpectralDomain(350,720);

SpectralCurves [] weightCurve = {
new IrregularSpectralCurve( {350 , 500 , 510 , 520 , 720} , {0,0,1,0,0} ),
new IrregularSpectralCurve( {350 , 600 , 610 , 620 , 720} , {0,0,1,0,0} )
};

lm.setSpectralWeightCurves( weightCurve );

The simulation is executed using compute(). By default, first the scene is built after which the light distribution is computed.

lm.compute();

Rebuilding a large scene can be costly. If the user wishes to simulate the same scene multiple times while only modifying the light sources, the user can instruct the simulation to skip the scene build.

// build the scene and compute the distribution
lm.compute(true,true);

// ... modify light sources here

// compute new distribution without rebuilding the scene.
lm.compute(true,false);

For RGB mode simulations, the simulation results can be obtained for each object trough LightModelBase.getAbsorbedPower3d(de.grogra.graph.impl.Node) and LightModelBase.getSensedIrradiance3d(de.grogra.graph.impl.Node). The user can also get a handle to the corresponding Experiment objects using getAbsorbedPower(de.grogra.graph.impl.Node) and getSensedIrradiance(de.grogra.graph.impl.Node), which contains a mapping from objects to measurements. Multiple experiment objects can be aggregated into one experiment. The following code computes the total absorbed power over the course of one day. All static light sources are simulated only once while the contribution of the sun between 4:00 and 22:00 is integrated using the midpoint rule with time steps of 1 hour. The simulations are aggregated into a single experiment, containing the measured data for one whole day.

// ... enable all static lights
// ... disable the sun

// perform simulation
lm.compute(true,true);
Experiment exp = lm.getAbsorbedPower();

exp.mul( 24 );

// ... disable all static lights
// ... enable the sun

for( int time = 4 ; time < 22 ; time++ )
{
// ... move the sun to its position at [time] + 30 minutes.

// perform simulation
lm.compute(true,false);

// aggregate experiments
Experiment sun_exp = lm.getAbsorbedPower();
exp.aggregate( sun_exp, 1 );
}

// ... use the final aggregates experiment data in exp

Since:
2011.0824
Author:
Dietger van Antwerpen

Nested Class Summary
static class FluxLightModel.Type
           
 
Field Summary
static FluxLightModel.Type $TYPE
           
static SCOType.Field processor$FIELD
           
 
Constructor Summary
FluxLightModel()
          Creates a default light model with 30.000 rays per computation and a ray depth of 10.
FluxLightModel(int sampleCount, int depth)
          Creates a light model
FluxLightModel(int sampleCount, int depth, double cutoffPower)
          Creates a light model
FluxLightModel(int sampleCount, int depth, double cutoffPower, boolean enableSensors)
          Creates a light model
 
Method Summary
 void build()
          Rebuild the scene
 void compute()
          Compute the light distribution
 void compute(boolean forceCompute)
          Compute the light distribution
 void compute(boolean forceCompute, boolean forceBuild)
          (Re-)computes the light distribution in the current graph.
 void compute(Spectrum spectrumFactory)
          (Re-)computes the light distribution in the current graph.
 void compute(Spectrum spectrumFactory, boolean force)
          (Re-)computes the light distribution in the current graph.
 Experiment getAbsorbedPower()
          Returns the experiment data on absorbed power, computed during the last call to compute()
 Spectrum getAbsorbedPower(Node node)
          Returns the radiant power in Watts which is absorbed by the surface of the volume of the given node.
 Measurement getAbsorbedPowerMeasurement(Node node)
          Returns the power absorbed by a node during the last call to compute()
 double getCutoffPower()
           
 int getDepth()
           
 ManageableType getManageableType()
           
 int getMaxLambda()
           
 FluxLightModelTracer.MeasureMode getMeasureMode()
           
 int getMinLambda()
           
 int getRayCount()
           
 Experiment getSensedIrradiance()
          Returns the experiment data on sensed irradiance, computed during the last call to compute()
 Spectrum getSensedIrradiance(Node node)
          Returns the irradiance in Watts per square meter which is sensed by the sensor attached to the volume of the given node.
 Measurement getSensedIrradianceMeasurement(Node node)
          Returns the irradiance sensed by a node during the last call to compute()
 int getSpectralBuckets()
           
 SpectralCurve getSpectralImportanceCurve()
           
 SpectralCurve[] getSpectralWeightCurve()
           
 boolean isSensorsEnabled()
           
 void setCutoffPower(double minPower)
          Sets the maximum neglectable power quantum
 void setDepth(int depth)
          Sets the maximum ray depth per sample
 void setDispersion(boolean dispersion)
          Enables dispersion
 void setEnableSensors(boolean enableSensors)
          Enables the simulation of sensor
 void setFlatness(float flatness)
          Sets the tessellation flatness for polygonizable objects
 void setLayerVisible(int layer, boolean visible)
          sets the visibility of a layer
 void setMeasureMode(FluxLightModelTracer.MeasureMode measureMode)
          Sets the current measurement mode.
 void setMeasureObjectFilter(ObjectFilter measureObjectFilter)
          Sets the object filter for filtering measurable objects.
 void setRayCount(int sampleCount)
          Sets the maximum sample count per simulation
 void setSpectralBuckets(int spectralBuckets)
          Sets the spectrum discretization resolution in buckets.
 void setSpectralDomain(int minLambda, int maxLambda)
          Sets the simulated spectral domain.
 void setSpectralImportanceCurve(SpectralCurve importanceCurve)
          Sets the spectral importance function, used for spectral importance sampling.
 void setSpectralWeightCurves(SpectralCurve[] weightCurves)
          Sets the spectral weight functions
 void setTargetVariance(double minPower, double targetVariance)
          Sets the required maximum target variance for some minimum measurable power quantum.
 
Methods inherited from class de.grogra.rgg.LightModelBase
getAbsorbedPower3d, getRadiantPower3dFor, getRadiantPowerFor, getSensedIrradiance3d
 
Methods inherited from class de.grogra.persistence.ShareableBase
addReference, appendReferencesTo, fieldModified, getProvider, getStamp, initProvider, manageableReadResolve, manageableWriteReplace, removeReference
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

$TYPE

public static final FluxLightModel.Type $TYPE

processor$FIELD

public static final SCOType.Field processor$FIELD
Constructor Detail

FluxLightModel

public FluxLightModel()
Creates a default light model with 30.000 rays per computation and a ray depth of 10.


FluxLightModel

public FluxLightModel(int sampleCount,
                      int depth)
Creates a light model

Parameters:
rayCount - the number of samples per computation
depth - the maximum ray depth

FluxLightModel

public FluxLightModel(int sampleCount,
                      int depth,
                      double cutoffPower)
Creates a light model

Parameters:
rayCount - the number of samples per computation
depth - the maximum ray depth
cutoffPower - the maximum neglectable power quantum

FluxLightModel

public FluxLightModel(int sampleCount,
                      int depth,
                      double cutoffPower,
                      boolean enableSensors)
Creates a light model

Parameters:
rayCount - the number of samples per computation
depth - the maximum ray depth
cutoffPower - the maximum neglectable power quantum
enableSensors - sensors are simulated if true
Method Detail

build

public void build()
Rebuild the scene


compute

public void compute()
Compute the light distribution

Specified by:
compute in class LightModelBase

compute

public void compute(boolean forceCompute)
Compute the light distribution

Specified by:
compute in class LightModelBase
Parameters:
forceCompute - if true forces recomputation of the light distribution

compute

public void compute(boolean forceCompute,
                    boolean forceBuild)
(Re-)computes the light distribution in the current graph.

Parameters:
forceCompute - if true forces recomputation of the light distribution
forceBuild - if true forces rebuilding of the scene

compute

public void compute(Spectrum spectrumFactory)
(Re-)computes the light distribution in the current graph.

Specified by:
compute in class LightModelBase
Parameters:
spectrumFactory - factrory for spectrum objects, not used in Flux light model

compute

public void compute(Spectrum spectrumFactory,
                    boolean force)
(Re-)computes the light distribution in the current graph.

Specified by:
compute in class LightModelBase
Parameters:
spectrumFactory - factrory for spectrum objects, not used in Flux light model
force - if true forces recomputation of the light distribution

getAbsorbedPower

public Experiment getAbsorbedPower()
Returns the experiment data on absorbed power, computed during the last call to compute()

Returns:
absorbed power data

getAbsorbedPower

public Spectrum getAbsorbedPower(Node node)
Description copied from class: LightModelBase
Returns the radiant power in Watts which is absorbed by the surface of the volume of the given node. If the node does not define a volume, the zero spectrum is returned.

Specified by:
getAbsorbedPower in class LightModelBase
Parameters:
node - a node of the graph
Returns:
the absorbed radiant power of the node

getAbsorbedPowerMeasurement

public Measurement getAbsorbedPowerMeasurement(Node node)
Returns the power absorbed by a node during the last call to compute()

Parameters:
node - node for which the absorbed power is returned
Returns:
absorbed power

getCutoffPower

public double getCutoffPower()
Returns:
returns the maximum neglectable power quantum

getDepth

public int getDepth()
Returns:
returns the maximum rays depth per sample

getManageableType

public ManageableType getManageableType()

getMaxLambda

public int getMaxLambda()
Returns:
returns the upper boundary of the simulated spectrum domain

getMeasureMode

public FluxLightModelTracer.MeasureMode getMeasureMode()
Returns:
returns the current measure mode

getMinLambda

public int getMinLambda()
Returns:
returns the lower boundary of the simulated spectrum domain

getRayCount

public int getRayCount()
Returns:
returns the maximum sample count per compute

getSensedIrradiance

public Experiment getSensedIrradiance()
Returns the experiment data on sensed irradiance, computed during the last call to compute()

Returns:
sensed irradiance data

getSensedIrradiance

public Spectrum getSensedIrradiance(Node node)
Description copied from class: LightModelBase
Returns the irradiance in Watts per square meter which is sensed by the sensor attached to the volume of the given node. If the node does not define a volume with a sensor, the zero spectrum is returned.

Specified by:
getSensedIrradiance in class LightModelBase
Parameters:
node - a node of the graph
Returns:
the sensed irradiance of the node

getSensedIrradianceMeasurement

public Measurement getSensedIrradianceMeasurement(Node node)
Returns the irradiance sensed by a node during the last call to compute()

Parameters:
node - node for which the absorbed power is returned
Returns:
sensed irradiance

getSpectralBuckets

public int getSpectralBuckets()
Returns:
returns the spectrum discretization resolution in buckets

getSpectralImportanceCurve

public SpectralCurve getSpectralImportanceCurve()
Returns:
returns the spectral importance function

getSpectralWeightCurve

public SpectralCurve[] getSpectralWeightCurve()
Returns:
returns the spectral weight functions

isSensorsEnabled

public boolean isSensorsEnabled()
Returns:
returns true if sensors are enabled

setCutoffPower

public void setCutoffPower(double minPower)
Sets the maximum neglectable power quantum

Parameters:
minPower - maximum neglectable power quantum

setDepth

public void setDepth(int depth)
Sets the maximum ray depth per sample

Parameters:
depth - maximum ray depth per sample

setDispersion

public void setDispersion(boolean dispersion)
Enables dispersion

Parameters:
dispersion - true enables dispersion

setEnableSensors

public void setEnableSensors(boolean enableSensors)
Enables the simulation of sensor

Parameters:
enableSensors - true enables the sensors

setFlatness

public void setFlatness(float flatness)
Sets the tessellation flatness for polygonizable objects

Parameters:
flatness - positive flatness parameter with 0 being infinite tessellation.

setLayerVisible

public void setLayerVisible(int layer,
                            boolean visible)
Description copied from class: LightModelBase
sets the visibility of a layer

Specified by:
setLayerVisible in class LightModelBase

setMeasureMode

public void setMeasureMode(FluxLightModelTracer.MeasureMode measureMode)
Sets the current measurement mode. There are three possible measurement modi. FULL_SPECTRUM: Measure the full spectral range, specified using setSpectralDomain(int, int). The spectral resolution is specified using INTEGRATED_SPECTRUM: Measure weighted spectral integrals, specified using setSpectralWeightCurves(de.grogra.imp3d.spectral.SpectralCurve[]) RGB: Measure RGB values Spectral dispersion only applies to FULL_SPECTRUM and INTEGRATED_SPECTRUM and may be enabled using setDispersion(boolean)

Parameters:
measureMode - measurement mode

setMeasureObjectFilter

public void setMeasureObjectFilter(ObjectFilter measureObjectFilter)
Sets the object filter for filtering measurable objects. All objects will participate in the simulation but the absorbed power is only computed for the filtered objects

Parameters:
measureObjectFilter - Object filter

setRayCount

public void setRayCount(int sampleCount)
Sets the maximum sample count per simulation

Parameters:
sampleCount - maximum sample count

setSpectralBuckets

public void setSpectralBuckets(int spectralBuckets)
Sets the spectrum discretization resolution in buckets. Measured discretized spectral distributions are represented by buckets, dividing the spectral domain in equal sized intervals

Parameters:
spectralBuckets - bucket resolution

setSpectralDomain

public void setSpectralDomain(int minLambda,
                              int maxLambda)
Sets the simulated spectral domain. The domain is assumed to be non-empty

Parameters:
minLambda - lower boundary wavelength
maxLambda - upper boundary wavelength

setSpectralImportanceCurve

public void setSpectralImportanceCurve(SpectralCurve importanceCurve)
Sets the spectral importance function, used for spectral importance sampling. The spectral importance function indicates regions of interest within the spectral domain. Setting an importance function does not alter the expected outcome, but may influence the distribution of variance in the spectral domain.

Parameters:
importanceCurve - spectral importance functions

setSpectralWeightCurves

public void setSpectralWeightCurves(SpectralCurve[] weightCurves)
Sets the spectral weight functions

Parameters:
weightCurves - array of spectral weight functions

setTargetVariance

public void setTargetVariance(double minPower,
                              double targetVariance)
Sets the required maximum target variance for some minimum measurable power quantum. When calling compute(), the simulation computes the minimum number of samples required to achieve the maximum target variance #targetVariance on any measurement of at least #minPower for the given scene.

Parameters:
minPower - minimal measurable power quantum
targetVariance - maximum target variance