added initial ambient occlusion attempt... but don't like it

git-svn-id: svn://anubis/fart/trunk@261 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-06-29 17:44:36 +00:00
parent c115dec69b
commit 77e99ac5a5
4 changed files with 52 additions and 4 deletions

View File

@ -18,6 +18,8 @@
using namespace std; using namespace std;
#define MAX_AMBIENT_OCCLUSION_DISTANCE 50.0
Scene::Scene(const map<string, const char *> & options, Scene::Scene(const map<string, const char *> & options,
const char * filename) const char * filename)
{ {
@ -25,7 +27,7 @@ Scene::Scene(const map<string, const char *> & options,
m_height = 600; m_height = 600;
m_multisample_level = 1; m_multisample_level = 1;
m_vfov = 60.0; m_vfov = 60.0;
m_ambient_light = Color(0.1, 0.1, 0.1); m_ambient_light = Color(0.2, 0.2, 0.2);
m_max_depth = 10; m_max_depth = 10;
m_exposure = 1.0f; m_exposure = 1.0f;
m_transforms.push(Transform()); m_transforms.push(Transform());
@ -213,7 +215,8 @@ Color Scene::computePhong(const refptr<Material> material,
const Vector & surfacePoint, const Vector & surfacePoint,
const Vector & surfaceNormal) const Vector & surfaceNormal)
{ {
Color result = m_ambient_light * material->getAmbientColor(); Color result = m_ambient_light * material->getAmbientColor()
* calculateAmbientOcclusion(Ray(surfacePoint, surfaceNormal).shift(1e-7));
Vector viewDirection = -viewRay.getDirection(); Vector viewDirection = -viewRay.getDirection();
double shininess = material->getShininess(); double shininess = material->getShininess();
@ -289,7 +292,7 @@ Color Scene::calculateLightContribution(const Ray & toLight,
const Vector & lightPosition) const Vector & lightPosition)
{ {
Color contrib(1.0, 1.0, 1.0); Color contrib(1.0, 1.0, 1.0);
double dist_to_light = lightPosition - toLight.getOrigin(); double dist_to_light = (lightPosition - toLight.getOrigin()).mag();
double dist_so_far = 0.0; double dist_so_far = 0.0;
Ray currentRay = toLight; Ray currentRay = toLight;
@ -320,3 +323,44 @@ Color Scene::calculateLightContribution(const Ray & toLight,
return contrib; return contrib;
} }
Color Scene::calculateAmbientOcclusion(const Ray & surfaceNormal)
{
Color result(1, 1, 1);
const int nISteps = 6, nJSteps = 3;
int nRays = 0;
Vector perpX = surfaceNormal.getDirection().getPerpendicular().normalize();
Vector perpY = (surfaceNormal.getDirection() * perpX).normalize();
double istep = 2.0 * M_PI / nISteps;
double jstep = M_PI_2 / nJSteps;
for (int i = 0; i < nISteps; i++)
{
int lim = i > 0 ? nJSteps : 1;
for (int j = 0; j < lim; j++)
{
Vector direction = cos(i * istep) * sin(j * jstep) * perpX
+ sin(i * istep) * sin(j * jstep) * perpY
+ cos(j * jstep) * surfaceNormal.getDirection();
Ray thisRay(surfaceNormal.getOrigin(), direction);
double dist = 0.0;
Color contrib(1, 1, 1);
while (contrib.r > 0.2 && contrib.g > 0.2 && contrib.b > 0.2)
{
Shape::Intersection hit = getRayClosestHit(thisRay);
if (hit.shape.isNull())
break;
double hitDist = (hit.position - thisRay.getOrigin()).mag();
dist += hitDist;
if (dist > MAX_AMBIENT_OCCLUSION_DISTANCE)
break;
contrib *= hit.shape->getMaterial()->getTransparency()
* hit.shape->getMaterial()->getDiffuseColor();
thisRay = thisRay.shift(hitDist + 1E-7);
}
result += contrib;
nRays++;
}
}
result /= nRays;
return result;
}

View File

@ -50,6 +50,7 @@ class Scene
const Vector & surfaceNormal); const Vector & surfaceNormal);
Color calculateLightContribution(const Ray & toLight, Color calculateLightContribution(const Ray & toLight,
const Vector & lightPosition); const Vector & lightPosition);
Color calculateAmbientOcclusion(const Ray & surfaceNormal);
/* In Scene-load.cc */ /* In Scene-load.cc */
void load(const char * filename); void load(const char * filename);

View File

@ -38,6 +38,8 @@ class Color
Color operator+(const Color & c1, const Color & c2); Color operator+(const Color & c1, const Color & c2);
Color operator-(const Color & c1, const Color & c2); Color operator-(const Color & c1, const Color & c2);
static inline Color operator*(double d, const Color & c) { return c * d; }
static inline Color operator/(double d, const Color & c) { return c / d; }
std::ostream & operator<<(std::ostream & out, const Color & color); std::ostream & operator<<(std::ostream & out, const Color & color);
#endif #endif

View File

@ -19,7 +19,6 @@ class Vector
double dist_to(const Vector & other) const; double dist_to(const Vector & other) const;
Vector proj(const Vector & target) const; Vector proj(const Vector & target) const;
Vector reflect(const Vector & target) const; Vector reflect(const Vector & target) const;
operator double() const { return mag(); }
Vector getPerpendicular() const; Vector getPerpendicular() const;
protected: protected:
@ -33,5 +32,7 @@ Vector operator+(const Vector & v1, const Vector & v2);
Vector operator-(const Vector & v1, const Vector & v2); Vector operator-(const Vector & v1, const Vector & v2);
Vector operator*(const Vector & v1, double scale); Vector operator*(const Vector & v1, double scale);
Vector operator/(const Vector & v1, double scale); Vector operator/(const Vector & v1, double scale);
static inline Vector operator*(double d, const Vector & v) { return v * d; }
static inline Vector operator/(double d, const Vector & v) { return v / d; }
#endif #endif