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:
parent
b24aea4dba
commit
1d5d043928
106
main/Scene.cc
106
main/Scene.cc
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user