From 742911314322e5dae3a07469d0ca53b61427f978 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 22 Oct 2014 18:08:17 +0200 Subject: [PATCH] Cycles: Implement Mitchell-Netravali pixel filter It's the same filter which is used by default by Blender Internal renderer and it gives crispier edges than gaussian filter. Default filter for Cycles is unchanged because it's unclear if new filter gives more noise or not. After some further real production tests we can consider making Mitchell filter default for Cycles as well. --- intern/cycles/blender/addon/properties.py | 1 + intern/cycles/render/film.cpp | 26 +++++++++++++++++++++++ intern/cycles/render/film.h | 3 ++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 05a6f70d423..7524fe366aa 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -54,6 +54,7 @@ enum_bvh_types = ( enum_filter_types = ( ('BOX', "Box", "Box filter"), ('GAUSSIAN', "Gaussian", "Gaussian filter"), + ('MITCHELL', "Mitchell-Netravali", "Mitchell-Netravali filter"), ) enum_aperture_types = ( diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 19f959d4ea1..76a92d3d704 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -198,6 +198,29 @@ static float filter_func_gaussian(float v, float width) return expf(-2.0f*v*v); } +static float filter_func_mitchell(float v, float width) +{ + (void)width; /* Ignored. */ + + /* B = 1, C = 0 - cubic B-spline */ + /* B = 1/3, C = 1/3 - recommended */ + /* B = 0, C = 1/2 - Catmull-Rom spline */ + const float B = 1.0f / 3.0f; + const float C = 1.0f / 3.0f; + + const float ax = fabsf(v); + if (ax < 1.0f) { + return ((12.0f - 9.0f * B - 6 * C) * ax * ax * ax + + (-18.0f + 12.0f * B + 6.0f * C) * ax * ax + + (6.0f - 2.0f * B)) / 6.0f; + } else if ((ax >= 1.0f) && (ax < 2.0f)) { + return ((-B - 6.0f * C) * ax * ax * ax + + (6.0f * B + 30.0f * C) * ax * ax + (-12.0f * B - 48.0f * C) * + ax + (8.0f * B + 24.0f * C)) / 6.0f; + } + return 0.0f; +} + static vector filter_table(FilterType type, float width) { const int filter_table_size = FILTER_TABLE_SIZE-1; @@ -213,6 +236,9 @@ static vector filter_table(FilterType type, float width) case FILTER_GAUSSIAN: filter_func = filter_func_gaussian; break; + case FILTER_MITCHELL: + filter_func = filter_func_mitchell; + break; default: assert(0); } diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h index cc7183bfd95..31cc7697679 100644 --- a/intern/cycles/render/film.h +++ b/intern/cycles/render/film.h @@ -30,7 +30,8 @@ class Scene; typedef enum FilterType { FILTER_BOX, - FILTER_GAUSSIAN + FILTER_GAUSSIAN, + FILTER_MITCHELL, } FilterType; class Pass {