-- glslfx version 0.1

//
// Copyright 2019 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//

--- This is what an import might look like.
--- #import $TOOLS/hdSt/shaders/fallbackVolume.glslfx

-- configuration
{
    "techniques": {
        "default": {
            "volumeShader": {
                "source": [ "FallbackVolume.VolumeShader" ]
            }
        }
    }
}

--- --------------------------------------------------------------------------
-- glsl FallbackVolume.VolumeShader

// Functions that the volume shader of a volume material would provide.
//
// The functions give extinction, scattering, emission at a point as well as
// a phase function such as Henyey-Greenstein (see, e.g., [1]).
//
// Only single scattering is taken into account and the result of the
// scattering function (together with the phase function) is used to compute
// the in-scattering component of the volume rendering equation for a light
// source (point lights only).
// The extinction function is supposed to return the sum of the
// absorption and out-scattering cross section.
// Note that the interpretation of emission here follows [1] (rather than [2]),
// so the emission is added by the ray-marcher without being multiplied by
// extinction.
// Note that one cannot use the fallback volume shader for assets containing
// "glow" rather "emission" where the convention is
// emission = glow * extinction.
//
// [1] Matt Pharr, Wenzel Jakob, Greg Humphreys, "Physically Based Rendering",
// Third Edition).
// [2] Julian Fong, Magnus Wrenninge, Christopher Kulla, Ralf Habel,
// "Production Volume Rendering", SIGGRAPH 2017 Course.

// The functions given here use a density and emission field with a fixed
// albedo.
//
//

// Extinction function, returns sum of absorption and out-scattering cross
// ratio.
//
float
extinctionFunction(vec3 p)
{
    return HdGet_density(p);
}

// Scattering function, returns in-scattering cross-section (will be combined
// with phase function).
//
// Here: constant on ellipsoid and zero outside.
float
scatteringFunction(vec3 p)
{
    const float albedo = 0.18;

    return extinctionFunction(p) * albedo;
}

// Emission function, returns emission cross-section.
//
// Here: zero since volume is not emitting light.
vec3
emissionFunction(vec3 p)
{
    return HdGet_emission(p);
}

// Phase function in volume rendering equation.
//
// Here: isotropic.
float
phaseFunction(vec3 direction1, vec3 direction2)
{
    const float pi = 3.14159265358979;
    const float sphereArea = 4.0 * pi;
    const float inverseSphereArea = 1.0 / sphereArea;

    return inverseSphereArea;
}

