diff options
Diffstat (limited to 'hw6/src/phongBrdf.cpp')
-rw-r--r-- | hw6/src/phongBrdf.cpp | 133 |
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; +} |