Scalar shader plugin

../../_images/scalarshaderplugin.jpg

Example of a procedural scalar shader plugin

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

Class header

To make a new scalar shader type, you need to subclass ScalarShaderPluginInterface defined in the scalarshaderplugin.h SDK header, and implement a set of pure virtual functions.

The example below shows the declaration of a simple scalar shader type named “scalar”:

#include <oceansdk/scalarshaderplugin.h>
#include <oceansdk/math/vec3.h>

class TestScalarShader : public Ocean::Sdk::IScalarShaderPlugin
{
public:
     TestScalarShader() { }
     ~TestScalarShader() { }

     float value(const Ocean::Sdk::IShaderContext * sc) const;

     const char * typeName() const { return "scalar"; }

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

     TestScalarShader * clone() const { return new TestScalarShader(*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

value function

In our example, the only non-trivial function we need to implement is IScalarShaderPlugin::value()

This is the main shader function, it evaluates and return the scalar shader value as a float. The shader may use all information passed by the IShaderContext, such as world position, uv coordinates, etc, except the wavelength information.

Warning

A scalar shader cannot be wavelength dependent!

We define here a sine function along the x axis, with 10 periods per meter:

float TestScalarShader::value(const Ocean::Sdk::ShaderContextInterface * sc) const
{
     float x = sc->worldPos().toVec3<float>()[0];
     return std::sin(x*10*2*M_PI) * 0.5 + 0.5;
}

Result

The image at the top of this page is the result of using this shader as a blend function between grey and red lambertian, as defined in the following material definition:

<material type="generic" name="previewmaterial">
     <bsdf type="blend" name="bsdf">
             <scalarshader type="sdktest/scalar" name="blend"/>
             <bsdf type="lambertian" name="bsdf1">
                     <filtershader type="constant" name="diffuse" value="0.18"/>
             </bsdf>
             <bsdf type="lambertian" name="bsdf2">
                     <filtershader type="uniform" name="diffuse">
                             <spectrum type="rgb" name="spectrum" rgb="0.8 0 0" gamma="2.2"/>
                     </filtershader>
             </bsdf>
     </bsdf>
</material>