Skip to content

Commit

Permalink
#5 Realistic Transparency
Browse files Browse the repository at this point in the history
  • Loading branch information
mandyedi committed Mar 16, 2024
1 parent 2583c1c commit 0267419
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ endif ()
set (SOURCE_BRDFS
src/BRDFs/BRDF.cpp
src/BRDFs/BRDF.h
src/BRDFs/FresnelReflector.cpp
src/BRDFs/FresnelReflector.h
src/BRDFs/GlossySpecular.cpp
src/BRDFs/GlossySpecular.h
src/BRDFs/Lambertian.cpp
Expand All @@ -29,6 +31,8 @@ set (SOURCE_BRDFS
set (SOURCE_BTDFS
src/BTDFs/BTDF.cpp
src/BTDFs/BTDF.h
src/BTDFs/FresnelTransmitter.cpp
src/BTDFs/FresnelTransmitter.h
src/BTDFs/PerfectTransmitter.cpp
src/BTDFs/PerfectTransmitter.h
)
Expand Down
69 changes: 69 additions & 0 deletions src/BRDFs/FresnelReflector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#include "FresnelReflector.h"

#include <cmath>
#include <utility>

#include "../Utilities/ShadeRec.h"
#include "../Utilities/Vector3D.h"

FresnelReflector::FresnelReflector(const FresnelReflector& fr) : BRDF(fr), eta_in(fr.eta_in), eta_out(fr.eta_out) {}

FresnelReflector::FresnelReflector(FresnelReflector&& fr) noexcept : BRDF(std::move(fr)), eta_in(std::exchange(fr.eta_in, 1.0f)), eta_out(std::exchange(fr.eta_out, 1.0f)) {}

FresnelReflector& FresnelReflector::operator=(const FresnelReflector& fr) {
FresnelReflector::operator=(fr);
eta_in = fr.eta_in;
eta_out = fr.eta_out;

return *this;
}

FresnelReflector& FresnelReflector::operator=(FresnelReflector&& fr) noexcept {
FresnelReflector::operator=(fr);
eta_in = std::exchange(fr.eta_in, 1.0f);
eta_out = std::exchange(fr.eta_out, 1.0f);

return *this;
}

FresnelReflector* FresnelReflector::clone() const { return new FresnelReflector(*this); }

RGBColor FresnelReflector::sample_f(const ShadeRec& sr, const Vector3D& wo, Vector3D& wr) const {
float ndotwo = sr.normal * wo;
wr = -wo + 2.0f * sr.normal * ndotwo;
return fresnel(sr) * RGBColor::white / fabs(sr.normal * wr);
}

float FresnelReflector::fresnel(const ShadeRec& sr) const {
Normal normal(sr.normal);
float ndotd = -normal * sr.ray.d;
float eta;

if (ndotd < 0.0f) {
normal = -normal;
eta = eta_out / eta_in;
} else {
eta = eta_in / eta_out;
}

float cos_theta_i = -normal * sr.ray.d;
float temp = 1.0f - (1.0f - cos_theta_i * cos_theta_i) / (eta * eta);
float cos_theta_t = sqrt(1.0f - (1.0f - cos_theta_i * cos_theta_i) / (eta * eta));
float r_parallel = (eta * cos_theta_i - cos_theta_t) / (eta * cos_theta_i + cos_theta_t);
float r_perpendicular = (cos_theta_i - eta * cos_theta_t) / (cos_theta_i + eta * cos_theta_t);
float kr = 0.5f * (r_parallel * r_parallel + r_perpendicular * r_perpendicular);

return kr;
}
56 changes: 56 additions & 0 deletions src/BRDFs/FresnelReflector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#ifndef __FRESNEL_REFLECTOR__
#define __FRESNEL_REFLECTOR__

class ShadeRec;
class Vector;

#include "BRDF.h"

class FresnelReflector : public BRDF {
public:

FresnelReflector() = default;

~FresnelReflector() = default;

FresnelReflector(const FresnelReflector& fr);

FresnelReflector(FresnelReflector&& fr) noexcept;

FresnelReflector& operator=(const FresnelReflector& fr);

FresnelReflector& operator=(FresnelReflector&& fr) noexcept;

FresnelReflector* clone() const override;

void set_eta_in(const float eta);

void set_eta_out(const float eta);

RGBColor sample_f(const ShadeRec& sr, const Vector3D& wo, Vector3D& wr) const override;

private:

float eta_in = 1.0f;
float eta_out = 1.0f;

float fresnel(const ShadeRec& sr) const;
};

inline void FresnelReflector::set_eta_in(const float eta) { eta_in = eta; }

inline void FresnelReflector::set_eta_out(const float eta) { eta_out = eta; }

#endif
2 changes: 1 addition & 1 deletion src/BTDFs/BTDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class BTDF {

BTDF& operator=(BTDF&& btdf) = default;

virtual BTDF* clone() = 0;
virtual BTDF* clone() const = 0;

virtual RGBColor f(const ShadeRec& sr, const Vector3D& wo, const Vector3D& wi) const;

Expand Down
81 changes: 81 additions & 0 deletions src/BTDFs/FresnelTransmitter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#include "FresnelTransmitter.h"

#include <utility>
#include <cmath>

#include "../Utilities/Vector3D.h"
#include "../Utilities/ShadeRec.h"

FresnelTransmitter::FresnelTransmitter(const FresnelTransmitter& pt) : BTDF(pt), kt(pt.kt), ior(pt.ior) {}

FresnelTransmitter::FresnelTransmitter(FresnelTransmitter&& pt) noexcept : BTDF(std::move(pt)), kt(std::exchange(pt.kt, 0.0f)), ior(std::exchange(pt.ior, 1.0f)) {}

FresnelTransmitter& FresnelTransmitter::operator=(const FresnelTransmitter& pt) {
FresnelTransmitter::operator=(pt);
kt = pt.kt;
ior = pt.ior;

return *this;
}

FresnelTransmitter& FresnelTransmitter::operator=(FresnelTransmitter&& pt) noexcept {
FresnelTransmitter::operator=(pt);
kt = std::exchange(pt.kt, 0.0f);
ior = std::exchange(pt.ior, 1.0f);

return *this;
}

FresnelTransmitter* FresnelTransmitter::clone() const { return new FresnelTransmitter(*this); }

// tests for total internal reflection

bool FresnelTransmitter::tir(const ShadeRec& sr) const {
Vector3D wo(-sr.ray.d);
float cos_thetai = sr.normal * wo;
float eta = ior;

if (cos_thetai < 0.0f) {
eta = 1.0f / eta;
}

return 1.0f - (1.0f - cos_thetai * cos_thetai) / (eta * eta) < 0.0f;
}

RGBColor FresnelTransmitter::f(const ShadeRec& sr, const Vector3D& wo, const Vector3D& wi) const { return RGBColor::black; }

// this computes the direction wt for perfect transmission
// and returns the transmission coefficient
// this is only called when there is no total internal reflection

RGBColor FresnelTransmitter::sample_f(const ShadeRec& sr, const Vector3D& wo, Vector3D& wt) const {
Normal n(sr.normal);
float cos_thetai = n * wo;
float eta = ior;

if (cos_thetai < 0.0f) { // transmitted ray is outside
cos_thetai = -cos_thetai;
n = -n; // reverse direction of normal
eta = 1.0f / eta; // invert ior
}

float temp = 1.0f - (1.0f - cos_thetai * cos_thetai) / (eta * eta);
float cos_theta2 = sqrt(temp);
wt = -wo / eta - (cos_theta2 - cos_thetai / eta) * n;

return kt / (eta * eta) * RGBColor::white / fabs(sr.normal * wt);
}

RGBColor FresnelTransmitter::rho(const ShadeRec& sr, const Vector3D& wo) const { return RGBColor::black; }
59 changes: 59 additions & 0 deletions src/BTDFs/FresnelTransmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#ifndef __FRESNEL_TRANSMITTER__
#define __FRESNEL_TRANSMITTER__

#include "BTDF.h"

class FresnelTransmitter : public BTDF {
public:

FresnelTransmitter() = default;

~FresnelTransmitter() = default;

FresnelTransmitter(const FresnelTransmitter& pt);

FresnelTransmitter(FresnelTransmitter&& pt) noexcept;

FresnelTransmitter& operator=(const FresnelTransmitter& rhs);

FresnelTransmitter& operator=(FresnelTransmitter&& rhs) noexcept;

FresnelTransmitter* clone() const override;

void set_eta_in(const float eta);

void set_eta_out(const float eta);

bool tir(const ShadeRec& sr) const;

RGBColor f(const ShadeRec& sr, const Vector3D& wo, const Vector3D& wi) const override;

RGBColor sample_f(const ShadeRec& sr, const Vector3D& wo, Vector3D& wt) const override;

RGBColor rho(const ShadeRec& sr, const Vector3D& wo) const override;

private:

float eta_in = 1.0f;
float eta_out = 1.0f;
float kt = 0.0f; // TODO: what is kt?
float ior = 0.0f; // TODO: what is ior?
};

inline void FresnelTransmitter::set_eta_in(const float eta) { eta_in = eta; }

inline void FresnelTransmitter::set_eta_out(const float eta) { eta_out = eta; }

#endif
2 changes: 1 addition & 1 deletion src/BTDFs/PerfectTransmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PerfectTransmitter& PerfectTransmitter::operator=(PerfectTransmitter&& pt) noexc
return *this;
}

PerfectTransmitter* PerfectTransmitter::clone() { return new PerfectTransmitter(*this); }
PerfectTransmitter* PerfectTransmitter::clone() const { return new PerfectTransmitter(*this); }

// tests for total internal reflection

Expand Down
2 changes: 1 addition & 1 deletion src/BTDFs/PerfectTransmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class PerfectTransmitter : public BTDF {

PerfectTransmitter& operator=(PerfectTransmitter&& rhs) noexcept;

PerfectTransmitter* clone() override;
PerfectTransmitter* clone() const override;

void set_kt(const float k);

Expand Down
13 changes: 13 additions & 0 deletions src/Materials/Dielectric.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#include "Dielectric.h"
22 changes: 22 additions & 0 deletions src/Materials/Dielectric.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#ifndef __DIELECTRIC__
#define __DIELECTRIC__

class Dielectric {

// TODO: implement, 28.3 Implementation, page 601

};

#endif

0 comments on commit 0267419

Please sign in to comment.