In this tutorial we will see how to get started with a FluxModel in GroIMP.
Go [[:groimp-platform:gpuflux|here]] to see more about how the FluxModel is defined in GroIMP.
====== Light Model ======
First, we setup of the Flux Light Model:
import de.grogra.gpuflux.tracer.FluxLightModelTracer.MeasureMode;
import de.grogra.gpuflux.scene.experiment.Measurement;
const int RAYS = 10000000;
const int DEPTH = 10;
const FluxLightModel LM = new FluxLightModel(RAYS,
DEPTH);
protected void init () {
LM.setMeasureMode(MeasureMode.FULL_SPECTRUM);
LM.setSpectralBuckets(81);
LM.setSpectralDomain(380, 780);
}
This is:
- importing of the needed classes
- initializing the model with 10 million rays and a recursion depth of 10
- setting the parameters with 400nm divided into 80 buckets of 5nm.
Then, run the light model and determine the amount of sensed radiation or of
absorbed power for an object-type.
public void run () [
{
LM.compute();
}
x:SensorNode ::> {
Measurement spectrum = LM.getSensedIrradianceMeasurement(x);
float absorbedPower = spectrum.integrate();
//...
}
x:Box ::> {
Measurement spectrum = LM.getAbsorbedPowerMeasurement(x);
float absorbedPower = spectrum.integrate();
//...
}
]
This is:
- computing the model
- computing the integration of the whole absorbed spectrum for both
- sensor nodes
- box objects
Demonstration of the method for the determination of the amount of absorbed power per bucket or integration over a certain spectral range.
Measurement spectrum = LM.getAbsorbedPowerMeasurement(x);
//absorbed power for the first bucket: 380-385 nm
float ap380_385 = spectrum.data[0];
//accumulate absorbed power for the first four 50 nm buckets
float b0 = 0, b1 = 0, b2 = 0, b3 = 0;
for (int i:(0:10)) {
b0 += spectrum.data[i];
b1 += spectrum.data[i + 10];
b2 += spectrum.data[i + 20];
b3 += spectrum.data[i + 30];
}
//integrate the whole spectrum
float ap = spectrum.integrate();
This is:
- Getting the absorbed spectrum
- Storing the first bucket in a variable
- building four integrals, each of 50 nm (10 buckets of 5 nm) and sum up the first 40 buckets.
- calculating the integral over the whole spectrum.
====== Light Sources ======
Now let's set up a parameterisable light node – with explicit definition of physical light and spectral power distribution by simple arrays:
import de.grogra.imp3d.spectral.IrregularSpectralCurve;
const double[][] DISTRIBUTION = {
{131.25, 131.67, 132.37, ...},
{131.36, 131.81, ...},
...
};
static const float[] WAVELENGTHS = {380,385, ...};
static const float[] AMPLITUDES = {0.000967,0.000980, ...};
module MyLamp extends LightNode() {
{
setLight(new SpectralLight(
new IrregularSpectralCurve(WAVELENGTHS, AMPLITUDES)).(
setPower(10), //[W]
setLight(new PhysicalLight(DISTRIBUTION))));
}
}
This is :
- importing the required classes
- defining of the physical light distribution
- defining of the spectral power distribution
- defining of a lamp using the specified parameters
The light distribution and spectral distribution (i.e. the ''DISTRIBUTION'', ''WAVELENGTHS'' and ''AMPLITUDES'' arrays) can also be provided from ''.ies'' files.
See [[:groimp-platform:input-and-output-in-groimp|here]] for more information on the supported file formats.
Then, let's create a parameterizable light node – using file references for physical and spectral power distribution.
const LightDistributionRef DISTRIBUTION = light("
distribution1");
const SpectrumRef SPECTRUM = spectrum("equal");
module MyLamp1 extends LightNode {
{
setLight(new SpectralLight(new PhysicalLight(
DISTRIBUTION), SPECTRUM, 10)); // 10 W
}
}
module MyLamp2 extends LightNode {
{
setLight(
new SpectralLight().(
setPower(10), //[W]
setLight(new PhysicalLight(DISTRIBUTION)),
setSpectrum(SPECTRUM)));
}
}
This is:
- Defining a file reference. This file can be included or linked to a project
- Applying a concrete lamp to the reference by:
- using the constructor
- using the set-methods of the //LightNode// class
====== Illumination Model ======
Definition of a Phong shader by textures, by colours and by a user-defined
spectral power distribution.
Phong myShader = new Phong();
ImageMap image = new ImageMap();
image.setImageAdapter(new FixedImageAdapter(image("leaf").toImageAdapter().getBufferedImage()));
myShader.setDiffuse(image);
Phong myShader = new Phong();
myShader.setDiffuse(new RGBColor(0,1,0));
//myShader.setSpecular(new Graytone(0.5));
//myShader.setShininess(new Graytone(0.5));
myShader.setDiffuseTransparency(new RGBColor(0.5,0,0));
//myShader.setAmbient(new Graytone(0.5));
//myShader.setEmissive(new Graytone(0.5));
ChannelSPD MySPD = new ChannelSPD(new IrregularSpectralCurve(
new float[] {400,410, ....,740,750}, //WAVELENGTHS
new float[] {0.1,0, .... ,0.4,0.25} //AMPLITUDES
));
Phong myShader = new Phong();
myShader.setDiffuse(MySPD);
This is:
- Setting an image as texture: Values for reflection depend on the colour of the texture at each pixel of the image.
- Setting specific properties: At this configuration green will be reflected to 100 % and red will be transmitted to 50 % for the whole surface of the object.
- A user-defined SPD is used to define the diffuse colour.