summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-04-12 14:09:46 -0400
committerTavian Barnes <tavianator@gmail.com>2011-04-12 14:09:46 -0400
commitb6d6b32a6f02965e1d088adaa6a0e051d620b878 (patch)
treec14af77cd111e37ac8cfb8b4cacf5e2229266ccf
parent167fe4ff63713d7267eb1f11651e969b0dc108f8 (diff)
downloaddimension-b6d6b32a6f02965e1d088adaa6a0e051d620b878.tar.xz
Fix up translucency semantics and API.
-rw-r--r--libdimension/color.c39
-rw-r--r--libdimension/dimension/color.h8
-rw-r--r--libdimension/raytrace.c17
-rw-r--r--libdimension/sky_sphere.c5
4 files changed, 45 insertions, 24 deletions
diff --git a/libdimension/color.c b/libdimension/color.c
index 2424e61..0b74adf 100644
--- a/libdimension/color.c
+++ b/libdimension/color.c
@@ -393,21 +393,42 @@ dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n)
return ret;
}
-/* Filters `color' through `filter' */
+/* Filters `light' through `filter' */
dmnsn_color
-dmnsn_color_filter(dmnsn_color color, dmnsn_color filter)
+dmnsn_filter_light(dmnsn_color light, dmnsn_color filter)
{
- dmnsn_color transmitted = dmnsn_color_mul(filter.trans, color);
- dmnsn_color filtered = dmnsn_color_mul(filter.filter,
- dmnsn_color_illuminate(filter, color));
-
+ dmnsn_color transmitted = dmnsn_color_mul(filter.trans, light);
+ dmnsn_color filtered = dmnsn_color_mul(
+ filter.filter,
+ dmnsn_color_illuminate(filter, light)
+ );
dmnsn_color ret = dmnsn_color_add(transmitted, filtered);
- ret.filter = color.filter*dmnsn_color_intensity(filtered)
- + filter.filter*color.trans + filter.trans*color.filter;
- ret.trans = filter.trans*color.trans;
+ ret.filter = light.filter*dmnsn_color_intensity(filtered)
+ + filter.filter*light.trans + filter.trans*light.filter;
+ ret.trans = filter.trans*light.trans;
+ return ret;
+}
+
+/* Adds the background contribution, `filtered', to `filter' */
+dmnsn_color
+dmnsn_apply_translucency(dmnsn_color filtered, dmnsn_color filter)
+{
+ dmnsn_color ret = dmnsn_color_add(
+ dmnsn_color_mul(1.0 - (filter.filter + filter.trans), filter),
+ filtered
+ );
+ ret.filter = filtered.filter;
+ ret.trans = filtered.trans;
return ret;
}
+/* Adds the background contribution of `color' to `filter' */
+dmnsn_color
+dmnsn_apply_filter(dmnsn_color color, dmnsn_color filter)
+{
+ return dmnsn_apply_translucency(dmnsn_filter_light(color, filter), filter);
+}
+
/* Illuminates `color' with `light' */
dmnsn_color
dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color)
diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h
index 363eb56..c9d777b 100644
--- a/libdimension/dimension/color.h
+++ b/libdimension/dimension/color.h
@@ -127,8 +127,12 @@ dmnsn_color dmnsn_color_add(dmnsn_color color1, dmnsn_color color2);
dmnsn_color dmnsn_color_mul(double n, dmnsn_color color);
/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */
dmnsn_color dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n);
-/** Filter \p color through \p filter. */
-dmnsn_color dmnsn_color_filter(dmnsn_color color, dmnsn_color filter);
+/** Filter \p light through \p filter. */
+dmnsn_color dmnsn_filter_light(dmnsn_color light, dmnsn_color filter);
+/** Add the background contribution \p filtered to \p filter. */
+dmnsn_color dmnsn_apply_translucency(dmnsn_color filtered, dmnsn_color filter);
+/** Add the background contribution of \p color to \p filter. */
+dmnsn_color dmnsn_apply_filter(dmnsn_color color, dmnsn_color filter);
/** Illuminate \p color with \p light. */
dmnsn_color dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color);
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index 1379c29..7a797bf 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -216,7 +216,7 @@ dmnsn_raytrace_background(dmnsn_raytrace_state *state, dmnsn_line ray)
{
dmnsn_color sky = dmnsn_sky_sphere_color(state->scene->sky_sphere,
dmnsn_vector_normalize(ray.n));
- color = dmnsn_color_add(dmnsn_color_filter(color, sky), sky);
+ color = dmnsn_apply_filter(color, sky);
}
return color;
@@ -269,7 +269,7 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state,
dmnsn_raytrace_pigment(&shadow_state);
if ((state->scene->quality & DMNSN_RENDER_TRANSLUCENCY)
&& (shadow_state.pigment.filter || shadow_state.pigment.trans)) {
- color = dmnsn_color_filter(color, shadow_state.pigment);
+ color = dmnsn_filter_light(color, shadow_state.pigment);
shadow_ray.x0 = dmnsn_line_point(shadow_ray, shadow_caster.t);
shadow_ray.n = dmnsn_vector_sub(light->x0, shadow_ray.x0);
shadow_ray = dmnsn_line_add_epsilon(shadow_ray);
@@ -396,14 +396,11 @@ dmnsn_raytrace_translucency(dmnsn_raytrace_state *state)
);
}
- state->diffuse = dmnsn_color_mul(
- 1.0 - state->pigment.filter - state->pigment.trans,
- state->diffuse
- );
-
dmnsn_color rec = dmnsn_raytrace_shoot(&recursive_state, trans_ray);
- dmnsn_color filtered = dmnsn_color_filter(rec, state->pigment);
- state->additional = dmnsn_color_add(filtered, state->additional);
+ dmnsn_color filtered = dmnsn_filter_light(rec, state->pigment);
+ state->diffuse.filter = state->pigment.filter;
+ state->diffuse.trans = state->pigment.trans;
+ state->diffuse = dmnsn_apply_translucency(filtered, state->diffuse);
}
}
@@ -411,7 +408,7 @@ dmnsn_raytrace_translucency(dmnsn_raytrace_state *state)
static dmnsn_color
dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray)
{
- if (state->reclevel <= 0)
+ if (state->reclevel == 0)
return dmnsn_black;
--state->reclevel;
diff --git a/libdimension/sky_sphere.c b/libdimension/sky_sphere.c
index 9643feb..0ea5fa3 100644
--- a/libdimension/sky_sphere.c
+++ b/libdimension/sky_sphere.c
@@ -58,14 +58,13 @@ dmnsn_initialize_sky_sphere(dmnsn_sky_sphere *sky_sphere)
dmnsn_color
dmnsn_sky_sphere_color(const dmnsn_sky_sphere *sky_sphere, dmnsn_vector d)
{
- dmnsn_color color = dmnsn_black;
- color.trans = 1.0;
+ dmnsn_color color = dmnsn_clear;
DMNSN_ARRAY_FOREACH (const dmnsn_pigment **, pigment, sky_sphere->pigments) {
dmnsn_pigment_fn *pigment_fn = (*pigment)->pigment_fn;
if (pigment_fn) {
dmnsn_color sky = pigment_fn(*pigment, d);
- color = dmnsn_color_add(dmnsn_color_filter(color, sky), sky);
+ color = dmnsn_apply_filter(color, sky);
}
}