trying new jitter method for soft shadows, getting better

git-svn-id: svn://anubis/fart/trunk@257 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-07-13 06:35:45 +00:00
parent eb14077ab7
commit 57a4e6ed8a
7 changed files with 74 additions and 40 deletions

View File

@ -28,7 +28,7 @@ class Light
} }
const Color & getSpecularColor() const { return m_specular_color; } const Color & getSpecularColor() const { return m_specular_color; }
void setJitter(int j) { m_jitter = j; } void setJitter(int j) { m_jitter = j >= 1 ? j : 1; }
int getJitter() const { return m_jitter; } int getJitter() const { return m_jitter; }
void setRadius(double r) { m_radius = r; } void setRadius(double r) { m_radius = r; }

View File

@ -1,5 +1,5 @@
#include <math.h> /* exp(), pow() */ #include <math.h> /* exp(), pow(), M_PI */
#include <stdlib.h> #include <stdlib.h>
#include <string> #include <string>
@ -224,48 +224,64 @@ Color Scene::computePhong(const refptr<Material> material,
it != m_lights.end(); it != m_lights.end();
it++) it++)
{ {
for (int jitter_index = 0, jitter_max = (*it)->getJitter(); Vector lightC = (*it)->getPosition();
jitter_index < jitter_max; double lightRadius = (*it)->getRadius();
jitter_index++) Vector directionToLightC = lightC - surfacePoint;
Vector lightPlaneX = directionToLightC.getPerpendicular().normalize();
Vector lightPlaneY = (directionToLightC * lightPlaneX).normalize();
int jitter_samples = 0, jitter_level = (*it)->getJitter();;
for (int jitter_index = 0; jitter_index < jitter_level; jitter_index++)
{ {
Vector lightPosition = (*it)->getJitterPosition(jitter_index); #if 0
Vector directionToLight = lightPosition - surfacePoint; double offset = ((double)rand()) / RAND_MAX * M_2_PI;
directionToLight.normalize(); #endif
Vector reflectedLightDirection = double offset = 0.0;
directionToLight.reflect(surfaceNormal); double jitterRadius = jitter_index * lightRadius
/ (jitter_level - 0.5);
Ray surfaceToLight(surfacePoint, directionToLight); for (int i = 0, num = (int) (M_PI * jitter_index) + 1; i < num; i++)
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 )
{ {
/* calculate the diffuse term */ jitter_samples++;
double diffuse_coef = directionToLight % surfaceNormal; double jitter_angle = offset + i * M_2_PI / num;
if (diffuse_coef > 0.0) Vector jitterPosition = lightC
{ + lightPlaneX * jitterRadius * cos(jitter_angle)
result += diffuseColor + lightPlaneY * jitterRadius * sin(jitter_angle);
* (*it)->getDiffuseColor() Vector directionToLight = jitterPosition - surfacePoint;
* diffuse_coef directionToLight.normalize();
* light_contribution Vector reflectedLightDirection =
/ jitter_max; directionToLight.reflect(surfaceNormal);
}
/* calculate the specular term */ Ray surfaceToLight(surfacePoint, directionToLight);
double specular_coef = reflectedLightDirection % viewDirection; Color light_contribution =
if (specular_coef > 0.0) calculateLightContribution(surfaceToLight.shift(0.0001),
jitterPosition);
if ( light_contribution.r > 0.0
|| light_contribution.g > 0.0
|| light_contribution.b > 0.0 )
{ {
result += specularColor /* calculate the diffuse term */
* (*it)->getSpecularColor() double diffuse_coef = directionToLight % surfaceNormal;
* pow(specular_coef, shininess) if (diffuse_coef > 0.0)
* light_contribution {
/ jitter_max; 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;
}
} }
} }
} }
result /= jitter_samples;
} }
return result; return result;

View File

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

View File

@ -87,6 +87,22 @@ Color & Color::operator*=(const Color & other)
return *this; return *this;
} }
Color & Color::operator/=(double scale)
{
r /= scale;
g /= scale;
b /= scale;
return *this;
}
Color & Color::operator/=(const Color & other)
{
r /= other.r;
g /= other.g;
b /= other.b;
return *this;
}
Color operator+(const Color & c1, const Color & c2) Color operator+(const Color & c1, const Color & c2)
{ {
return Color(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b); return Color(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b);

View File

@ -23,6 +23,8 @@ class Color
Color & operator-=(const Color & other); Color & operator-=(const Color & other);
Color & operator*=(double scale); Color & operator*=(double scale);
Color & operator*=(const Color & other); Color & operator*=(const Color & other);
Color & operator/=(double scale);
Color & operator/=(const Color & other);
static const Color black; static const Color black;
static const Color white; static const Color white;

View File

@ -83,7 +83,7 @@ Vector Vector::reflect(const Vector & target) const
return (*this) + me_to_proj * 2.0; return (*this) + me_to_proj * 2.0;
} }
Vector Vector::getPerpendicularVector() const Vector Vector::getPerpendicular() const
{ {
Vector t = *this; Vector t = *this;
t.normalize(); t.normalize();

View File

@ -20,7 +20,7 @@ class Vector
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(); } operator double() const { return mag(); }
Vector getPerpendicularVector() const; Vector getPerpendicular() const;
protected: protected:
double m_array[3]; double m_array[3];