Environment plugin


Example of a procedural environment plugin

With the SDK, you may create new environments types that will extend the base types included in Ocean.

Class header

To make a new environment type, you need to subclass IEnvironmentPlugin defined in the environmentplugin.h SDK header, and implement a set of pure virtual functions.

The example below shows the declaration of a simple environment type named “test”:

#include <oceansdk/environmentplugin.h>

class TestEnvironment : public Ocean::Sdk::IEnvironmentPlugin
     TestEnvironment() { }
     ~TestEnvironment() { }

     void addRadianceValues(Ocean::Sdk::IStokesContext *context,
                            const Vec3<float> &direction) const;

     float samplePdf(Vec3<float> * dest, Ocean::Sdk::ISampler * sampler) const;
     float pdf(const Vec3<float> & direction) const;

     const char * typeName() const { return "test"; }
     const char * prettyTypeName() const { return "SDK Test"; }

     Ocean::Sdk::IEnvironmentPlugin * clone() const
     { return new TestEnvironment(*this); }

     void getParameters(Ocean::Sdk::IParamList * /*iParamList*/) { }

     bool setParameter(const char * /*parameterName*/,
                       const Ocean::Sdk::IParamValue & /*value*/)
     { return false; }

     void addChildren(Ocean::Sdk::IAddChildContext * /*iChildAdd*/) { }
     bool prepare(const Ocean::Sdk::IPrepareContext * /*iPrepare*/)
     { return true; }

Class implementation

addRadianceValues function

Documentation : IEnvironmentPlugin::addRadianceValues()

This is the main environment function, it adds the environment radiance for a given direction to supplied Stokes vectors.

In this example, we write a procedural environment which :
  • Has a 5.108 W/m3 spectral radiance on the x>0 hemisphere for wavelengths above 500nm (yellow-orange-reds)

  • Has a 5.108 W/m3 spectral radiance on the x<0 hemisphere for wavelengths above 500nm (blue-greens)

  • Has a zero spectral radiance otherwise.

This should result in a diffuse environment with an orange hemisphere and a blue opposite hemisphere.

void TestEnvironment::addRadianceValues(Ocean::Sdk::IStokesContext * context,
                                        const Vec3<float> & direction) const
     float * sptr[4];
     unsigned int numWL = context->numWavelengths();

     for(unsigned int i=0;i<numWL;i++)
             float wl = context->getWavelengthMeters(i, wlMin, wlMax);
             if(direction[0]>0.0f && wl>500E-9f || direction[0]<0.0f && wl<500E-9f)
                     sptr[0][i] += 0.5E9f;

             //No polarization : we do not change sptr[1], sptr[2] and sptr[3]
             //Corresponding to Q,U,V Stokes parameters

samplePdf function

Documentation : IEnvironmentPlugin::samplePdf()

This function samples an environment direction and returns the pdf.

As the environment emits roughly the same amount of light in all direction, we can sample uniformly the unit sphere:

float TestEnvironment::samplePdf(Vec3<float> * dest,
                                 Ocean::Sdk::ISampler * sampler) const
     //Sample only the lit hemisphere
     *dest = sampler->sampleUnitSphereF();

     //Returns 1/4Pi pdf
     return 0.25f*M_1_PIf;

pdf function

Documentation : IEnvironmentPlugin::pdf()

This function must return the pdf corresponding to the sampling function IEnvironmentPlugin::samplePdf()

float TestEnvironment::pdf(const Vec3<float> & direction) const
     return 0.25f*M_1_PIf;

prepare function

Documentation : IEnvironmentPlugin::prepare()

To get the wavelength in IEnvironmentPlugin::addRadianceValues(), we need to get the simulation wavelength range during initialization. This is done in this function:

bool TestEnvironment::prepare(const Ocean::Sdk::IPrepareContext * iPrepare)
     wlMin = iPrepare->wavelengthMin();
     wlMax = iPrepare->wavelengthMax();


The image at the top of this page is the result of using this environment with a simple grey lambertian material