From f9cf1381a6402e429ea70e0320b3c86daa55e1d4 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 4 Mar 2009 02:03:21 +0000 Subject: [PATCH] working on shadows but they are appearing in weird places... git-svn-id: svn://anubis/fart/trunk@185 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene.cc | 68 ++++++++++++++++++++++++++++++++++++++++----------- main/Scene.h | 2 ++ util/Ray.cc | 5 ++++ util/Ray.h | 1 + 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/main/Scene.cc b/main/Scene.cc index 37cffb5..4aa3a26 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -250,22 +250,31 @@ Color Scene::computePhong(const refptr material, Vector reflectedLightDirection = directionToLight.reflect(surfaceNormal); - /* calculate the diffuse term */ - double diffuse_coef = directionToLight % surfaceNormal; - if (diffuse_coef > 0.0) - { - result += diffuseColor - * (*it)->getDiffuseColor() - * diffuse_coef; - } + Ray surfaceToLight(surfacePoint, directionToLight); + double light_contribution = + calculateLightContribution(surfaceToLight.shift(0.0001), *it); - /* calculate the specular term */ - double specular_coef = reflectedLightDirection % viewDirection; - if (specular_coef > 0.0) + if (light_contribution > 0.0) { - result += specularColor - * (*it)->getSpecularColor() - * pow(specular_coef, shininess); + /* calculate the diffuse term */ + double diffuse_coef = directionToLight % surfaceNormal; + if (diffuse_coef > 0.0) + { + result += diffuseColor + * (*it)->getDiffuseColor() + * diffuse_coef + * light_contribution; + } + + /* calculate the specular term */ + double specular_coef = reflectedLightDirection % viewDirection; + if (specular_coef > 0.0) + { + result += specularColor + * (*it)->getSpecularColor() + * pow(specular_coef, shininess) + * light_contribution; + } } } @@ -279,6 +288,37 @@ Color Scene::computePhong(const refptr material, return result; } + +double Scene::calculateLightContribution(const Ray & toLight, + refptr light) +{ + double contrib = 1.0; + double dist_to_light = toLight.getOrigin().dist_to(light->getPosition()); + double dist_so_far = 0.0; + + Ray currentRay = toLight; + + for (;;) + { + ShapeDistance hit = getRayClosestHit(currentRay); + + if ( hit.shape.isNull() ) + break; + + if ( dist_so_far + hit.dist > dist_to_light ) + break; + + contrib *= hit.shape->getMaterial()->getTransparency(); + + if ( contrib < SCENE_FACTOR_THRESHOLD ) + break; + + dist_so_far += hit.dist + 0.0001; + } + + return contrib; +} + bool operator<(const Scene::ShapeDistance & sd1, const Scene::ShapeDistance & sd2) { diff --git a/main/Scene.h b/main/Scene.h index efcd514..62b927e 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -56,6 +56,8 @@ class Scene const Ray & viewRay, const Vector & surfacePoint, const Vector & surfaceNormal); + double calculateLightContribution(const Ray & toLight, + refptr light); /* In Scene-load.cc */ void load(const char * filename); diff --git a/util/Ray.cc b/util/Ray.cc index 88baf51..ebf592c 100644 --- a/util/Ray.cc +++ b/util/Ray.cc @@ -31,3 +31,8 @@ std::ostream & operator<<(std::ostream & out, const Ray & r) out << "(" << r.getOrigin() << " -> " << r.getDirection() << ")"; return out; } + +Ray Ray::shift(double amt) +{ + return Ray(getPositionAt(amt), m_direction); +} diff --git a/util/Ray.h b/util/Ray.h index d251bfe..806a359 100644 --- a/util/Ray.h +++ b/util/Ray.h @@ -14,6 +14,7 @@ class Ray const Vector & getDirection() const { return m_direction; } Vector getPositionAt(double dist) const; Vector operator[](double dist) const { return getPositionAt(dist); } + Ray shift(double amt); protected: Vector m_origin;