diff --git a/main/Light.cc b/main/Light.cc index 8afd582..bccaae2 100644 --- a/main/Light.cc +++ b/main/Light.cc @@ -12,7 +12,9 @@ Light::Light() m_radius = 1.0; } -Vector Light::getJitterPosition() const +Vector Light::getJitterPosition(int index) const { + if (index == 0) + return m_position; return m_position + Vector::randomVector() * m_radius; } diff --git a/main/Light.h b/main/Light.h index 88ebe30..99b5db9 100644 --- a/main/Light.h +++ b/main/Light.h @@ -14,7 +14,7 @@ class Light void setPosition(refptr vec) { setPosition(*vec); } const Vector & getPosition() const { return m_position; } - Vector getJitterPosition() const; + Vector getJitterPosition(int index) const; void setDiffuseColor(const Color & diffuse) { @@ -27,9 +27,13 @@ class Light m_specular_color = specular; } const Color & getSpecularColor() const { return m_specular_color; } + void setJitter(int j) { m_jitter = j; } int getJitter() const { return m_jitter; } + void setRadius(double r) { m_radius = r; } + double getRadius() const { return m_radius; } + protected: Vector m_position; Color m_diffuse_color; diff --git a/main/Scene-load.cc b/main/Scene-load.cc index b1fd18d..1bd736c 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -395,6 +395,14 @@ refptr Scene::processLight(refptr node) light->setDiffuseColor(c); light->setSpecularColor(c); } + else if ( typeid(**it) == typeid(RadiusNode) ) + { + light->setRadius((*it)->getNumber()); + } + else if ( typeid(**it) == typeid(JitterNode) ) + { + light->setJitter((*it)->getInteger()); + } } return light; diff --git a/main/Scene.cc b/main/Scene.cc index f6fb123..3f237e3 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -224,37 +224,46 @@ Color Scene::computePhong(const refptr material, it != m_lights.end(); it++) { - Vector directionToLight = (*it)->getPosition() - surfacePoint; - directionToLight.normalize(); - Vector reflectedLightDirection = - directionToLight.reflect(surfaceNormal); - - Ray surfaceToLight(surfacePoint, directionToLight); - Color light_contribution = - calculateLightContribution(surfaceToLight.shift(0.0001), *it); - - if ( light_contribution.r > 0.0 - || light_contribution.g > 0.0 - || light_contribution.b > 0.0 ) + for (int jitter_index = 0, jitter_max = (*it)->getJitter(); + jitter_index < jitter_max; + jitter_index++) { - /* calculate the diffuse term */ - double diffuse_coef = directionToLight % surfaceNormal; - if (diffuse_coef > 0.0) - { - result += diffuseColor - * (*it)->getDiffuseColor() - * diffuse_coef - * light_contribution; - } + Vector lightPosition = (*it)->getJitterPosition(jitter_index); + Vector directionToLight = lightPosition - surfacePoint; + directionToLight.normalize(); + Vector reflectedLightDirection = + directionToLight.reflect(surfaceNormal); - /* calculate the specular term */ - double specular_coef = reflectedLightDirection % viewDirection; - if (specular_coef > 0.0) + Ray surfaceToLight(surfacePoint, directionToLight); + Color light_contribution = + calculateLightContribution(surfaceToLight.shift(0.0001), + lightPosition); + + if ( light_contribution.r > 0.0 + || light_contribution.g > 0.0 + || light_contribution.b > 0.0 ) { - result += specularColor - * (*it)->getSpecularColor() - * pow(specular_coef, shininess) - * light_contribution; + /* calculate the diffuse term */ + double diffuse_coef = directionToLight % surfaceNormal; + if (diffuse_coef > 0.0) + { + result += diffuseColor + * (*it)->getDiffuseColor() + * diffuse_coef + * light_contribution + / jitter_max; + } + + /* calculate the specular term */ + double specular_coef = reflectedLightDirection % viewDirection; + if (specular_coef > 0.0) + { + result += specularColor + * (*it)->getSpecularColor() + * pow(specular_coef, shininess) + * light_contribution + / jitter_max; + } } } } @@ -263,10 +272,10 @@ Color Scene::computePhong(const refptr material, } Color Scene::calculateLightContribution(const Ray & toLight, - refptr light) + const Vector & lightPosition) { Color contrib(1.0, 1.0, 1.0); - double dist_to_light = toLight.getOrigin().dist_to(light->getPosition()); + double dist_to_light = lightPosition - toLight.getOrigin(); double dist_so_far = 0.0; Ray currentRay = toLight; diff --git a/main/Scene.h b/main/Scene.h index 62f38ff..99781eb 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -49,7 +49,7 @@ class Scene const Vector & surfacePoint, const Vector & surfaceNormal); Color calculateLightContribution(const Ray & toLight, - refptr light); + const Vector & lightPosition); /* In Scene-load.cc */ void load(const char * filename); diff --git a/scenes/subtract-subtract.fart b/scenes/subtract-subtract.fart index c11e527..0909b98 100644 --- a/scenes/subtract-subtract.fart +++ b/scenes/subtract-subtract.fart @@ -15,7 +15,7 @@ scene light { position <-1, -3, 4> - jitter 5 + jitter 50 } plane diff --git a/util/Vector.cc b/util/Vector.cc index 1744dcb..9e2df3a 100644 --- a/util/Vector.cc +++ b/util/Vector.cc @@ -83,6 +83,18 @@ Vector Vector::reflect(const Vector & target) const return (*this) + me_to_proj * 2.0; } +Vector Vector::getPerpendicularVector() const +{ + Vector t = *this; + t.normalize(); + Vector p = t * Vector(0, 0, 1); + if (p.mag() <= 0.1) + { + p = t * Vector(1, 0, 0); + } + return p; +} + std::ostream & operator<<(std::ostream & out, const Vector & v) { out << "[" << v[0] << ", " << v[1] << ", " << v[2] << "]"; diff --git a/util/Vector.h b/util/Vector.h index 9e8fff4..8b37eae 100644 --- a/util/Vector.h +++ b/util/Vector.h @@ -19,7 +19,8 @@ class Vector double dist_to(const Vector & other) const; Vector proj(const Vector & target) const; Vector reflect(const Vector & target) const; - operator double() { return mag(); } + operator double() const { return mag(); } + Vector getPerpendicularVector() const; protected: double m_array[3];