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/integrator/shade_surface.h')
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h76
1 files changed, 55 insertions, 21 deletions
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index df9af6ca107..c5dd9fe27f4 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -6,6 +6,8 @@
#include "kernel/film/accumulate.h"
#include "kernel/film/passes.h"
+#include "kernel/integrator/mnee.h"
+
#include "kernel/integrator/path_state.h"
#include "kernel/integrator/shader_eval.h"
#include "kernel/integrator/subsurface.h"
@@ -92,6 +94,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
#ifdef __EMISSION__
/* Path tracing: sample point on light and evaluate light shader, then
* queue shadow ray to be traced. */
+template<uint node_feature_mask>
ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
IntegratorState state,
ccl_private ShaderData *sd,
@@ -124,34 +127,65 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
* integrate_surface_bounce, evaluate the BSDF, and only then evaluate
* the light shader. This could also move to its own kernel, for
* non-constant light sources. */
- ShaderDataTinyStorage emission_sd_storage;
+ ShaderDataCausticsStorage emission_sd_storage;
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
- if (is_zero(light_eval)) {
- return;
- }
-
- /* Evaluate BSDF. */
- const bool is_transmission = shader_bsdf_is_transmission(sd, ls.D);
+ Ray ray ccl_optional_struct_init;
BsdfEval bsdf_eval ccl_optional_struct_init;
- const float bsdf_pdf = shader_bsdf_eval(kg, sd, ls.D, is_transmission, &bsdf_eval, ls.shader);
- bsdf_eval_mul3(&bsdf_eval, light_eval / ls.pdf);
+ const bool is_transmission = shader_bsdf_is_transmission(sd, ls.D);
- if (ls.shader & SHADER_USE_MIS) {
- const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);
- bsdf_eval_mul(&bsdf_eval, mis_weight);
+# ifdef __MNEE__
+ bool skip_nee = false;
+ IF_KERNEL_NODES_FEATURE(RAYTRACE)
+ {
+ if (ls.lamp != LAMP_NONE) {
+ /* Is this a caustic light? */
+ const bool use_caustics = kernel_tex_fetch(__lights, ls.lamp).use_caustics;
+ if (use_caustics) {
+ /* Are we on a caustic caster? */
+ if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER))
+ return;
+
+ /* Are we on a caustic receiver? */
+ if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER))
+ skip_nee = kernel_path_mnee_sample(
+ kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
+ }
+ }
+ }
+ if (skip_nee) {
+ /* Create shadow ray after successful manifold walk:
+ * emission_sd contains the last interface intersection and
+ * the light sample ls has been updated */
+ light_sample_to_surface_shadow_ray(kg, emission_sd, &ls, &ray);
}
+ else
+# endif /* __MNEE__ */
+ {
+ const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
+ if (is_zero(light_eval)) {
+ return;
+ }
- /* Path termination. */
- const float terminate = path_state_rng_light_termination(kg, rng_state);
- if (light_sample_terminate(kg, &ls, &bsdf_eval, terminate)) {
- return;
+ /* Evaluate BSDF. */
+ const float bsdf_pdf = shader_bsdf_eval(kg, sd, ls.D, is_transmission, &bsdf_eval, ls.shader);
+ bsdf_eval_mul3(&bsdf_eval, light_eval / ls.pdf);
+
+ if (ls.shader & SHADER_USE_MIS) {
+ const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);
+ bsdf_eval_mul(&bsdf_eval, mis_weight);
+ }
+
+ /* Path termination. */
+ const float terminate = path_state_rng_light_termination(kg, rng_state);
+ if (light_sample_terminate(kg, &ls, &bsdf_eval, terminate)) {
+ return;
+ }
+
+ /* Create shadow ray. */
+ light_sample_to_surface_shadow_ray(kg, sd, &ls, &ray);
}
- /* Create shadow ray. */
- Ray ray ccl_optional_struct_init;
- light_sample_to_surface_shadow_ray(kg, sd, &ls, &ray);
const bool is_light = light_sample_is_light(&ls);
/* Branch off shadow kernel. */
@@ -501,7 +535,7 @@ ccl_device bool integrate_surface(KernelGlobals kg,
/* Direct light. */
PROFILING_EVENT(PROFILING_SHADE_SURFACE_DIRECT_LIGHT);
- integrate_surface_direct_light(kg, state, &sd, &rng_state);
+ integrate_surface_direct_light<node_feature_mask>(kg, state, &sd, &rng_state);
#if defined(__AO__)
/* Ambient occlusion pass. */