summaryrefslogtreecommitdiffstats
path: root/libdimension/raytrace.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-11-18 23:30:38 -0500
committerTavian Barnes <tavianator@gmail.com>2009-11-18 23:30:38 -0500
commit5038d1f96af332e474a1e0a076bf5dead6855727 (patch)
tree128921e3bbdc29046695ac4d9c9fb8d7535bc49a /libdimension/raytrace.c
parentc576229cc54c0fb963967751281e6a42fc9230ea (diff)
downloaddimension-5038d1f96af332e474a1e0a076bf5dead6855727.tar.xz
Translucency support.
Diffstat (limited to 'libdimension/raytrace.c')
-rw-r--r--libdimension/raytrace.c96
1 files changed, 67 insertions, 29 deletions
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index 7608d85..1024a7e 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -316,28 +316,31 @@ dmnsn_raytrace_lighting(dmnsn_intersection *intersection, dmnsn_scene *scene,
);
/* Search for an object in the way of the light source */
- dmnsn_intersection *shadow_caster
- = dmnsn_kD_splay_search(kD_splay_tree, shadow_ray);
- bool lit = !shadow_caster || shadow_caster->t > 1.0;
- dmnsn_delete_intersection(shadow_caster);
-
- if (scene->quality >= DMNSN_RENDER_FINISH && finish) {
- dmnsn_color light_color = dmnsn_black;
- if (lit)
- light_color = (*light->light_fn)(light, x0);
-
- dmnsn_vector ray = dmnsn_vector_normalize(shadow_ray.n);
- dmnsn_vector normal = intersection->normal;
- dmnsn_vector viewer
- = dmnsn_vector_normalize(dmnsn_vector_negate(intersection->ray.n));
-
- /* Get this light's color contribution to the object */
- dmnsn_color contrib = (*finish->finish_fn)(finish,
- light_color, color,
- ray, normal, viewer);
- illum = dmnsn_color_add(contrib, illum);
- } else if (lit) {
- illum = color;
+ bool lit = dmnsn_vector_dot(shadow_ray.n, intersection->normal) > 0.0;
+ if (lit) {
+ dmnsn_intersection *shadow_caster
+ = dmnsn_kD_splay_search(kD_splay_tree, shadow_ray);
+ lit = (!shadow_caster || shadow_caster->t > 1.0);
+ dmnsn_delete_intersection(shadow_caster);
+ }
+
+ if (lit) {
+ if (scene->quality >= DMNSN_RENDER_FINISH && finish) {
+ dmnsn_color light_color = (*light->light_fn)(light, x0);
+
+ dmnsn_vector ray = dmnsn_vector_normalize(shadow_ray.n);
+ dmnsn_vector normal = intersection->normal;
+ dmnsn_vector viewer
+ = dmnsn_vector_normalize(dmnsn_vector_negate(intersection->ray.n));
+
+ /* Get this light's color contribution to the object */
+ dmnsn_color contrib = (*finish->finish_fn)(finish,
+ light_color, color,
+ ray, normal, viewer);
+ illum = dmnsn_color_add(contrib, illum);
+ } else {
+ illum = color;
+ }
}
}
@@ -347,24 +350,59 @@ dmnsn_raytrace_lighting(dmnsn_intersection *intersection, dmnsn_scene *scene,
/* Shoot a ray, and calculate the color, using `color' as the background */
static dmnsn_color
dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene,
- dmnsn_kD_splay_tree *kD_splay_tree, dmnsn_color color)
+ dmnsn_kD_splay_tree *kD_splay_tree, dmnsn_color background)
{
dmnsn_intersection *intersection = dmnsn_kD_splay_search(kD_splay_tree, ray);
+ dmnsn_color color = background;
if (intersection) {
- /* Default to black if we aren't rendering pigments */
- color = dmnsn_black;
-
+ /* Get the pigment of the object */
+ dmnsn_color pigment = dmnsn_black;
if (scene->quality >= DMNSN_RENDER_PIGMENT) {
- color = dmnsn_raytrace_pigment(intersection, scene);
+ pigment = dmnsn_raytrace_pigment(intersection, scene);
}
+ color = pigment;
+ color.filter = 0.0;
+ color.trans = 0.0;
+ /* Account for finishes and shadows */
+ dmnsn_color illum = pigment;
if (scene->quality >= DMNSN_RENDER_LIGHTS) {
- color = dmnsn_raytrace_lighting(intersection,
+ illum = dmnsn_raytrace_lighting(intersection,
scene,
kD_splay_tree,
- color);
+ pigment);
+ }
+ color = illum;
+ color.filter = 0.0;
+ color.trans = 0.0;
+
+ /* Account for translucency */
+ dmnsn_color trans = illum;
+ if (scene->quality >= DMNSN_RENDER_TRANSLUCENCY
+ && (pigment.filter || pigment.trans))
+ {
+ trans = dmnsn_color_mul(1.0 - pigment.filter - pigment.trans, illum);
+ trans.filter = 0.0;
+ trans.trans = 0.0;
+
+ dmnsn_line trans_ray = dmnsn_line_construct(
+ dmnsn_vector_add(
+ dmnsn_line_point(ray, intersection->t),
+ dmnsn_vector_mul(1.0e-9, ray.n)
+ ),
+ ray.n
+ );
+ trans_ray.n = ray.n;
+
+ dmnsn_color rec = dmnsn_raytrace_shoot(trans_ray,
+ scene,
+ kD_splay_tree,
+ background);
+ dmnsn_color filtered = dmnsn_color_filter(rec, pigment);
+ trans = dmnsn_color_add(trans, filtered);
}
+ color = trans;
dmnsn_delete_intersection(intersection);
}