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.
This commit is contained in:
Sergey Sharybin 2014-10-22 18:08:17 +02:00
parent e2c04a8bf0
commit 7429113143
3 changed files with 29 additions and 1 deletions

@ -54,6 +54,7 @@ enum_bvh_types = (
enum_filter_types = ( enum_filter_types = (
('BOX', "Box", "Box filter"), ('BOX', "Box", "Box filter"),
('GAUSSIAN', "Gaussian", "Gaussian filter"), ('GAUSSIAN', "Gaussian", "Gaussian filter"),
('MITCHELL', "Mitchell-Netravali", "Mitchell-Netravali filter"),
) )
enum_aperture_types = ( enum_aperture_types = (

@ -198,6 +198,29 @@ static float filter_func_gaussian(float v, float width)
return expf(-2.0f*v*v); 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<float> filter_table(FilterType type, float width) static vector<float> filter_table(FilterType type, float width)
{ {
const int filter_table_size = FILTER_TABLE_SIZE-1; const int filter_table_size = FILTER_TABLE_SIZE-1;
@ -213,6 +236,9 @@ static vector<float> filter_table(FilterType type, float width)
case FILTER_GAUSSIAN: case FILTER_GAUSSIAN:
filter_func = filter_func_gaussian; filter_func = filter_func_gaussian;
break; break;
case FILTER_MITCHELL:
filter_func = filter_func_mitchell;
break;
default: default:
assert(0); assert(0);
} }

@ -30,7 +30,8 @@ class Scene;
typedef enum FilterType { typedef enum FilterType {
FILTER_BOX, FILTER_BOX,
FILTER_GAUSSIAN FILTER_GAUSSIAN,
FILTER_MITCHELL,
} FilterType; } FilterType;
class Pass { class Pass {