java.lang.Object
de.grogra.persistence.ShareableBase
de.grogra.rgg.LightModelBase
de.grogra.rgg.FluxLightModel
- All Implemented Interfaces:
Manageable
,Shareable
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 {@link #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.gpuflux.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);
SpectralCurve [] 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
- Version:
- 1.0
- Author:
- Dietger van Antwerpen <dietger@xs4all.nl>
-
Nested Class Summary
Nested Classes -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionCreates a default light model with 30.000 rays per computation and a ray depth of 10.FluxLightModel
(int sampleCount, int depth) Creates a light modelFluxLightModel
(int sampleCount, int depth, double cutoffPower) Creates a light modelFluxLightModel
(int sampleCount, int depth, double cutoffPower, boolean enableSensors) Creates a light model -
Method Summary
Modifier and TypeMethodDescriptionvoid
build()
Rebuild the scenevoid
compute()
Compute the light distributionvoid
compute
(boolean forceCompute) Compute the light distributionvoid
compute
(boolean forceCompute, boolean forceBuild) (Re-)computes the light distribution in the current graph.void
(Re-)computes the light distribution in the current graph.void
(Re-)computes the light distribution in the current graph.Returns the experiment data on absorbed power, computed during the last call tocompute()
getAbsorbedPower
(Node node) Returns the radiant power in Watts which is absorbed by the surface of the volume of the givennode
.Returns the power absorbed by a node during the last call tocompute()
double
int
getDepth()
int
int
int
int
Returns the experiment data on sensed irradiance, computed during the last call tocompute()
getSensedIrradiance
(Node node) Returns the irradiance in Watts per square meter which is sensed by the sensor attached to the volume of the givennode
.Returns the irradiance sensed by a node during the last call tocompute()
int
boolean
void
setCutoffPower
(double minPower) Sets the maximum neglectable power quantumvoid
setDepth
(int depth) Sets the maximum ray depth per samplevoid
setDispersion
(boolean dispersion) Enables dispersionvoid
setEnableSensors
(boolean enableSensors) Enables the simulation of sensorvoid
setFlatness
(float flatness) Sets the tessellation flatness for polygonizable objectsvoid
setLayerVisible
(int layer, boolean visible) sets the visibility of a layervoid
setMeasureMode
(FluxLightModelTracer.MeasureMode measureMode) Sets the current measurement mode.void
setMeasureObjectFilter
(ObjectFilter measureObjectFilter) Sets the object filter for filtering measurable objects.void
setRandomseed
(int seed) Sets the random seed for the random number generatorvoid
setRandomSeed
(int value) sets the random seedvoid
setRayCount
(int sampleCount) Sets the maximum sample count per simulationvoid
setSeed
(int value) sets the random seedvoid
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 functionsvoid
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
-
Field Details
-
$TYPE
-
processor$FIELD
-
-
Constructor Details
-
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 computationdepth
- the maximum ray depth
-
FluxLightModel
public FluxLightModel(int sampleCount, int depth, double cutoffPower) Creates a light model- Parameters:
rayCount
- the number of samples per computationdepth
- the maximum ray depthcutoffPower
- 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 computationdepth
- the maximum ray depthcutoffPower
- the maximum neglectable power quantumenableSensors
- sensors are simulated if true
-
-
Method Details
-
getManageableType
-
isSensorsEnabled
public boolean isSensorsEnabled()- Returns:
- returns true if sensors are enabled
-
getDepth
public int getDepth()- Returns:
- returns the maximum rays depth per sample
-
getRandomSeed
public int getRandomSeed()- Returns:
- returns the random seed
-
setRandomSeed
public void setRandomSeed(int value) sets the random seed -
setSeed
public void setSeed(int value) sets the random seed -
getRayCount
public int getRayCount()- Returns:
- returns the maximum sample count per compute
-
getMinLambda
public int getMinLambda()- Returns:
- returns the lower boundary of the simulated spectrum domain
-
getMaxLambda
public int getMaxLambda()- Returns:
- returns the upper boundary of the simulated spectrum domain
-
getSpectralBuckets
public int getSpectralBuckets()- Returns:
- returns the spectrum discretization resolution in buckets
-
getCutoffPower
public double getCutoffPower()- Returns:
- returns the maximum neglectable power quantum
-
getMeasureMode
- Returns:
- returns the current measure mode
-
getSpectralWeightCurve
- Returns:
- returns the spectral weight functions
-
getSpectralImportanceCurve
- Returns:
- returns the spectral importance function
-
setEnableSensors
public void setEnableSensors(boolean enableSensors) Enables the simulation of sensor- Parameters:
enableSensors
- true enables the sensors
-
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
-
setRandomseed
public void setRandomseed(int seed) Sets the random seed for the random number generator- Parameters:
seed
-
-
setRayCount
public void setRayCount(int sampleCount) Sets the maximum sample count per simulation- Parameters:
sampleCount
- maximum sample count
-
setSpectralWeightCurves
Sets the spectral weight functions- Parameters:
weightCurves
- array of spectral weight functions
-
setSpectralImportanceCurve
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
-
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
-
setMeasureMode
Sets the current measurement mode. There are three possible measurement modi. FULL_SPECTRUM: Measure the full spectral range, specified usingsetSpectralDomain(int, int)
. The spectral resolution is specified using INTEGRATED_SPECTRUM: Measure weighted spectral integrals, specified usingsetSpectralWeightCurves(de.grogra.gpuflux.imp3d.spectral.SpectralCurve[])
RGB: Measure RGB values Spectral dispersion only applies to FULL_SPECTRUM and INTEGRATED_SPECTRUM and may be enabled usingsetDispersion(boolean)
- Parameters:
measureMode
- measurement mode
-
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 wavelengthmaxLambda
- upper boundary wavelength
-
setTargetVariance
public void setTargetVariance(double minPower, double targetVariance) Sets the required maximum target variance for some minimum measurable power quantum. When callingcompute()
, 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 quantumtargetVariance
- maximum target variance
-
setDispersion
public void setDispersion(boolean dispersion) Enables dispersion- Parameters:
dispersion
- true enables dispersion
-
setFlatness
public void setFlatness(float flatness) Sets the tessellation flatness for polygonizable objects- Parameters:
flatness
- positive flatness parameter with 0 being infinite tessellation.
-
setMeasureObjectFilter
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
-
build
public void build()Rebuild the scene -
compute
public void compute()Compute the light distribution- Specified by:
compute
in classLightModelBase
-
compute
public void compute(boolean forceCompute) Compute the light distribution- Specified by:
compute
in classLightModelBase
- 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 distributionforceBuild
- if true forces rebuilding of the scene
-
compute
(Re-)computes the light distribution in the current graph.- Specified by:
compute
in classLightModelBase
- Parameters:
spectrumFactory
- factrory for spectrum objects, not used in Flux light model
-
compute
(Re-)computes the light distribution in the current graph.- Specified by:
compute
in classLightModelBase
- Parameters:
spectrumFactory
- factrory for spectrum objects, not used in Flux light modelforce
- if true forces recomputation of the light distribution
-
getAbsorbedPower
Description copied from class:LightModelBase
Returns the radiant power in Watts which is absorbed by the surface of the volume of the givennode
. If thenode
does not define a volume, the zero spectrum is returned.- Specified by:
getAbsorbedPower
in classLightModelBase
- Parameters:
node
- a node of the graph- Returns:
- the absorbed radiant power of the node
-
getSensedIrradiance
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 givennode
. If thenode
does not define a volume with a sensor, the zero spectrum is returned.- Specified by:
getSensedIrradiance
in classLightModelBase
- Parameters:
node
- a node of the graph- Returns:
- the sensed irradiance of the node
-
getSensedIrradiance
Returns the experiment data on sensed irradiance, computed during the last call tocompute()
- Returns:
- sensed irradiance data
-
getAbsorbedPower
Returns the experiment data on absorbed power, computed during the last call tocompute()
- Returns:
- absorbed power data
-
getSensedIrradianceMeasurement
Returns the irradiance sensed by a node during the last call tocompute()
- Parameters:
node
- node for which the absorbed power is returned- Returns:
- sensed irradiance
-
getAbsorbedPowerMeasurement
Returns the power absorbed by a node during the last call tocompute()
- Parameters:
node
- node for which the absorbed power is returned- Returns:
- absorbed power
-
setLayerVisible
public void setLayerVisible(int layer, boolean visible) Description copied from class:LightModelBase
sets the visibility of a layer- Specified by:
setLayerVisible
in classLightModelBase
-