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
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_accumulate.h')
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h146
1 files changed, 81 insertions, 65 deletions
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 46a51f5a560..606c288649a 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -174,13 +174,13 @@ ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
* visible as the first non-transparent hit, while indirectly visible are the
* bounces after that. */
-ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
+ccl_device_inline void path_radiance_init(KernelGlobals *kg, PathRadiance *L)
{
/* clear all */
#ifdef __PASSES__
- L->use_light_pass = use_light_pass;
+ L->use_light_pass = kernel_data.film.use_light_pass;
- if (use_light_pass) {
+ if (kernel_data.film.use_light_pass) {
L->indirect = make_float3(0.0f, 0.0f, 0.0f);
L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
@@ -285,7 +285,37 @@ ccl_device_inline void path_radiance_bsdf_bounce(KernelGlobals *kg,
}
}
-ccl_device_inline void path_radiance_accum_emission(PathRadiance *L,
+#ifdef __CLAMP_SAMPLE__
+ccl_device_forceinline void path_radiance_clamp(KernelGlobals *kg, float3 *L, int bounce)
+{
+ float limit = (bounce > 0) ? kernel_data.integrator.sample_clamp_indirect :
+ kernel_data.integrator.sample_clamp_direct;
+ float sum = reduce_add(fabs(*L));
+ if (sum > limit) {
+ *L *= limit / sum;
+ }
+}
+
+ccl_device_forceinline void path_radiance_clamp_throughput(KernelGlobals *kg,
+ float3 *L,
+ float3 *throughput,
+ int bounce)
+{
+ float limit = (bounce > 0) ? kernel_data.integrator.sample_clamp_indirect :
+ kernel_data.integrator.sample_clamp_direct;
+
+ float sum = reduce_add(fabs(*L));
+ if (sum > limit) {
+ float clamp_factor = limit / sum;
+ *L *= clamp_factor;
+ *throughput *= clamp_factor;
+ }
+}
+
+#endif
+
+ccl_device_inline void path_radiance_accum_emission(KernelGlobals *kg,
+ PathRadiance *L,
ccl_addr_space PathState *state,
float3 throughput,
float3 value)
@@ -296,23 +326,29 @@ ccl_device_inline void path_radiance_accum_emission(PathRadiance *L,
}
#endif
+ float3 contribution = throughput * value;
+#ifdef __CLAMP_SAMPLE__
+ path_radiance_clamp(kg, &contribution, state->bounce - 1);
+#endif
+
#ifdef __PASSES__
if (L->use_light_pass) {
if (state->bounce == 0)
- L->emission += throughput * value;
+ L->emission += contribution;
else if (state->bounce == 1)
- L->direct_emission += throughput * value;
+ L->direct_emission += contribution;
else
- L->indirect += throughput * value;
+ L->indirect += contribution;
}
else
#endif
{
- L->emission += throughput * value;
+ L->emission += contribution;
}
}
-ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
+ccl_device_inline void path_radiance_accum_ao(KernelGlobals *kg,
+ PathRadiance *L,
ccl_addr_space PathState *state,
float3 throughput,
float3 alpha,
@@ -339,21 +375,23 @@ ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
}
#endif
+ float3 contribution = throughput * bsdf * ao;
+
#ifdef __PASSES__
if (L->use_light_pass) {
if (state->bounce == 0) {
/* Directly visible lighting. */
- L->direct_diffuse += throughput * bsdf * ao;
+ L->direct_diffuse += contribution;
}
else {
/* Indirectly visible lighting after BSDF bounce. */
- L->indirect += throughput * bsdf * ao;
+ L->indirect += contribution;
}
}
else
#endif
{
- L->emission += throughput * bsdf * ao;
+ L->emission += contribution;
}
}
@@ -374,7 +412,8 @@ ccl_device_inline void path_radiance_accum_total_ao(PathRadiance *L,
#endif
}
-ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
+ccl_device_inline void path_radiance_accum_light(KernelGlobals *kg,
+ PathRadiance *L,
ccl_addr_space PathState *state,
float3 throughput,
BsdfEval *bsdf_eval,
@@ -394,15 +433,24 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
}
#endif
+ float3 shaded_throughput = throughput * shadow;
+
#ifdef __PASSES__
if (L->use_light_pass) {
+ /* Compute the clamping based on the total contribution.
+ * The resulting scale is then be applied to all individual components. */
+ float3 full_contribution = shaded_throughput * bsdf_eval_sum(bsdf_eval);
+# ifdef __CLAMP_SAMPLE__
+ path_radiance_clamp_throughput(kg, &full_contribution, &shaded_throughput, state->bounce);
+# endif
+
if (state->bounce == 0) {
/* directly visible lighting */
- L->direct_diffuse += throughput * bsdf_eval->diffuse * shadow;
- L->direct_glossy += throughput * bsdf_eval->glossy * shadow;
- L->direct_transmission += throughput * bsdf_eval->transmission * shadow;
- L->direct_subsurface += throughput * bsdf_eval->subsurface * shadow;
- L->direct_scatter += throughput * bsdf_eval->scatter * shadow;
+ L->direct_diffuse += shaded_throughput * bsdf_eval->diffuse;
+ L->direct_glossy += shaded_throughput * bsdf_eval->glossy;
+ L->direct_transmission += shaded_throughput * bsdf_eval->transmission;
+ L->direct_subsurface += shaded_throughput * bsdf_eval->subsurface;
+ L->direct_scatter += shaded_throughput * bsdf_eval->scatter;
if (is_lamp) {
L->shadow.x += shadow.x * shadow_fac;
@@ -412,13 +460,15 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
}
else {
/* indirectly visible lighting after BSDF bounce */
- L->indirect += throughput * bsdf_eval_sum(bsdf_eval) * shadow;
+ L->indirect += full_contribution;
}
}
else
#endif
{
- L->emission += throughput * bsdf_eval->diffuse * shadow;
+ float3 contribution = shaded_throughput * bsdf_eval->diffuse;
+ path_radiance_clamp(kg, &contribution, state->bounce);
+ L->emission += contribution;
}
}
@@ -439,7 +489,8 @@ ccl_device_inline void path_radiance_accum_total_light(PathRadiance *L,
#endif
}
-ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
+ccl_device_inline void path_radiance_accum_background(KernelGlobals *kg,
+ PathRadiance *L,
ccl_addr_space PathState *state,
float3 throughput,
float3 value)
@@ -456,19 +507,24 @@ ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
}
#endif
+ float3 contribution = throughput * value;
+#ifdef __CLAMP_SAMPLE__
+ path_radiance_clamp(kg, &contribution, state->bounce - 1);
+#endif
+
#ifdef __PASSES__
if (L->use_light_pass) {
if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)
- L->background += throughput * value;
+ L->background += contribution;
else if (state->bounce == 1)
- L->direct_emission += throughput * value;
+ L->direct_emission += contribution;
else
- L->indirect += throughput * value;
+ L->indirect += contribution;
}
else
#endif
{
- L->emission += throughput * value;
+ L->emission += contribution;
}
#ifdef __DENOISING_FEATURES__
@@ -587,8 +643,6 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg,
/* Light Passes are used */
#ifdef __PASSES__
float3 L_direct, L_indirect;
- float clamp_direct = kernel_data.integrator.sample_clamp_direct;
- float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
if (L->use_light_pass) {
path_radiance_sum_indirect(L);
@@ -622,44 +676,6 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg,
L->emission = make_float3(0.0f, 0.0f, 0.0f);
}
-
- /* Clamp direct and indirect samples */
-# ifdef __CLAMP_SAMPLE__
- else if (sum > clamp_direct || sum > clamp_indirect) {
- 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->direct_scatter *= scale;
- L->emission *= scale;
- L->background *= 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;
- L->indirect_scatter *= scale;
- }
-
- /* Sum again, after clamping */
- L_sum = L_direct + L_indirect;
- }
-# endif
}
/* No Light Passes */