From e390e9e57140b6cb65c3640ac70e127af2359d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Sat, 23 Aug 2014 16:14:11 +0200 Subject: Fix T41538: Sun Beam Node has artifact at its radius. The sunbeams node was clamping the range of influence to start at 1 pixel distance from the source. This was a poor fix for artifacts caused by an off set in buffer coordinates. Since the u coordinate starts at ceil(umax) the v coordinate also has to use ceil. This also fixes some discontinuities that became visible when the source point is close to a sharp line in the input image. --- .../operations/COM_SunBeamsOperation.cpp | 29 +++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index 97f9f7b5eea..9a34dccacb1 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -93,25 +93,31 @@ struct BufferLineAccumulator { */ static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2], float dist_min, float dist_max, - int &x, int &y, int &num, float &v, float &dv) + int &x, int &y, int &num, float &v, float &dv, float &falloff_factor) { float pu, pv; buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv); /* line angle */ float tan_phi = pv / pu; - float cos_phi = 1.0f / sqrtf(tan_phi * tan_phi + 1.0f); + float dr = sqrtf(tan_phi * tan_phi + 1.0f); + float cos_phi = 1.0f / dr; - float umin = pu - cos_phi * dist_min; - float umax = pu - cos_phi * dist_max; + /* clamp u range to avoid influence of pixels "behind" the source */ + float umin = max_ff(pu - cos_phi * dist_min, 0.0f); + float umax = max_ff(pu - cos_phi * dist_max, 0.0f); v = umin * tan_phi; dv = tan_phi; - sector_to_buffer(umin, v, x, y); - x += source[0]; - y += source[1]; + int start = (int)floorf(umax); + int end = (int)ceilf(umin); + num = end - start; - num = (int)ceilf(umin) - max_ii((int)floorf(umax), 1); + sector_to_buffer(end, (int)ceilf(v), x, y); + x += (int)source[0]; + y += (int)source[1]; + + falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f; float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y); return iter; @@ -131,11 +137,10 @@ struct BufferLineAccumulator { int buffer_width = input->getWidth(); int x, y, num; float v, dv; + float falloff_factor; /* initialise the iteration variables */ - float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv); - - float falloff_factor = num > 1 ? 1.0f / (float)(num - 1) : 0.0f; + float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor); int tot = 0; @@ -273,7 +278,7 @@ void SunBeamsOperation::executePixel(float output[4], int x, int y, void *data) static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length) { - float co[2] = {x, y}; + float co[2] = {(float)x, (float)y}; float dir[2], dist; /* move (x,y) vector toward the source by ray_length distance */ -- cgit v1.2.3