diff options
-rw-r--r-- | intern/cycles/app/cycles_xml.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 15 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_accumulate.h | 67 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 4 | ||||
-rw-r--r-- | intern/cycles/render/film.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/render/integrator.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/integrator.h | 3 |
10 files changed, 77 insertions, 43 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 3c8e4847270..efd7e5ec66e 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -276,7 +276,8 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node) xml_read_float(&integrator->filter_glossy, node, "filter_glossy"); xml_read_int(&integrator->seed, node, "seed"); - xml_read_float(&integrator->sample_clamp, node, "sample_clamp"); + xml_read_float(&integrator->sample_clamp_direct, node, "sample_clamp_direct"); + xml_read_float(&integrator->sample_clamp_indirect, node, "sample_clamp_indirect"); } /* Camera */ diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 5adcbc67f4c..0f0bff2acfb 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -363,9 +363,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=0, ) - cls.sample_clamp = FloatProperty( - name="Clamp", - description="If non-zero, the maximum value for a sample, " + cls.sample_clamp_direct = FloatProperty( + name="Clamp Direct", + description="If non-zero, the maximum value for a direct sample, " + "higher values will be scaled down to avoid too " + "much noise and slow convergence at the cost of accuracy", + min=0.0, max=1e8, + default=0.0, + ) + + cls.sample_clamp_indirect = FloatProperty( + name="Clamp Indirect", + description="If non-zero, the maximum value for an indirect sample, " "higher values will be scaled down to avoid too " "much noise and slow convergence at the cost of accuracy", min=0.0, max=1e8, diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 3217a9697f0..65eb75a2f6f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -120,7 +120,8 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): sub = col.column(align=True) sub.label("Settings:") sub.prop(cscene, "seed") - sub.prop(cscene, "sample_clamp") + sub.prop(cscene, "sample_clamp_direct") + sub.prop(cscene, "sample_clamp_indirect") if cscene.progressive == 'PATH': col = split.column() diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 68ef209371d..4415940b359 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -182,7 +182,8 @@ void BlenderSync::sync_integrator() integrator->layer_flag = render_layer.layer; - integrator->sample_clamp = get_float(cscene, "sample_clamp"); + integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct"); + integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect"); #ifdef __CAMERA_MOTION__ if(!preview) { if(integrator->motion_blur != r.use_motion_blur()) { diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 24e9d7b8858..80f3bfd33a0 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -316,15 +316,50 @@ ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L) #endif } -ccl_device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) +ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L) { #ifdef __PASSES__ if(L->use_light_pass) { path_radiance_sum_indirect(L); - float3 L_sum = L->emission - + L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface - + L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface; + float3 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->emission; + float3 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface; + +#ifdef __CLAMP_SAMPLE__ + float clamp_direct = kernel_data.integrator.sample_clamp_direct; + float clamp_indirect = kernel_data.integrator.sample_clamp_indirect; + + if(clamp_direct != FLT_MAX || clamp_indirect != FLT_MAX) { + float scale; + + /* Direct */ + float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z); + if(sum_direct > clamp_direct) { + scale = clamp_direct/sum_direct; + L_direct *= scale; + + L->direct_diffuse *= scale; + L->direct_glossy *= scale; + L->direct_transmission *= scale; + L->direct_subsurface *= scale; + L->emission *= scale; + } + + /* Indirect */ + float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z); + if(sum_indirect > clamp_indirect) { + scale = clamp_indirect/sum_indirect; + L_indirect *= scale; + + L->indirect_diffuse *= scale; + L->indirect_glossy *= scale; + L->indirect_transmission *= scale; + L->indirect_subsurface *= scale; + } + } +#endif + /* Combine */ + float3 L_sum = L_direct + L_indirect; if(!kernel_data.background.transparent) L_sum += L->background; @@ -338,7 +373,7 @@ ccl_device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) #endif } -ccl_device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float clamp) +ccl_device_inline void path_radiance_reject(PathRadiance *L, float3 *L_sum) { float sum = fabsf((*L_sum).x) + fabsf((*L_sum).y) + fabsf((*L_sum).z); @@ -362,28 +397,6 @@ ccl_device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float } #endif } - else if(sum > clamp) { - /* value to high, scale down */ - float scale = clamp/sum; - - *L_sum *= scale; - -#ifdef __PASSES__ - if(L->use_light_pass) { - L->direct_diffuse *= scale; - L->direct_glossy *= scale; - L->direct_transmission *= scale; - L->direct_subsurface *= scale; - - L->indirect_diffuse *= scale; - L->indirect_glossy *= scale; - L->indirect_transmission *= scale; - L->indirect_subsurface *= scale; - - L->emission *= scale; - } -#endif - } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index aabac2e8e5e..77bc20468f4 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -884,10 +884,10 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, ray.t = FLT_MAX; } - float3 L_sum = path_radiance_sum(kg, &L); + float3 L_sum = path_radiance_clamp_and_sum(kg, &L); #ifdef __CLAMP_SAMPLE__ - path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); + path_radiance_reject(&L, &L_sum); #endif kernel_write_light_passes(kg, buffer, &L, sample); @@ -1320,10 +1320,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in #endif } - float3 L_sum = path_radiance_sum(kg, &L); + float3 L_sum = path_radiance_clamp_and_sum(kg, &L); #ifdef __CLAMP_SAMPLE__ - path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); + path_radiance_reject(&L, &L_sum); #endif kernel_write_light_passes(kg, buffer, &L, sample); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 06bf6b7c5dd..5ee25a6cb98 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -822,7 +822,9 @@ typedef struct KernelIntegrator { int layer_flag; /* clamp */ - float sample_clamp; + float sample_clamp_direct; + float sample_clamp_indirect; + float pad1, pad2, pad3; /* branched path */ int branched; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 23a70303557..0a1a88e6bfb 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -288,12 +288,15 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) device_free(device, dscene, scene); KernelFilm *kfilm = &dscene->data.film; + KernelIntegrator *kintegrator = &dscene->data.integrator; + + bool use_clamping = (kintegrator->sample_clamp_direct != FLT_MAX) || (kintegrator->sample_clamp_indirect != FLT_MAX); /* update __data */ kfilm->exposure = exposure; kfilm->pass_flag = 0; kfilm->pass_stride = 0; - kfilm->use_light_pass = use_light_visibility; + kfilm->use_light_pass = use_light_visibility || use_clamping; foreach(Pass& pass, passes) { kfilm->pass_flag |= pass.type; diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 1042a5c4102..f48e04f31e1 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -48,7 +48,8 @@ Integrator::Integrator() filter_glossy = 0.0f; seed = 0; layer_flag = ~0; - sample_clamp = 0.0f; + sample_clamp_direct = 0.0f; + sample_clamp_indirect = 0.0f; motion_blur = false; aa_samples = 0; @@ -115,7 +116,8 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->use_ambient_occlusion = ((dscene->data.film.pass_flag & PASS_AO) || dscene->data.background.ao_factor != 0.0f); - kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f; + kintegrator->sample_clamp_direct = (sample_clamp_direct == 0.0f)? FLT_MAX: sample_clamp_direct*3.0f; + kintegrator->sample_clamp_indirect = (sample_clamp_indirect == 0.0f)? FLT_MAX: sample_clamp_indirect*3.0f; kintegrator->branched = (method == BRANCHED_PATH); kintegrator->aa_samples = aa_samples; @@ -180,7 +182,8 @@ bool Integrator::modified(const Integrator& integrator) filter_glossy == integrator.filter_glossy && layer_flag == integrator.layer_flag && seed == integrator.seed && - sample_clamp == integrator.sample_clamp && + sample_clamp_direct == integrator.sample_clamp_direct && + sample_clamp_indirect == integrator.sample_clamp_indirect && method == integrator.method && aa_samples == integrator.aa_samples && diffuse_samples == integrator.diffuse_samples && diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index cc4a28a4e54..573b258af60 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -50,7 +50,8 @@ public: int seed; int layer_flag; - float sample_clamp; + float sample_clamp_direct; + float sample_clamp_indirect; bool motion_blur; int aa_samples; |