reworked Scene::traceRayRecurse() to handle backfaces properly for refraction

git-svn-id: svn://anubis/fart/trunk@378 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-10-12 16:39:29 +00:00
parent b24aea4dba
commit 1d5d043928
2 changed files with 76 additions and 48 deletions

View File

@ -119,8 +119,7 @@ void Scene::renderPixel(int x, int y, unsigned char * pixel)
Color Scene::traceRay(const Ray & ray) Color Scene::traceRay(const Ray & ray)
{ {
static refptr<Material> air = new Material(); return traceRayRecurse(ray, m_max_depth, 1.0, NULL);
return traceRayRecurse(ray, m_max_depth, 1.0, air);
} }
/** /**
@ -129,7 +128,11 @@ Color Scene::traceRay(const Ray & ray)
Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor, Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor,
refptr<Material> last_material) refptr<Material> last_material)
{ {
Color color; static refptr<Material> air = new Material();
Color color(0, 0, 0);
if (last_material.isNull())
last_material = air;
Shape::Intersection hit = getRayClosestHit(ray); Shape::Intersection hit = getRayClosestHit(ray);
@ -139,52 +142,63 @@ Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor,
refptr<Material> material = hit.shape->getMaterial(); refptr<Material> material = hit.shape->getMaterial();
/* check for backfaces */ /* check for backfaces */
if (ray.getDirection() % hit.normal > 0.0) bool frontface = ray.getDirection() % hit.normal < 0.0;
if (frontface)
{ {
/* if dot product is positive, this is a back-face */ color = computePhong(material,
hit.normal = -hit.normal; ray,
hit.position,
hit.normal);
if (depth > 0 && factor > SCENE_FACTOR_THRESHOLD)
{
double reflectance = material->getReflectance();
if (factor * reflectance > SCENE_FACTOR_THRESHOLD)
{
color *= (1.0 - reflectance);
Vector reflected_direction =
ray.getDirection().reflect(hit.normal);
Ray newRay(hit.position, reflected_direction);
Vector jitter_surface_point = newRay[0.0001];
Ray jitterNewRay(jitter_surface_point, reflected_direction);
Color c = traceRayRecurse(jitterNewRay,
depth - 1,
factor * reflectance,
material);
color += c * reflectance;
}
double transparency = material->getTransparency();
if (factor * transparency > SCENE_FACTOR_THRESHOLD)
{
color *= (1.0 - transparency);
Vector jitter_surface_point = hit.position
+ ray.getDirection() * 0.0001;
Vector refracted_direction =
ray.getDirection().refract(hit.normal,
last_material->getRefraction(),
material->getRefraction());
Ray newRay(jitter_surface_point, refracted_direction);
Color c = traceRayRecurse(newRay,
depth - 1,
factor * transparency,
material);
color += c * transparency;
}
}
} }
else
color = computePhong(material,
ray,
hit.position,
hit.normal);
if (depth > 0 && factor > SCENE_FACTOR_THRESHOLD)
{ {
double reflectance = material->getReflectance(); material = air;
if (factor * reflectance > SCENE_FACTOR_THRESHOLD) Vector jitter_surface_point = hit.position
{ + ray.getDirection() * 0.0001;
color *= (1.0 - reflectance); Vector refracted_direction =
Vector reflected_direction = ray.getDirection().refract(-hit.normal,
ray.getDirection().reflect(hit.normal); last_material->getRefraction(),
Ray newRay(hit.position, reflected_direction); material->getRefraction());
Vector jitter_surface_point = newRay[0.0001]; Ray newRay(jitter_surface_point, refracted_direction);
Ray jitterNewRay(jitter_surface_point, reflected_direction); color = traceRayRecurse(newRay, depth, factor, material);
Color c = traceRayRecurse(jitterNewRay,
depth - 1,
factor * reflectance,
material);
color += c * reflectance;
}
double transparency = material->getTransparency();
if (factor * transparency > SCENE_FACTOR_THRESHOLD)
{
color *= (1.0 - transparency);
Vector jitter_surface_point = hit.position
+ ray.getDirection() * 0.0001;
Vector refracted_direction =
ray.getDirection().refract(hit.normal,
last_material->getRefraction(),
material->getRefraction());
Ray newRay(jitter_surface_point, refracted_direction);
Color c = traceRayRecurse(newRay,
depth - 1,
factor * transparency,
material);
color += c * transparency;
}
} }
} }

View File

@ -3,7 +3,7 @@ scene
{ {
camera camera
{ {
position <0, 0, 40> position <0, -40, 40>
look_at <0, 100, 5> look_at <0, 100, 5>
} }
@ -17,6 +17,12 @@ scene
color <0, 0.8, 1> color <0, 0.8, 1>
} }
define material glass
{
transparency 1
refraction 1.5
}
plane plane
{ {
position <0, 0, 1>, 0 position <0, 0, 1>, 0
@ -34,7 +40,15 @@ scene
{ {
radius 10 radius 10
translate <$x, $y, 10> translate <$x, $y, 10>
material mat if ($x == 0 && $y == 0)
{
material glass
translate <0, 0, 20>
}
else
{
material mat
}
} }
} }
} }