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:
authorThomas Dinges <blender@dingto.org>2014-03-10 01:19:27 +0400
committerThomas Dinges <blender@dingto.org>2014-03-10 01:20:01 +0400
commit99e20d7b8930479edfacae246a529e03b84264ae (patch)
tree9bffdd2a43d7948a864528f205eef4f3c86687b3 /intern/cycles
parent6fdbab43662d3f646f7d94bfaad83111f7d41830 (diff)
Cycles: Option to Sample all Lights in the Branched Path integrator for indirect samples
This adds a new option "Sample All Lights" to the Sampling panel in Cycles (Branched Path). When enabled, Cycles will sample all the lights in the scene for the indirect samples, instead of randomly picking one. This is already happening for direct samples, now you can optionally enable it for indirect. Example file and renders: Blend file: http://www.pasteall.org/blend/27411 Random: http://www.pasteall.org/pic/show.php?id=68033 All: http://www.pasteall.org/pic/show.php?id=68034 Sampling all lights is a bit slower, but there is less variance, so it should help in situations with many lights. Patch by myself with some tweaks by Brecht. Differential Revision: https://developer.blender.org/D391
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/addon/properties.py5
-rw-r--r--intern/cycles/blender/addon/ui.py2
-rw-r--r--intern/cycles/blender/blender_sync.cpp2
-rw-r--r--intern/cycles/kernel/kernel_path.h184
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/render/integrator.cpp4
-rw-r--r--intern/cycles/render/integrator.h1
7 files changed, 105 insertions, 96 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index e267ea48b73..875f9d36d63 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -252,6 +252,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
items=enum_use_layer_samples,
default='USE',
)
+ cls.sample_all_lights_indirect = BoolProperty(
+ name="Sample All Lights",
+ description="Sample all lights (for indirect samples), rather than randomly picking one",
+ default=False,
+ )
cls.no_caustics = BoolProperty(
name="No Caustics",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index a3138266b20..da334e208b7 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -133,6 +133,8 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
sub.label(text="AA Samples:")
sub.prop(cscene, "aa_samples", text="Render")
sub.prop(cscene, "preview_aa_samples", text="Preview")
+ sub.separator()
+ sub.prop(cscene, "sample_all_lights_indirect")
col = split.column()
sub = col.column(align=True)
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 1d507ed9b1d..202eff48d53 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -197,6 +197,8 @@ void BlenderSync::sync_integrator()
#endif
integrator->method = (Integrator::Method)get_enum(cscene, "progressive");
+
+ integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
int diffuse_samples = get_int(cscene, "diffuse_samples");
int glossy_samples = get_int(cscene, "glossy_samples");
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 635201471e1..000b241f544 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -133,6 +133,93 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__)
+ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, bool sample_all_lights)
+{
+ /* sample illumination from lights to find path contribution */
+ if(sd->flag & SD_BSDF_HAS_EVAL) {
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
+
+#ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+#endif
+
+ if(sample_all_lights) {
+ /* lamp sampling */
+ for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
+ float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
+ RNG lamp_rng = cmj_hash(*rng, i);
+
+ if(kernel_data.integrator.pdf_triangles != 0.0f)
+ num_samples_inv *= 0.5f;
+
+ for(int j = 0; j < num_samples; j++) {
+ float light_u, light_v;
+ path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+
+ /* mesh light sampling */
+ if(kernel_data.integrator.pdf_triangles != 0.0f) {
+ int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
+ float num_samples_inv = num_samples_adjust/num_samples;
+
+ if(kernel_data.integrator.num_all_lights)
+ num_samples_inv *= 0.5f;
+
+ for(int j = 0; j < num_samples; j++) {
+ float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT);
+ float light_u, light_v;
+ path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* only sample triangle lights */
+ if(kernel_data.integrator.num_all_lights)
+ light_t = 0.5f*light_t;
+
+ if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+ }
+ else {
+ float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* sample random light */
+ if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+}
+
ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer,
float3 throughput, int num_samples, PathState state, PathRadiance *L)
{
@@ -302,36 +389,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
#ifdef __EMISSION__
if(kernel_data.integrator.use_direct_light) {
- /* sample illumination from lights to find path contribution */
- if(sd.flag & SD_BSDF_HAS_EVAL) {
- float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
-#ifdef __MULTI_CLOSURE__
- float light_o = 0.0f;
-#else
- float light_o = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT_F);
-#endif
- float light_u, light_v;
- path_state_rng_2D(kg, rng, &state, PRNG_LIGHT_U, &light_u, &light_v);
-
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd.time;
-#endif
-
- /* sample random light */
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp);
- }
- }
- }
+ bool all = kernel_data.integrator.sample_all_lights_indirect;
+ kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all);
}
#endif
@@ -898,70 +957,7 @@ ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *
PathState *state, PathRadiance *L, ccl_global float *buffer)
{
#ifdef __EMISSION__
- /* sample illumination from lights to find path contribution */
- if(sd->flag & SD_BSDF_HAS_EVAL) {
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd->time;
-#endif
-
- /* lamp sampling */
- for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
- int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
- float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
- RNG lamp_rng = cmj_hash(*rng, i);
-
- if(kernel_data.integrator.pdf_triangles != 0.0f)
- num_samples_inv *= 0.5f;
-
- for(int j = 0; j < num_samples; j++) {
- float light_u, light_v;
- path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
- }
- }
- }
- }
-
- /* mesh light sampling */
- if(kernel_data.integrator.pdf_triangles != 0.0f) {
- int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
- float num_samples_inv = num_samples_adjust/num_samples;
-
- if(kernel_data.integrator.num_all_lights)
- num_samples_inv *= 0.5f;
-
- for(int j = 0; j < num_samples; j++) {
- float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT);
- float light_u, light_v;
- path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- /* only sample triangle lights */
- if(kernel_data.integrator.num_all_lights)
- light_t = 0.5f*light_t;
-
- if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
- }
- }
- }
- }
- }
+ kernel_branched_path_integrate_direct_lighting(kg, rng, sd, state, throughput, num_samples_adjust, L, true);
#endif
for(int i = 0; i< sd->num_closure; i++) {
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index fc3e2730141..bf79b0aa3bf 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -834,6 +834,7 @@ typedef struct KernelIntegrator {
int ao_samples;
int mesh_light_samples;
int subsurface_samples;
+ int sample_all_lights_indirect;
/* mis */
int use_lamp_mis;
@@ -847,7 +848,7 @@ typedef struct KernelIntegrator {
int volume_max_steps;
float volume_step_size;
int volume_samples;
- int pad1, pad2;
+ int pad1;
} KernelIntegrator;
typedef struct KernelBVH {
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index 5b26440594a..849157d9e91 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -130,6 +130,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->mesh_light_samples = mesh_light_samples;
kintegrator->subsurface_samples = subsurface_samples;
kintegrator->volume_samples = volume_samples;
+ kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
kintegrator->sampling_pattern = sampling_pattern;
@@ -197,7 +198,8 @@ bool Integrator::modified(const Integrator& integrator)
subsurface_samples == integrator.subsurface_samples &&
volume_samples == integrator.volume_samples &&
motion_blur == integrator.motion_blur &&
- sampling_pattern == integrator.sampling_pattern);
+ sampling_pattern == integrator.sampling_pattern &&
+ sample_all_lights_indirect == integrator.sample_all_lights_indirect);
}
void Integrator::tag_update(Scene *scene)
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 4a8240c3941..587968dc1e4 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -63,6 +63,7 @@ public:
int mesh_light_samples;
int subsurface_samples;
int volume_samples;
+ bool sample_all_lights_indirect;
enum Method {
BRANCHED_PATH = 0,