| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #include "DavisTransmittance.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| DavisTransmittance::DavisTransmittance() | ||
| : _alpha(1.1f) | ||
| { | ||
| } | ||
|
|
||
| void DavisTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("alpha", _alpha); | ||
|
|
||
| if (_alpha < 1 + 1e-6f) { | ||
| std::cout << "Warning: alpha parameter of Davis transmittance has to be > 1. Clamping the current value (" << _alpha << ")" << std::endl; | ||
| _alpha = 1 + 1e-6f; | ||
| } | ||
| } | ||
|
|
||
| rapidjson::Value DavisTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "davis", | ||
| "alpha", _alpha | ||
| }; | ||
| } | ||
|
|
||
| Vec3f DavisTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return std::pow(1.0f + tau/_alpha, -_alpha); | ||
| } | ||
| Vec3f DavisTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return std::pow(1.0f + tau/_alpha, -(_alpha + 1.0f)); | ||
| } | ||
| Vec3f DavisTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return surfaceMedium(tau); | ||
| } | ||
| Vec3f DavisTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| return (1.0f + 1.0f/_alpha)*std::pow(1.0f + tau/_alpha, -(_alpha + 2.0f)); | ||
| } | ||
|
|
||
| float DavisTransmittance::sigmaBar() const | ||
| { | ||
| return 1.0f; | ||
| } | ||
|
|
||
| float DavisTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| return _alpha*(std::pow(1.0f - sampler.next1D(), -1.0f/_alpha) - 1.0f); | ||
| } | ||
| float DavisTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return _alpha*(std::pow(1.0f - sampler.next1D(), -1.0f/(1.0f + _alpha)) - 1.0f); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #ifndef DAVISTRANSMITTANCE_HPP_ | ||
| #define DAVISTRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class DavisTransmittance : public Transmittance | ||
| { | ||
| float _alpha; | ||
|
|
||
| public: | ||
| DavisTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif /* DAVISTRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| #include "DavisWeinsteinTransmittance.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| DavisWeinsteinTransmittance::DavisWeinsteinTransmittance() | ||
| : _h(0.75f), | ||
| _c(1.0f) | ||
| { | ||
| } | ||
|
|
||
| void DavisWeinsteinTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("h", _h); | ||
| value.getField("c", _c); | ||
| if (_h < 0.5f || _h > 1.0f) | ||
| std::cout << "Warning: Valid range of Davis Weinstein transmittance is [0.5, 1.0]. Clamping current value (" << _h << ") to within range" << std::endl; | ||
| _h = clamp(_h, 0.5f, 1.0f); | ||
| } | ||
|
|
||
| rapidjson::Value DavisWeinsteinTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "davis", | ||
| "h", _h, | ||
| "c", _c | ||
| }; | ||
| } | ||
|
|
||
| float DavisWeinsteinTransmittance::computeAlpha(float tau) const | ||
| { | ||
| float beta = 2.0f*_h - 1.0f; | ||
| return std::pow(tau, 1 - beta)/(std::pow(_c, 1 + beta)); | ||
| } | ||
|
|
||
| Vec3f DavisWeinsteinTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| float alpha = computeAlpha(tau[0]); | ||
| float Tr = std::pow(1.0f + tau[0]/alpha, -alpha); | ||
|
|
||
| return Vec3f(std::isnan(Tr) ? 0 : Tr); | ||
| } | ||
| Vec3f DavisWeinsteinTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| float beta = 2.0f*_h - 1.0f; | ||
| float t = tau[0]; | ||
| float alpha = computeAlpha(t); | ||
| float base = 1.0f + t/alpha; | ||
| float trSurface = std::pow(base, -alpha); | ||
|
|
||
| float Tr = trSurface*(beta/base - (beta - 1.0f)*alpha/t*std::log(base)); | ||
|
|
||
| return Vec3f(std::isnan(Tr) ? 0 : Tr); | ||
| } | ||
| Vec3f DavisWeinsteinTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return surfaceMedium(tau); | ||
| } | ||
| Vec3f DavisWeinsteinTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| float beta = 2.0f*_h - 1.0f; | ||
| float t = tau[0]; | ||
| float alpha = computeAlpha(t); | ||
| float base = 1.0f + t/alpha; | ||
| float logBase = std::log(base); | ||
| float trSurface = std::pow(base, -alpha); | ||
| float term1 = beta*(-1.0f + beta*(1.0f + t) + (-1.0f + 2.0f*beta)*t/alpha)/(t*base*base); | ||
| float term2 = ((-1.0f + beta)*beta*alpha/(t*t)*(2.0f*t + base)*logBase)/base; | ||
| float term3 = (beta - 1.0f)*alpha/t*logBase; | ||
|
|
||
| float Tr = trSurface*(term1 - term2 + term3*term3); | ||
|
|
||
| return Vec3f(std::isnan(Tr) ? 0 : Tr); | ||
| } | ||
|
|
||
| float DavisWeinsteinTransmittance::sigmaBar() const | ||
| { | ||
| return 1.0f; | ||
| } | ||
|
|
||
| // We have no real way of analytically sampling this function, so a simple bisection will have to do | ||
| float DavisWeinsteinTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| float xi = sampler.next1D(); | ||
| auto cdf = [this](float tau) { return 1.0f - surfaceSurface(Vec3f(tau))[0]; }; | ||
| float step = 1e6; | ||
| float result = step*2; | ||
| while (step > 1e-6) { | ||
| if (cdf(result) > xi) | ||
| result -= step; | ||
| else | ||
| result += step; | ||
| step /= 2; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
| float DavisWeinsteinTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| float xi = sampler.next1D(); | ||
| auto cdf = [this](float tau) { return 1.0f - mediumSurface(Vec3f(tau))[0]; }; | ||
| float step = 1e6; | ||
| float result = step * 2; | ||
| while (step > 1e-6) { | ||
| if (cdf(result) > xi) | ||
| result -= step; | ||
| else | ||
| result += step; | ||
| step /= 2; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #ifndef DAVISWEINSTEINTRANSMITTANCE_HPP_ | ||
| #define DAVISWEINSTEINTRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class DavisWeinsteinTransmittance : public Transmittance | ||
| { | ||
| float _h; | ||
| float _c; | ||
|
|
||
| float computeAlpha(float tau) const; | ||
|
|
||
| public: | ||
| DavisWeinsteinTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif /* DAVISWEINSTEINTRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #include "DoubleExponentialTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| DoubleExponentialTransmittance::DoubleExponentialTransmittance() | ||
| : _sigmaA(0.5f), | ||
| _sigmaB(10.0f) | ||
| { | ||
| } | ||
|
|
||
| void DoubleExponentialTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("sigma_a", _sigmaA); | ||
| value.getField("sigma_b", _sigmaB); | ||
| } | ||
|
|
||
| rapidjson::Value DoubleExponentialTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "double_exponential", | ||
| "sigma_a", _sigmaA, | ||
| "sigma_b", _sigmaB, | ||
| }; | ||
| } | ||
|
|
||
| Vec3f DoubleExponentialTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return 0.5f*(std::exp(-_sigmaA*tau) + std::exp(-_sigmaB*tau)); | ||
| } | ||
| Vec3f DoubleExponentialTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return 0.5f*(_sigmaA*std::exp(-_sigmaA*tau) + _sigmaB*std::exp(-_sigmaB*tau)); | ||
| } | ||
| Vec3f DoubleExponentialTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return (_sigmaA*std::exp(-_sigmaA*tau) + _sigmaB*std::exp(-_sigmaB*tau))/(_sigmaA + _sigmaB); | ||
| } | ||
| Vec3f DoubleExponentialTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| return (sqr(_sigmaA)*std::exp(-_sigmaA*tau) + sqr(_sigmaB)*std::exp(-_sigmaB*tau))/(_sigmaA + _sigmaB); | ||
| } | ||
|
|
||
| float DoubleExponentialTransmittance::sigmaBar() const | ||
| { | ||
| return 0.5f*(_sigmaA + _sigmaB); | ||
| } | ||
|
|
||
| float DoubleExponentialTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| float t = -std::log(1.0f - sampler.next1D()); | ||
| return sampler.nextBoolean(0.5f) ? t/_sigmaA : t/_sigmaB; | ||
| } | ||
| float DoubleExponentialTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| float t = -std::log(1.0f - sampler.next1D()); | ||
| return sampler.nextBoolean(_sigmaA/(_sigmaA + _sigmaB)) ? t/_sigmaA : t/_sigmaB; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #ifndef DoubleExponentialTransmittance_HPP_ | ||
| #define DoubleExponentialTransmittance_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class DoubleExponentialTransmittance : public Transmittance | ||
| { | ||
| float _sigmaA; | ||
| float _sigmaB; | ||
|
|
||
| public: | ||
| DoubleExponentialTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| #endif /* DoubleExponentialTransmittance_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| #include "ErlangTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| ErlangTransmittance::ErlangTransmittance() | ||
| : _lambda(5.0f) | ||
| { | ||
| } | ||
|
|
||
| void ErlangTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("rate", _lambda); | ||
| } | ||
|
|
||
| rapidjson::Value ErlangTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "erlang", | ||
| "rate", _lambda, | ||
| }; | ||
| } | ||
|
|
||
| Vec3f ErlangTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return 0.5f*std::exp(-_lambda*tau)*(2.0f + _lambda*tau); | ||
| } | ||
| Vec3f ErlangTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return mediumSurface(tau)*_lambda*0.5f; | ||
| } | ||
| Vec3f ErlangTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return std::exp(-_lambda*tau)*(1.0f + _lambda*tau); | ||
| } | ||
| Vec3f ErlangTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| return sqr(_lambda)*tau*std::exp(-_lambda*tau); | ||
| } | ||
|
|
||
| float ErlangTransmittance::sigmaBar() const | ||
| { | ||
| return _lambda*0.5f; | ||
| } | ||
|
|
||
| float ErlangTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| float xi = sampler.next1D(); | ||
| float x = 0.5f; | ||
| for (int i = 0; i < 10; ++i) { | ||
| x += (xi - (1.0f - surfaceSurface(Vec3f(x))[0]))/surfaceMedium(Vec3f(x))[0]; | ||
| x = max(x, 0.0f); | ||
| } | ||
| return x; | ||
| } | ||
| float ErlangTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return -1.0f/_lambda*std::log(sampler.next1D()*sampler.next1D()); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #ifndef ErlangTransmittance_HPP_ | ||
| #define ErlangTransmittance_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class ErlangTransmittance : public Transmittance | ||
| { | ||
| float _lambda; | ||
|
|
||
| public: | ||
| ErlangTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| #endif /* ErlangTransmittance_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| #include "ExponentialTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
| #include "math/FastMath.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| void ExponentialTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| } | ||
|
|
||
| rapidjson::Value ExponentialTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "exponential", | ||
| }; | ||
| } | ||
|
|
||
| Vec3f ExponentialTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return FastMath::exp(-tau); | ||
| } | ||
| Vec3f ExponentialTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return FastMath::exp(-tau); | ||
| } | ||
| Vec3f ExponentialTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return FastMath::exp(-tau); | ||
| } | ||
| Vec3f ExponentialTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| return FastMath::exp(-tau); | ||
| } | ||
|
|
||
| float ExponentialTransmittance::sigmaBar() const | ||
| { | ||
| return 1.0f; | ||
| } | ||
|
|
||
| float ExponentialTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| return -std::log(1.0f - sampler.next1D()); | ||
| } | ||
| float ExponentialTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return -std::log(1.0f - sampler.next1D()); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #ifndef EXPONENTIALTRANSMITTANCE_HPP_ | ||
| #define EXPONENTIALTRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class ExponentialTransmittance : public Transmittance | ||
| { | ||
| public: | ||
| ExponentialTransmittance() = default; | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| #endif /* EXPONENTIALTRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #include "InterpolatedTransmittance.hpp" | ||
|
|
||
| #include "ExponentialTransmittance.hpp" | ||
| #include "LinearTransmittance.hpp" | ||
| #include "ErlangTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
| #include "io/Scene.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| InterpolatedTransmittance::InterpolatedTransmittance() | ||
| : _trA(std::make_shared<LinearTransmittance>()), | ||
| _trB(std::make_shared<ErlangTransmittance>()), | ||
| _u(0.5f) | ||
| { | ||
| } | ||
|
|
||
| void InterpolatedTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| if (auto m = value["tr_a"]) _trA = scene.fetchTransmittance(m); | ||
| if (auto m = value["tr_b"]) _trB = scene.fetchTransmittance(m); | ||
| value.getField("ratio", _u); | ||
| } | ||
|
|
||
| rapidjson::Value InterpolatedTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "interpolated", | ||
| "tr_a", _trA->toJson(allocator), | ||
| "tr_b", _trB->toJson(allocator), | ||
| "ratio", _u | ||
| }; | ||
| } | ||
|
|
||
| Vec3f InterpolatedTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return sigmaBar()*lerp(_trA->surfaceSurface(tau)/_trA->sigmaBar(), _trB->surfaceSurface(tau)/_trB->sigmaBar(), _u); | ||
| } | ||
| Vec3f InterpolatedTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return mediumSurface(tau)*sigmaBar(); | ||
| } | ||
| Vec3f InterpolatedTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return lerp(_trA->mediumSurface(tau), _trB->mediumSurface(tau), _u); | ||
| } | ||
| Vec3f InterpolatedTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| Vec3f pdfA = _trA->mediumMedium(tau); | ||
| Vec3f pdfB = _trB->mediumMedium(tau); | ||
| Vec3f result; | ||
| for (int i = 0; i < 3; ++i) { | ||
| bool diracA = _trA->isDirac() && pdfA[i] > 0.0f; | ||
| bool diracB = _trB->isDirac() && pdfB[i] > 0.0f; | ||
| if (diracA ^ diracB) | ||
| result[i] = diracA ? pdfA[i] : pdfB[i]; | ||
| else | ||
| result[i] = lerp(pdfA[i], pdfB[i], _u); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| float InterpolatedTransmittance::sigmaBar() const | ||
| { | ||
| return 1.0f/lerp(1.0f/_trA->sigmaBar(), 1.0f/_trB->sigmaBar(), _u); | ||
| } | ||
|
|
||
| float InterpolatedTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| return sampler.nextBoolean(_u) ? _trB->sampleSurface(sampler) : _trA->sampleSurface(sampler); | ||
| } | ||
| float InterpolatedTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return sampler.nextBoolean(_u) ? _trB->sampleMedium(sampler) : _trA->sampleMedium(sampler); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| #ifndef INTERPOLATEDTRANSMITTANCE_HPP_ | ||
| #define INTERPOLATEDTRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| #include <vector> | ||
| #include <memory> | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class InterpolatedTransmittance : public Transmittance | ||
| { | ||
| std::shared_ptr<Transmittance> _trA; | ||
| std::shared_ptr<Transmittance> _trB; | ||
| float _u; | ||
|
|
||
| public: | ||
| InterpolatedTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| #endif /* INTERPOLATEDTRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| #include "LinearTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| LinearTransmittance::LinearTransmittance() | ||
| : _maxT(1.0f) | ||
| { | ||
| } | ||
|
|
||
| void LinearTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("max_t", _maxT); | ||
| } | ||
|
|
||
| rapidjson::Value LinearTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "linear", | ||
| "max_t", _maxT | ||
| }; | ||
| } | ||
|
|
||
| Vec3f LinearTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| return 1.0f - min(tau/_maxT, Vec3f(1.0f)); | ||
| } | ||
| Vec3f LinearTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| Vec3f result(1.0f/_maxT); | ||
| for (int i = 0; i < 3; ++i) | ||
| if (tau[i] > _maxT) | ||
| result[i] = 0.0f; | ||
| return result; | ||
| } | ||
| Vec3f LinearTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| Vec3f result(1.0f); | ||
| for (int i = 0; i < 3; ++i) | ||
| if (tau[i] > _maxT) | ||
| result[i] = 0.0f; | ||
| return result; | ||
| } | ||
| Vec3f LinearTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| Vec3f result; | ||
| for (int i = 0; i < 3; ++i) | ||
| result[i] = std::abs(tau[i] - _maxT) < 1e-3f ? 1.0f : 0.0f; | ||
| return result; | ||
| } | ||
|
|
||
| float LinearTransmittance::sigmaBar() const | ||
| { | ||
| return 1.0f/_maxT; | ||
| } | ||
|
|
||
| bool LinearTransmittance::isDirac() const | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| float LinearTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| return _maxT*sampler.next1D(); | ||
| } | ||
| float LinearTransmittance::sampleMedium(PathSampleGenerator &/*sampler*/) const | ||
| { | ||
| return _maxT; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #ifndef LINEARTRANSMITTANCE_HPP_ | ||
| #define LINEARTRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class LinearTransmittance : public Transmittance | ||
| { | ||
| float _maxT; | ||
|
|
||
| public: | ||
| LinearTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual bool isDirac() const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif /* LINEARTRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| #include "PulseTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
| #include "io/FileUtils.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| PulseTransmittance::PulseTransmittance() | ||
| : _a(0.0f), | ||
| _b(1.0f), | ||
| _numPulses(4) | ||
| { | ||
| } | ||
|
|
||
| void PulseTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("min", _a); | ||
| value.getField("max", _b); | ||
| value.getField("num_pulses", _numPulses); | ||
| } | ||
|
|
||
| rapidjson::Value PulseTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "pulse", | ||
| "min", _a, | ||
| "max", _b, | ||
| "num_pulses", _numPulses, | ||
| }; | ||
| } | ||
|
|
||
| bool PulseTransmittance::isDirac() const | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| Vec3f PulseTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| Vec3f idxF = clamp(float(_numPulses)*(tau - _a)/(_b - _a) + 0.5f, Vec3f(0.0f), Vec3f(_numPulses)); | ||
| Vec3i idx = Vec3i(idxF); | ||
|
|
||
| Vec3f height = Vec3f(_numPulses - idx)/float(_numPulses); | ||
|
|
||
| Vec3f cellIntegral = height*(idxF - Vec3f(idx)); | ||
| for (int i = 0; i < 3; ++i) { | ||
| if (idx[i] > 0) | ||
| cellIntegral[i] += (idx[i] - 0.5f) - (idx[i]*(idx[i] - 1))/(2.0f*_numPulses); | ||
| else | ||
| cellIntegral[i] -= 0.5f; | ||
| } | ||
|
|
||
| return 1.0f - (2.0f/_numPulses)*cellIntegral; | ||
| } | ||
| Vec3f PulseTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return 2.0f/(_b - _a)*mediumSurface(tau); | ||
| } | ||
| Vec3f PulseTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| Vec3i idx = clamp(Vec3i(float(_numPulses)*(tau - _a)/(_b - _a) + 0.5f), Vec3i(0), Vec3i(_numPulses)); | ||
| return 1.0f - Vec3f(idx)/float(_numPulses); | ||
| } | ||
| Vec3f PulseTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| Vec3f idxF = clamp(float(_numPulses)*(tau - _a)/(_b - _a), Vec3f(0.0f), Vec3f(_numPulses)); | ||
| Vec3i idx = Vec3i(idxF); | ||
| return (1.0f/_numPulses)*Vec3f( | ||
| std::abs(idxF[0] - idx[0] - 0.5f) < 1e-3f ? 1.0f : 0.0f, | ||
| std::abs(idxF[1] - idx[1] - 0.5f) < 1e-3f ? 1.0f : 0.0f, | ||
| std::abs(idxF[2] - idx[2] - 0.5f) < 1e-3f ? 1.0f : 0.0f | ||
| ); | ||
| } | ||
|
|
||
| float PulseTransmittance::sigmaBar() const | ||
| { | ||
| return 2.0f/(_b - _a); | ||
| } | ||
|
|
||
| float PulseTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| float xi = sampler.next1D()*_numPulses*0.5f; | ||
| float delta = 1.0f/_numPulses; | ||
|
|
||
| for (int i = 0; i < _numPulses; ++i) { | ||
| float h0 = 1.0f - (i + 0.0f)*delta; | ||
| float h1 = 1.0f - (i + 1.0f)*delta; | ||
| xi -= h0*0.5f; | ||
| if (xi < 0.0f) | ||
| return _a + (i + 0.0f + 0.5f*sampler.next1D())*(_b - _a)*delta; | ||
| xi -= h1*0.5f; | ||
| if (xi < 0.0f) | ||
| return _a + (i + 0.5f + 0.5f*sampler.next1D())*(_b - _a)*delta; | ||
| } | ||
| return 0.0f; | ||
| } | ||
| float PulseTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return _a + (0.5f + int(sampler.next1D()*_numPulses))/float(_numPulses)*(_b - _a); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #ifndef PULSETRANSMITTANCE_HPP_ | ||
| #define PULSETRANSMITTANCE_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class PulseTransmittance : public Transmittance | ||
| { | ||
| float _a, _b; | ||
| int _numPulses; | ||
|
|
||
| public: | ||
| PulseTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual bool isDirac() const override final; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| #endif /* PULSETRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #include "QuadraticTransmittance.hpp" | ||
|
|
||
| #include "sampling/UniformPathSampler.hpp" | ||
|
|
||
| #include "math/MathUtil.hpp" | ||
|
|
||
| #include "io/JsonObject.hpp" | ||
|
|
||
| #include "Memory.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| QuadraticTransmittance::QuadraticTransmittance() | ||
| : _maxT(0.75f) | ||
| { | ||
| } | ||
|
|
||
| void QuadraticTransmittance::fromJson(JsonPtr value, const Scene &scene) | ||
| { | ||
| Transmittance::fromJson(value, scene); | ||
| value.getField("max_t", _maxT); | ||
| } | ||
|
|
||
| rapidjson::Value QuadraticTransmittance::toJson(Allocator &allocator) const | ||
| { | ||
| return JsonObject{Transmittance::toJson(allocator), allocator, | ||
| "type", "quadratic", | ||
| "max_t", _maxT | ||
| }; | ||
| } | ||
|
|
||
| Vec3f QuadraticTransmittance::surfaceSurface(const Vec3f &tau) const | ||
| { | ||
| Vec3f t = min(tau/_maxT, Vec3f(1.0f)); | ||
| return 1.0f - 2.0f*t + t*t; | ||
| } | ||
| Vec3f QuadraticTransmittance::surfaceMedium(const Vec3f &tau) const | ||
| { | ||
| return (2.0f/_maxT)*(1.0f - min(tau/_maxT, Vec3f(1.0f))); | ||
| } | ||
| Vec3f QuadraticTransmittance::mediumSurface(const Vec3f &tau) const | ||
| { | ||
| return 1.0f - min(tau/_maxT, Vec3f(1.0f)); | ||
| } | ||
| Vec3f QuadraticTransmittance::mediumMedium(const Vec3f &tau) const | ||
| { | ||
| Vec3f result(1.0f/_maxT); | ||
| for (int i = 0; i < 3; ++i) | ||
| if (tau[i] > _maxT) | ||
| result[i] = 0.0f; | ||
| return result; | ||
| } | ||
|
|
||
| float QuadraticTransmittance::sigmaBar() const | ||
| { | ||
| return 2.0f/_maxT; | ||
| } | ||
|
|
||
| float QuadraticTransmittance::sampleSurface(PathSampleGenerator &sampler) const | ||
| { | ||
| return _maxT*(1.0f - std::sqrt(1.0f - sampler.next1D())); | ||
| } | ||
| float QuadraticTransmittance::sampleMedium(PathSampleGenerator &sampler) const | ||
| { | ||
| return _maxT*sampler.next1D(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #ifndef QuadraticTransmittance_HPP_ | ||
| #define QuadraticTransmittance_HPP_ | ||
|
|
||
| #include "Transmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class QuadraticTransmittance : public Transmittance | ||
| { | ||
| float _maxT; | ||
|
|
||
| public: | ||
| QuadraticTransmittance(); | ||
|
|
||
| virtual void fromJson(JsonPtr value, const Scene &scene) override; | ||
| virtual rapidjson::Value toJson(Allocator &allocator) const override; | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const override final; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const override final; | ||
|
|
||
| virtual float sigmaBar() const override final; | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const override final; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const override final; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif /* QuadraticTransmittance_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #ifndef TRANSMITTANCE_HPP_ | ||
| #define TRANSMITTANCE_HPP_ | ||
|
|
||
| #include "sampling/PathSampleGenerator.hpp" | ||
|
|
||
| #include "math/Vec.hpp" | ||
|
|
||
| #include "io/JsonSerializable.hpp" | ||
|
|
||
| #include "StringableEnum.hpp" | ||
|
|
||
| #include <algorithm> | ||
| #include <array> | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class Transmittance : public JsonSerializable | ||
| { | ||
| public: | ||
| virtual ~Transmittance() {} | ||
|
|
||
| inline Vec3f eval(const Vec3f &tau, bool startOnSurface, bool endOnSurface) const | ||
| { | ||
| if (startOnSurface && endOnSurface) | ||
| return surfaceSurface(tau); | ||
| else if (!startOnSurface && !endOnSurface) | ||
| return mediumMedium(tau)/sigmaBar(); | ||
| else | ||
| return mediumSurface(tau); | ||
| } | ||
| inline float sample(PathSampleGenerator &sampler, bool startOnSurface) const | ||
| { | ||
| return startOnSurface ? sampleSurface(sampler) : sampleMedium(sampler); | ||
| } | ||
| inline Vec3f surfaceProbability(const Vec3f &tau, bool startOnSurface) const | ||
| { | ||
| return startOnSurface ? surfaceSurface(tau) : mediumSurface(tau); | ||
| } | ||
| inline Vec3f mediumPdf(const Vec3f &tau, bool startOnSurface) const | ||
| { | ||
| return startOnSurface ? surfaceMedium(tau) : mediumMedium(tau); | ||
| } | ||
|
|
||
| virtual bool isDirac() const // Returns true if mediumMedium is a dirac/sum of dirac deltas | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| virtual Vec3f surfaceSurface(const Vec3f &tau) const = 0; | ||
| virtual Vec3f surfaceMedium(const Vec3f &tau) const = 0; | ||
| virtual Vec3f mediumSurface(const Vec3f &tau) const = 0; | ||
| virtual Vec3f mediumMedium(const Vec3f &tau) const = 0; | ||
|
|
||
| virtual float sigmaBar() const = 0; // Returns surfaceMedium(x)/mediumSurface(x) (i.e. identical to surfaceMedium(0)) | ||
|
|
||
| virtual float sampleSurface(PathSampleGenerator &sampler) const = 0; | ||
| virtual float sampleMedium(PathSampleGenerator &sampler) const = 0; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| #endif /* TRANSMITTANCE_HPP_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #include "TransmittanceFactory.hpp" | ||
| #include "DoubleExponentialTransmittance.hpp" | ||
| #include "DavisWeinsteinTransmittance.hpp" | ||
| #include "InterpolatedTransmittance.hpp" | ||
| #include "ExponentialTransmittance.hpp" | ||
| #include "QuadraticTransmittance.hpp" | ||
| #include "ErlangTransmittance.hpp" | ||
| #include "LinearTransmittance.hpp" | ||
| #include "DavisTransmittance.hpp" | ||
| #include "PulseTransmittance.hpp" | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| DEFINE_STRINGABLE_ENUM(TransmittanceFactory, "transmittance", ({ | ||
| {"double_exponential", std::make_shared<DoubleExponentialTransmittance>}, | ||
| {"exponential", std::make_shared<ExponentialTransmittance>}, | ||
| {"quadratic", std::make_shared<QuadraticTransmittance>}, | ||
| {"linear", std::make_shared<LinearTransmittance>}, | ||
| {"erlang", std::make_shared<ErlangTransmittance>}, | ||
| {"davis", std::make_shared<DavisTransmittance>}, | ||
| {"davis_weinstein", std::make_shared<DavisWeinsteinTransmittance>}, | ||
| {"pulse", std::make_shared<PulseTransmittance>}, | ||
| {"interpolated", std::make_shared<InterpolatedTransmittance>}, | ||
| })) | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #ifndef TRANSMITTANCEFACTORY_HPP_ | ||
| #define TRANSMITTANCEFACTORY_HPP_ | ||
|
|
||
| #include "StringableEnum.hpp" | ||
|
|
||
| #include <functional> | ||
| #include <memory> | ||
|
|
||
| namespace Tungsten { | ||
|
|
||
| class Transmittance; | ||
|
|
||
| typedef StringableEnum<std::function<std::shared_ptr<Transmittance>()>> TransmittanceFactory; | ||
|
|
||
| } | ||
|
|
||
| #endif /* TRANSMITTANCEFACTORY_HPP_ */ |