/******************************************************************/ /* 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 #include "constants.h" #include "areaLightsource.h" ////////////////// // Constructors // ////////////////// areaLightsource::areaLightsource(const color& power, const std::shared_ptr& geometry, const vec3d& attenuation) { _power = power; _geometry = geometry; _attenuation = attenuation; if(_geometry) { _center = _geometry->sample(0.5f, 0.5).position(); _area = _geometry->area(); } } ///////////// // Methods // ///////////// lightSample areaLightsource::intensityAt(const vec3d& point) const { // use the 'center position' and emulate a point light source vec3d direction = point - _center; float distance = direction.length(); float attenuation = ((_attenuation[2]*distance + _attenuation[1])*distance + _attenuation[0]); // Done. return lightSample(direction, _power / attenuation, distance - 2.0f * EPSILON); // reduce distance to avoid self-intersection } lightSample areaLightsource::emittanceAt(const vec3d& point, float r1, float r2) const { if(!_geometry) return lightSample(); // sample surface surfaceSample sample = _geometry->sample(r1, r2); // direction vec3d direction = point - sample.position(); float distance = direction.length(); // handle backside case if(direction.dot(sample.normal()) < 0.0f) return lightSample(); // Done. return lightSample(direction, _power / (2.0f * PI * _area), distance - 2.0f * EPSILON, // reduce distance to avoid self-intersection sample.pdf(), direction.dot( sample.normal() ) / distance); } color areaLightsource::_emittance(const intersectionPoint& ip) const { // check if back hit // Note: ip.direction toward the intersection point if(ip.normal().dot(ip.direction()) > 0.0f) return color(); // evaluate emittance (assume point lies on light source) return _power / (2.0f * PI * _area); } ///////////////////// // Private Methods // ///////////////////// void areaLightsource::_print(std::ostream& s) const { if(_geometry) s << "Area Lightsource: power=" << _power << ", attenuation=" << _attenuation << ", area=" << _area << " centered at: " << _center; else s << "Invalid Area Lightsource"; }