diff options
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/film/accumulate.h | 38 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/object.h | 20 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_background.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_light.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_surface.h | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_volume.h | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shadow_state_template.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/light/light.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/types.h | 13 |
9 files changed, 84 insertions, 17 deletions
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h index d6a385a4bff..e10acfd7eb5 100644 --- a/intern/cycles/kernel/film/accumulate.h +++ b/intern/cycles/kernel/film/accumulate.h @@ -320,12 +320,13 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, } /* Write background or emission to appropriate pass. */ -ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg, - ConstIntegratorState state, - float3 contribution, - ccl_global float *ccl_restrict - buffer, - const int pass) +ccl_device_inline void kernel_accum_emission_or_background_pass( + KernelGlobals kg, + ConstIntegratorState state, + float3 contribution, + ccl_global float *ccl_restrict buffer, + const int pass, + const int lightgroup = LIGHTGROUP_NONE) { if (!(kernel_data.film.light_pass_flag & PASS_ANY)) { return; @@ -347,6 +348,11 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg } # endif /* __DENOISING_FEATURES__ */ + if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { + kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); + } + if (!(path_flag & PATH_RAY_ANY_PASS)) { /* Directly visible, write to emission or background pass. */ pass_offset = pass; @@ -449,6 +455,13 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, return; } + /* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */ + const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1; + if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { + kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); + } + if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { int pass_offset = PASS_UNUSED; @@ -566,15 +579,20 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg, kernel_accum_combined_transparent_pass( kg, path_flag, sample, contribution, transparent, buffer); } - kernel_accum_emission_or_background_pass( - kg, state, contribution, buffer, kernel_data.film.pass_background); + kernel_accum_emission_or_background_pass(kg, + state, + contribution, + buffer, + kernel_data.film.pass_background, + kernel_data.background.lightgroup); } /* Write emission to render buffer. */ ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, const float3 L, - ccl_global float *ccl_restrict render_buffer) + ccl_global float *ccl_restrict render_buffer, + const int lightgroup = LIGHTGROUP_NONE) { float3 contribution = L; kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1); @@ -585,7 +603,7 @@ ccl_device_inline void kernel_accum_emission(KernelGlobals kg, kernel_accum_combined_pass(kg, path_flag, sample, contribution, buffer); kernel_accum_emission_or_background_pass( - kg, state, contribution, buffer, kernel_data.film.pass_emission); + kg, state, contribution, buffer, kernel_data.film.pass_emission, lightgroup); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/geom/object.h b/intern/cycles/kernel/geom/object.h index 86c57c84b47..3faab7fa905 100644 --- a/intern/cycles/kernel/geom/object.h +++ b/intern/cycles/kernel/geom/object.h @@ -283,6 +283,26 @@ ccl_device_inline float object_pass_id(KernelGlobals kg, int object) return kernel_tex_fetch(__objects, object).pass_id; } +/* Lightgroup of lamp */ + +ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp) +{ + if (lamp == LAMP_NONE) + return LIGHTGROUP_NONE; + + return kernel_tex_fetch(__lights, lamp).lightgroup; +} + +/* Lightgroup of object */ + +ccl_device_inline int object_lightgroup(KernelGlobals kg, int object) +{ + if (object == OBJECT_NONE) + return LIGHTGROUP_NONE; + + return kernel_tex_fetch(__objects, object).lightgroup; +} + /* Per lamp random number for shader variation */ ccl_device_inline float lamp_random_number(KernelGlobals kg, int lamp) diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h index 4fd41121466..62b3ce1c15c 100644 --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@ -186,7 +186,8 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg, /* Write to render buffer. */ const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_accum_emission(kg, state, throughput * light_eval, render_buffer); + kernel_accum_emission( + kg, state, throughput * light_eval, render_buffer, kernel_data.background.lightgroup); } } } diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h index 4a519a76ed0..be926c78439 100644 --- a/intern/cycles/kernel/integrator/shade_light.h +++ b/intern/cycles/kernel/integrator/shade_light.h @@ -78,7 +78,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg, /* Write to render buffer. */ const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_accum_emission(kg, state, throughput * light_eval, render_buffer); + kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group); } ccl_device void integrator_shade_light(KernelGlobals kg, diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index c5dd9fe27f4..a9bf3b5b432 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -87,7 +87,8 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, } const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_accum_emission(kg, state, throughput * L, render_buffer); + kernel_accum_emission( + kg, state, throughput * L, render_buffer, object_lightgroup(kg, sd->object)); } #endif /* __EMISSION__ */ @@ -258,6 +259,12 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, if (kernel_data.kernel_features & KERNEL_FEATURE_SHADOW_PASS) { INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = throughput; } + + /* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */ + INTEGRATOR_STATE_WRITE( + shadow_state, shadow_path, lightgroup) = (ls.type != LIGHT_BACKGROUND) ? + ls.group + 1 : + kernel_data.background.lightgroup + 1; } #endif diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index acda4b8e9d1..4a5015946aa 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -653,7 +653,8 @@ ccl_device_forceinline void volume_integrate_heterogeneous( /* Write accumulated emission. */ if (!is_zero(accum_emission)) { - kernel_accum_emission(kg, state, accum_emission, render_buffer); + kernel_accum_emission( + kg, state, accum_emission, render_buffer, object_lightgroup(kg, sd->object)); } # ifdef __DENOISING_FEATURES__ @@ -833,6 +834,12 @@ ccl_device_forceinline void integrate_volume_direct_light( INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = throughput; } + /* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */ + INTEGRATOR_STATE_WRITE( + shadow_state, shadow_path, lightgroup) = (ls->type != LIGHT_BACKGROUND) ? + ls->group + 1 : + kernel_data.background.lightgroup + 1; + integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state); } # endif diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h index 9308df53e46..eaee65ada40 100644 --- a/intern/cycles/kernel/integrator/shadow_state_template.h +++ b/intern/cycles/kernel/integrator/shadow_state_template.h @@ -38,6 +38,8 @@ KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_diffuse_weight, KERNEL_FEA KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) /* Number of intersections found by ray-tracing. */ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING) +/* Light group. */ +KERNEL_STRUCT_MEMBER(shadow_path, uint8_t, lightgroup, KERNEL_FEATURE_PATH_TRACING) KERNEL_STRUCT_END(shadow_path) /********************************** Shadow Ray *******************************/ diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index fb637008ca4..1df1615ed99 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -23,6 +23,7 @@ typedef struct LightSample { int prim; /* primitive id for triangle/curve lights */ int shader; /* shader id */ int lamp; /* lamp id */ + int group; /* lightgroup */ LightType type; /* type of light */ } LightSample; @@ -52,6 +53,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg, ls->lamp = lamp; ls->u = randu; ls->v = randv; + ls->group = lamp_lightgroup(kg, lamp); if (in_volume_segment && (type == LIGHT_DISTANT || type == LIGHT_BACKGROUND)) { /* Distant lights in a volume get a dummy sample, position will not actually @@ -413,6 +415,7 @@ ccl_device bool light_sample_from_distant_ray(KernelGlobals kg, ls->P = -ray_D; ls->Ng = -ray_D; ls->D = ray_D; + ls->group = lamp_lightgroup(kg, lamp); /* compute pdf */ float invarea = klight->distant.invarea; @@ -441,6 +444,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg, ls->t = isect->t; ls->P = ray_P + ray_D * ls->t; ls->D = ray_D; + ls->group = lamp_lightgroup(kg, lamp); if (type == LIGHT_SPOT) { const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]); @@ -706,6 +710,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg, ls->lamp = LAMP_NONE; ls->shader |= SHADER_USE_MIS; ls->type = LIGHT_TRIANGLE; + ls->group = object_lightgroup(kg, object); float distance_to_plane = fabsf(dot(N0, V[0] - P) / dot(N0, N0)); diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 00b5b007e11..9d9daaa0dda 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -46,6 +46,7 @@ CCL_NAMESPACE_BEGIN #define LAMP_NONE (~0) #define ID_NONE (0.0f) #define PASS_UNUSED (~0) +#define LIGHTGROUP_NONE (~0) #define INTEGRATOR_SHADOW_ISECT_SIZE_CPU 1024U #define INTEGRATOR_SHADOW_ISECT_SIZE_GPU 4U @@ -1108,6 +1109,7 @@ typedef struct KernelFilm { int pass_aov_color; int pass_aov_value; + int pass_lightgroup; /* XYZ to rendering color space transform. float4 instead of float3 to * ensure consistent padding/alignment across devices. */ @@ -1192,8 +1194,10 @@ typedef struct KernelBackground { int use_mis; + int lightgroup; + /* Padding */ - int pad1, pad2, pad3; + int pad1, pad2; } KernelBackground; static_assert_align(KernelBackground, 16); @@ -1372,9 +1376,12 @@ typedef struct KernelObject { float ao_distance; + int lightgroup; + uint visibility; int primitive_type; - int pad[2]; + + int pad1; } KernelObject; static_assert_align(KernelObject, 16); @@ -1427,7 +1434,7 @@ typedef struct KernelLight { float random; float strength[3]; int use_caustics; - float pad1; + int lightgroup; Transform tfm; Transform itfm; union { |