added jitter parameter to lights, currently uses random vectors, which i'm not happy with; added Vector::getPerpendicularVector() which will be used to replace random jitter for lights

git-svn-id: svn://anubis/fart/trunk@256 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-06-25 18:12:00 +00:00
parent 1af787b9ab
commit eb14077ab7
8 changed files with 71 additions and 35 deletions

View File

@ -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;
}

View File

@ -14,7 +14,7 @@ class Light
void setPosition(refptr<Vector> 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;

View File

@ -395,6 +395,14 @@ refptr<Light> Scene::processLight(refptr<Node> 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;

View File

@ -224,37 +224,46 @@ Color Scene::computePhong(const refptr<Material> 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> material,
}
Color Scene::calculateLightContribution(const Ray & toLight,
refptr<Light> 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;

View File

@ -49,7 +49,7 @@ class Scene
const Vector & surfacePoint,
const Vector & surfaceNormal);
Color calculateLightContribution(const Ray & toLight,
refptr<Light> light);
const Vector & lightPosition);
/* In Scene-load.cc */
void load(const char * filename);

View File

@ -15,7 +15,7 @@ scene
light
{
position <-1, -3, 4>
jitter 5
jitter 50
}
plane

View File

@ -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] << "]";

View File

@ -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];