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:
parent
c115dec69b
commit
77e99ac5a5
@ -18,6 +18,8 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_AMBIENT_OCCLUSION_DISTANCE 50.0
|
||||
|
||||
Scene::Scene(const map<string, const char *> & options,
|
||||
const char * filename)
|
||||
{
|
||||
@ -25,7 +27,7 @@ Scene::Scene(const map<string, const char *> & options,
|
||||
m_height = 600;
|
||||
m_multisample_level = 1;
|
||||
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_exposure = 1.0f;
|
||||
m_transforms.push(Transform());
|
||||
@ -213,7 +215,8 @@ Color Scene::computePhong(const refptr<Material> material,
|
||||
const Vector & surfacePoint,
|
||||
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();
|
||||
double shininess = material->getShininess();
|
||||
@ -289,7 +292,7 @@ Color Scene::calculateLightContribution(const Ray & toLight,
|
||||
const Vector & lightPosition)
|
||||
{
|
||||
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;
|
||||
|
||||
Ray currentRay = toLight;
|
||||
@ -320,3 +323,44 @@ Color Scene::calculateLightContribution(const Ray & toLight,
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ class Scene
|
||||
const Vector & surfaceNormal);
|
||||
Color calculateLightContribution(const Ray & toLight,
|
||||
const Vector & lightPosition);
|
||||
Color calculateAmbientOcclusion(const Ray & surfaceNormal);
|
||||
|
||||
/* In Scene-load.cc */
|
||||
void load(const char * filename);
|
||||
|
@ -38,6 +38,8 @@ class Color
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,6 @@ class Vector
|
||||
double dist_to(const Vector & other) const;
|
||||
Vector proj(const Vector & target) const;
|
||||
Vector reflect(const Vector & target) const;
|
||||
operator double() const { return mag(); }
|
||||
Vector getPerpendicular() const;
|
||||
|
||||
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, 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user