Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorThomas Dinges <blender@dingto.org>2014-02-11 00:44:49 +0400
committerThomas Dinges <blender@dingto.org>2014-02-11 00:46:02 +0400
commite29a45b396ccf507d858ec4afc301bdaf816b328 (patch)
tree29bdd2ed72f2ef26d4e7300b2bf58ce9282e575b /intern
parente920206a900cf322f3894f13ffeb1568c1bdfd12 (diff)
Cycles: Separation of Indirect and Direct clamping.
Indirect and Direct samples can now be clamped individually. This way we can clamp the indirect samples (fireflies), while keeping the direct highlights. Example render: http://www.pasteall.org/pic/show.php?id=66586 WARNING: This breaks backwards compatibility. If you had Clamping enabled in an old file, you must re-enable either Direct/Indirect clamping or both again. Reviewed by: brecht Differential Revision: https://developer.blender.org/D303
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/app/cycles_xml.cpp3
-rw-r--r--intern/cycles/blender/addon/properties.py15
-rw-r--r--intern/cycles/blender/addon/ui.py3
-rw-r--r--intern/cycles/blender/blender_sync.cpp3
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h67
-rw-r--r--intern/cycles/kernel/kernel_path.h8
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/render/film.cpp5
-rw-r--r--intern/cycles/render/integrator.cpp9
-rw-r--r--intern/cycles/render/integrator.h3
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;