summaryrefslogtreecommitdiff
path: root/hw6/src/phongBrdf.cpp
diff options
context:
space:
mode:
author53hornet <53hornet@gmail.com>2019-02-02 23:33:15 -0500
committer53hornet <53hornet@gmail.com>2019-02-02 23:33:15 -0500
commitdb072ad4dc181eca5a1458656b130beb43f475bf (patch)
treea3c03c7f5497cb70503e2486662fa85cfb53415a /hw6/src/phongBrdf.cpp
downloadcsci427-db072ad4dc181eca5a1458656b130beb43f475bf.tar.xz
csci427-db072ad4dc181eca5a1458656b130beb43f475bf.zip
Diffstat (limited to 'hw6/src/phongBrdf.cpp')
-rw-r--r--hw6/src/phongBrdf.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/hw6/src/phongBrdf.cpp b/hw6/src/phongBrdf.cpp
new file mode 100644
index 0000000..939f3a1
--- /dev/null
+++ b/hw6/src/phongBrdf.cpp
@@ -0,0 +1,133 @@
+/******************************************************************/
+/* This file is part of the homework assignments for CSCI-427/527 */
+/* at The College of William & Mary and authored by Pieter Peers. */
+/* No part of this file, whether altered or in original form, can */
+/* be distributed or used outside the context of CSCI-427/527 */
+/* without consent of either the College of William & Mary or */
+/* Pieter Peers. */
+/******************************************************************/
+#include <cmath>
+#include "constants.h"
+#include "phongBrdf.h"
+#include "coordinateTransform.h"
+
+//////////////////
+// Constructors //
+//////////////////
+phongBrdf::phongBrdf(const color& albedo, float sharpness)
+{
+ _albedo = albedo;
+ _sharpness = sharpness;
+}
+
+
+phongBrdf::phongBrdf(const phongBrdf& src)
+{
+ _albedo = src._albedo;
+ _sharpness = src._sharpness;
+}
+
+
+///////////////
+// Operators //
+///////////////
+phongBrdf& phongBrdf::operator=(const phongBrdf& src)
+{
+ _assign(src);
+ return *this;
+}
+
+
+/////////////
+// Methods //
+/////////////
+color phongBrdf::shade(const vec3d& in, const vec3d& out) const
+{
+ // sanity check (below horizon)
+ if(in.z < 0.0f || out.z < 0.0f) return color(0.0f);
+
+ // compute reflected direction (simplies when n=(0,0,1))
+ vec3d reflected(-in.x, -in.y, in.z);
+
+ // evaluate phong
+ return _albedo * std::pow(std::max( reflected.dot(out), 0.0f), _sharpness);
+}
+
+
+color phongBrdf::reflectance(const vec3d& in, const vec3d& out) const
+{
+ // use shade evaluation times a normalization factor to ensure
+ // conservation of enegery.
+ return shade(in, out) * (_sharpness + 2.0f) / (2.0f * PI);
+}
+
+
+brdfSample phongBrdf::sample(const vec3d& in, float r1, float r2) const
+{
+ // sanity check
+ if(in.z < 0.0f) return brdfSample();
+
+ // compute reflected direction
+ vec3d reflected(-in.x, -in.y, in.z);
+
+ // sample hemisphere around reflected direction.
+ vec3d out( sqrt( 1.0f - pow(r1, 2.0f / (_sharpness + 1.0f)) ) * cos(2.0f * PI * r2),
+ sqrt( 1.0f - pow(r1, 2.0f / (_sharpness + 1.0f)) ) * sin(2.0f * PI * r2),
+ pow(r1, 1.0f / (_sharpness + 1.0f)) );
+
+ // transform to global coord
+ coordinateTransformation trans(reflected);
+ out = trans.transformDirection(out);
+
+ // compute pdf
+ float pdf = 0.0f;
+ if(out.z >= 0.0f)
+ pdf = (_sharpness + 1.0f) / (2.0f * PI) * pow(reflected.dot(out), _sharpness);
+
+ // Done.
+ return brdfSample(out, pdf, this->reflectance(in, out));
+}
+
+
+bool phongBrdf::isSpecular(void) const
+{
+ // Consider low roughness to be diffuse.
+ // Use 5.0f as an arbitrary threshold.
+ return (_sharpness > 5.0f);
+}
+
+
+bool phongBrdf::isDiffuse(void) const
+{
+ return !isSpecular();
+}
+
+
+float phongBrdf::reflectivity(void) const
+{
+ // Done.
+ return (_albedo.r + _albedo.g + _albedo.b) / 3.0f;
+}
+
+
+/////////////////////
+// Private Methods //
+/////////////////////
+void phongBrdf::_assign(const phongBrdf& src)
+{
+ _albedo = src._albedo;
+ _sharpness = src._sharpness;
+}
+
+
+void phongBrdf::_swap(phongBrdf& src)
+{
+ swap(_albedo, src._albedo);
+ std::swap(_sharpness, src._sharpness);
+}
+
+
+void phongBrdf::_print(std::ostream& s) const
+{
+ s << "Phong BRDF: albedo=" << _albedo << ", sharpness=" << _sharpness;
+}