Table of Contents
In this tutorial we will see how to get started with a FluxModel in GroIMP.
Go 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 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.