[Bf-blender-cvs] [05bdef7ce64] master: Fix T103094: Cycles ignores small suns in Nishita sky
Commit: 05bdef7ce64fe3125b95d72d80f1f4f60c2b1274 Author: Jeffrey Liu Date: Thu Jan 19 18:22:47 2023 -0600 Branches: master https://developer.blender.org/rB05bdef7ce64fe3125b95d72d80f1f4f60c2b1274 Fix T103094: Cycles ignores small suns in Nishita sky The background evaluation samples the sky discretely, so if the sun is too small, it can be missed in the evaluation. To solve this, the sun is ignored during the background evaluation and its contribution is computed separately. === M intern/cycles/kernel/bake/bake.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/integrator/shade_volume.h M intern/cycles/kernel/osl/shaders/node_sky_texture.osl M intern/cycles/kernel/svm/sky.h M intern/cycles/kernel/svm/svm.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/osl.cpp M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M release/scripts/addons === diff --git a/intern/cycles/kernel/bake/bake.h b/intern/cycles/kernel/bake/bake.h index 384ca9168f0..899aa783289 100644 --- a/intern/cycles/kernel/bake/bake.h +++ b/intern/cycles/kernel/bake/bake.h @@ -63,8 +63,9 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg, shader_setup_from_background(kg, , ray_P, ray_D, ray_time); /* Evaluate shader. - * This is being evaluated for all BSDFs, so path flag does not contain a specific type. */ - const uint32_t path_flag = PATH_RAY_EMISSION; + * This is being evaluated for all BSDFs, so path flag does not contain a specific type. + * However, we want to flag the ray visibility to ignore the sun in the background map. */ + const uint32_t path_flag = PATH_RAY_EMISSION | PATH_RAY_IMPORTANCE_BAKE; surface_shader_eval( kg, INTEGRATOR_STATE_NULL, , NULL, path_flag); diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 21a6f2d4e36..09433caa063 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -264,7 +264,6 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, /* Copy state from main path to shadow path. */ uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); - shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; const Spectrum unlit_throughput = INTEGRATOR_STATE(state, path, throughput); const Spectrum throughput = unlit_throughput * bsdf_eval_sum(_eval); diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 75962ce5499..98dc5603a78 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -838,7 +838,6 @@ ccl_device_forceinline void integrate_volume_direct_light( const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce); const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce); uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); - shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; const Spectrum throughput_phase = throughput * bsdf_eval_sum(_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { diff --git a/intern/cycles/kernel/osl/shaders/node_sky_texture.osl b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl index 1373db04a31..763f73a35d7 100644 --- a/intern/cycles/kernel/osl/shaders/node_sky_texture.osl +++ b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl @@ -135,8 +135,9 @@ color sky_radiance_nishita(vector dir, float nishita_data[10], string filename) float half_angular = angular_diameter / 2.0; float dir_elevation = M_PI_2 - direction[0]; -/* if ray inside sun disc render it, otherwise render sky */ -if (sun_dir_angle < half_angular && sun_disc == 1) { +/* if ray inside sun disc render it, otherwise render sky. + * alternatively, ignore the sun if we're evaluating the background texture. */ +if (sun_dir_angle < half_angular && sun_disc == 1 && raytype("importance_bake") != 1) { /* get 2 pixels data */ color pixel_bottom = color(nishita_data[0], nishita_data[1], nishita_data[2]); color pixel_top = color(nishita_data[3], nishita_data[4], nishita_data[5]); diff --git a/intern/cycles/kernel/svm/sky.h b/intern/cycles/kernel/svm/sky.h index 1638e783a69..92b292d660d 100644 --- a/intern/cycles/kernel/svm/sky.h +++ b/intern/cycles/kernel/svm/sky.h @@ -118,6 +118,7 @@ ccl_device float3 geographical_to_direction(float lat, float lon) ccl_device float3 sky_radiance_nishita(KernelGlobals kg, float3 dir, + uint32_t path_flag,
[Bf-blender-cvs] [794de3a222d] soc-2022-many-lights-sampling: Fix: light tree pdf uses wrong index
Commit: 794de3a222d9bb1eb77b894a808f767f777512d2 Author: Jeffrey Liu Date: Sun Sep 4 02:34:34 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB794de3a222d9bb1eb77b894a808f767f777512d2 Fix: light tree pdf uses wrong index === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index b265530e5e8..0e41f83bd05 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -513,8 +513,9 @@ ccl_device float light_tree_pdf(KernelGlobals kg, kernel_data_fetch(light_to_tree, ~prim); ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, emitter); + const int target_leaf = kemitter->parent_index; ccl_global const KernelLightTreeNode *kleaf = _data_fetch(light_tree_nodes, - kemitter->parent_index); + target_leaf); /* We generate a random number to use for selecting a light. */ RNGState rng_state; @@ -551,7 +552,7 @@ ccl_device float light_tree_pdf(KernelGlobals kg, /* If we're at the leaf node containing the light we need, * then we iterate through the lights to find the target emitter. * Otherwise, we randomly select one. */ - if (index == emitter) { + if (index == target_leaf) { light_tree_pdf = pdf; float target_emitter_importance = 0.0f; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5c9d2685546] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 5c9d2685546800b9402ca23ee8746745fe87e117 Author: Jeffrey Liu Date: Sun Sep 4 02:35:11 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5c9d2685546800b9402ca23ee8746745fe87e117 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8d4fbfda26e] soc-2022-many-lights-sampling: Fix: resolve light tree compilation errors
Commit: 8d4fbfda26e74ea9c89869174f08819401a676fe Author: Jeffrey Liu Date: Sat Sep 3 18:37:55 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB8d4fbfda26e74ea9c89869174f08819401a676fe Fix: resolve light tree compilation errors === M intern/cycles/kernel/integrator/shade_background.h M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h index 041a8df8e9d..2e0bbc4899d 100644 --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@ -121,7 +121,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg, /* multiple importance sampling, get background light pdf for ray * direction, and compute weight with respect to BSDF pdf */ - const float pdf = background_light_pdf(kg, ray_P, ray_D); + float pdf = background_light_pdf(kg, ray_P, ray_D); if (kernel_data.integrator.use_light_tree) { const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); pdf *= distant_lights_pdf(kg, ray_P, N, kernel_data.background.light_index); diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index efe3a746b6d..b265530e5e8 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -519,7 +519,8 @@ ccl_device float light_tree_pdf(KernelGlobals kg, /* We generate a random number to use for selecting a light. */ RNGState rng_state; path_state_rng_load(state, _state); - float randu = path_state_rng_1D_hash(kg, _state, 0x6a21694c); + /* to-do: is this the correct macro to use? */ + float randu = path_state_rng_1D(kg, _state, PRNG_LIGHT); /* We traverse to the leaf node and * find the probability of selecting the target light. */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [0484d5ca5b1] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 0484d5ca5b17cece7f4cd55156a128c13de32bb5 Author: Jeffrey Liu Date: Sat Sep 3 17:10:34 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB0484d5ca5b17cece7f4cd55156a128c13de32bb5 Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc intern/cycles/blender/sync.cpp index 3e46e668d3a,fe16f19556e..02889c9c6a0 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@@ -342,15 -342,8 +342,15 @@@ void BlenderSync::sync_integrator(BL::V integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold")); + integrator->set_use_light_tree(get_boolean(cscene, "use_light_tree")); + integrator->set_splitting_threshold(get_float(cscene, "splitting_threshold")); + + if (integrator->use_light_tree_is_modified()) { +scene->light_manager->tag_update(scene, LightManager::UPDATE_ALL); + } + SamplingPattern sampling_pattern = (SamplingPattern)get_enum( - cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); + cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_PMJ); integrator->set_sampling_pattern(sampling_pattern); int samples = 1; diff --cc intern/cycles/kernel/integrator/shade_background.h index c5beda0a5ec,30ce0999258..041a8df8e9d --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@@ -3,10 -3,11 +3,12 @@@ #pragma once - #include "kernel/film/accumulate.h" - #include "kernel/integrator/shader_eval.h" + #include "kernel/film/light_passes.h" + + #include "kernel/integrator/surface_shader.h" + #include "kernel/light/light.h" +#include "kernel/light/light_tree.h" #include "kernel/light/sample.h" CCL_NAMESPACE_BEGIN @@@ -122,13 -98,33 +99,37 @@@ ccl_device_inline void integrate_backgr #endif /* __MNEE__ */ /* Evaluate background shader. */ - Spectrum L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) : -zero_spectrum(); + Spectrum L = zero_spectrum(); + + if (eval_background) { + L = integrator_eval_background_shader(kg, state, render_buffer); + + /* When using the ao bounces approximation, adjust background + * shader intensity with ao factor. */ + if (path_state_ao_bounce(kg, state)) { + L *= kernel_data.integrator.ao_bounces_factor; + } - /* When using the ao bounces approximation, adjust background -* shader intensity with ao factor. */ - if (path_state_ao_bounce(kg, state)) { - L *= kernel_data.integrator.ao_bounces_factor; + /* Background MIS weights. */ + float mis_weight = 1.0f; + /* Check if background light exists or if we should skip pdf. */ + if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_MIS_SKIP) && + kernel_data.background.use_mis) { + const float3 ray_P = INTEGRATOR_STATE(state, ray, P); + const float3 ray_D = INTEGRATOR_STATE(state, ray, D); + const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); + + /* multiple importance sampling, get background light pdf for ray +* direction, and compute weight with respect to BSDF pdf */ + const float pdf = background_light_pdf(kg, ray_P, ray_D); ++ if (kernel_data.integrator.use_light_tree) { ++const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); ++pdf *= distant_lights_pdf(kg, ray_P, N, kernel_data.background.light_index); ++ } + mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf); + } + + L *= mis_weight; } /* Write to render buffer. */ @@@ -184,13 -181,7 +186,12 @@@ ccl_device_inline void integrate_distan /* multiple importance sampling, get regular light pdf, * and compute weight with respect to BSDF pdf */ const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); -mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); +if (kernel_data.integrator.use_light_tree) { + const float3 ray_P = INTEGRATOR_STATE(state, ray, P); + const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); + ls.pdf *= distant_lights_pdf(kg, ray_P, N, lamp); +} +const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); - light_eval *= mis_weight; } /* Write to render buffer. */ diff --cc intern/cycles/kernel/integrator/shade_surface.h index 0b32680c017,c19f56a9b70..62eaf6b3882 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integra
[Bf-blender-cvs] [5f105939257] soc-2022-many-lights-sampling: Cycles: limit light tree traversal to 8 splits
Commit: 5f1059392575593169a57a0d193ac384a6a11782 Author: Jeffrey Liu Date: Sat Sep 3 16:37:17 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5f1059392575593169a57a0d193ac384a6a11782 Cycles: limit light tree traversal to 8 splits === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 55b0b43d1db..efe3a746b6d 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -287,6 +287,9 @@ ccl_device bool light_tree_sample(KernelGlobals kg, stack[0] = 0; pdfs[0] = 1.0f; + /* For now, we arbitrarily limit splitting to 8 so that it doesn't continuously split. */ + int split_count = 0; + /* First traverse the light tree until a leaf node is reached. * Also keep track of the probability of traversing to a given node, * so that we can scale our PDF accordingly later. */ @@ -337,12 +340,14 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const int left_index = index + 1; const int right_index = knode->child_index; if (light_tree_should_split(kg, P, knode) && +split_count < 8 && stack_index < stack_size - 1) { stack[stack_index] = left_index; pdfs[stack_index] = pdf; stack[stack_index + 1] = right_index; pdfs[stack_index + 1] = pdf; stack_index++; + split_count++; continue; } @@ -525,6 +530,8 @@ ccl_device float light_tree_pdf(KernelGlobals kg, stack[0] = 0; pdfs[0] = 1.0f; + int split_count = 0; + float light_tree_pdf = 0.0f; float light_leaf_pdf = 0.0f; float total_weight = 0.0f; @@ -591,12 +598,15 @@ ccl_device float light_tree_pdf(KernelGlobals kg, * We adaptively split if the variance is high enough. */ const int left_index = index + 1; const int right_index = knode->child_index; -if (light_tree_should_split(kg, P, knode) && stack_index < stack_size - 1) { +if (light_tree_should_split(kg, P, knode) && +split_count < 8 && +stack_index < stack_size - 1) { stack[stack_index] = left_index; pdfs[stack_index] = pdf; stack[stack_index + 1] = right_index; pdfs[stack_index + 1] = pdf; stack_index++; + split_count++; continue; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [38ea294d013] soc-2022-many-lights-sampling: Cleanup: remove redundant or outdated light tree comments
Commit: 38ea294d01390d18ac30dd69c117ca5502fc985e Author: Jeffrey Liu Date: Thu Aug 25 15:47:41 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB38ea294d01390d18ac30dd69c117ca5502fc985e Cleanup: remove redundant or outdated light tree comments === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 0cdc5b58e8f..55b0b43d1db 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -12,7 +12,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, const float3 P, const float3 point_to_centroid) { - /* Want to iterate through all 8 possible points of the bounding box. */ + /* Iterate through all 8 possible points of the bounding box. */ float theta_u = 0; float3 corners[8]; corners[0] = bbox_min; @@ -32,8 +32,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, } /* This is the general function for calculating the importance of either a cluster or an emitter. - * Both of the specialized functions obtain the necessary data before calling this function. - * to-do: find a better way to handle this? or rename it to be more clear? */ + * Both of the specialized functions obtain the necessary data before calling this function. */ ccl_device float light_tree_node_importance(const float3 P, const float3 N, const float3 bbox_min, @@ -60,7 +59,6 @@ ccl_device float light_tree_node_importance(const float3 P, } const float theta_u = light_tree_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid); - /* to-do: compare this with directly using fmaxf and cosf. */ /* Avoid using cosine until needed. */ const float theta_prime = fmaxf(theta - theta_o - theta_u, 0.0f); if (theta_prime >= theta_e) { @@ -75,7 +73,6 @@ ccl_device float light_tree_node_importance(const float3 P, /* to-do: find a good approximation for this value. */ const float f_a = 1.0f; - float importance = f_a * cos_theta_i_prime * energy / distance_squared * cos_theta_prime; return importance; } @@ -97,9 +94,9 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, const ccl_global KernelLight *klight = _data_fetch(lights, lamp); float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); +/* We use a special calculation to check if a light is + * within the bounds of a spot or area light. */ if (klight->type == LIGHT_SPOT) { - /* to-do: since spot light importance sampling isn't the best, - * we have a special case to check that the point is inside the cone. */ const float radius = klight->spot.radius; const float cos_theta = klight->spot.spot_angle; const float theta = fast_acosf(cos_theta); @@ -118,7 +115,6 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, } } else if (klight->type == LIGHT_AREA) { - /* area light */ float3 axisu = make_float3( klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]); float3 axisv = make_float3( @@ -152,7 +148,6 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, emitter_index); - /* Convert the data from the struct into float3 for calculations. */ const float3 bbox_min = make_float3(kemitter->bounding_box_min[0], kemitter->bounding_box_min[1], kemitter->bounding_box_min[2]); @@ -167,8 +162,6 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, P, N, bbox_min, bbox_max, bcone_axis, kemitter->theta_o, kemitter->theta_e, kemitter->energy); } -/* to-do: this is using a lot of the same calculations as the cluster importance, - * so it may be better to compute these once and then hold on to it somewhere. */ ccl_device bool light_tree_should_split(KernelGlobals kg, const float3 P, const ccl_global KernelLightTreeNode *knode) @@ -214,7 +207,6 @@ ccl_device float light_tree_cluster_importance(KernelGlobals kg, const float3 N, const ccl_global KernelLightTreeNod
[Bf-blender-cvs] [4b0373ce8fa] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 4b0373ce8faeb5282380651008356dd858609504 Author: Jeffrey Liu Date: Thu Aug 25 15:48:04 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB4b0373ce8faeb5282380651008356dd858609504 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [27da23de710] soc-2022-many-lights-sampling: Fix: support negative power in light tree
Commit: 27da23de710b5b8132836c79113cd5f19d3557d4 Author: Jeffrey Liu Date: Tue Aug 23 15:26:36 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB27da23de710b5b8132836c79113cd5f19d3557d4 Fix: support negative power in light tree === M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index ecbf6bcb8cf..5ef5a4ad4ab 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -62,10 +62,6 @@ OrientationBounds merge(const OrientationBounds& cone_a, } } -/* to-do: right now, this is assuming that the primitive is a point light. - * The plan is to progressively add support for more primitives. - * Some of the logic is different from the past GSoC work, so - * will have to see which logic is more correct. */ BoundBox LightTreePrimitive::calculate_bbox(Scene *scene) const { BoundBox bbox = BoundBox::empty; @@ -229,7 +225,7 @@ float LightTreePrimitive::calculate_energy(Scene *scene) const strength = lamp->get_strength(); } - return scene->shader_manager->linear_rgb_to_gray(strength); + return fabsf(scene->shader_manager->linear_rgb_to_gray(strength)); } void LightTreeBuildNode::init_leaf( ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [c8315dcedea] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: c8315dcedea8938cabb7fb94d3d3fe5cca050f85 Author: Jeffrey Liu Date: Tue Aug 23 15:27:46 2022 -0500 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBc8315dcedea8938cabb7fb94d3d3fe5cca050f85 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [a75eccd8a92] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: a75eccd8a9274e3d97ada18da333c28d50eaca0e Author: Jeffrey Liu Date: Thu Aug 18 16:09:50 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBa75eccd8a9274e3d97ada18da333c28d50eaca0e Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [a7cd05d1502] soc-2022-many-lights-sampling: Cycles: use bit-trail for light tree pdf
Commit: a7cd05d15028dc71d341bf21ca6b49dcf3b9e784 Author: Jeffrey Liu Date: Mon Aug 15 17:50:47 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBa7cd05d15028dc71d341bf21ca6b49dcf3b9e784 Cycles: use bit-trail for light tree pdf === M intern/cycles/kernel/integrator/shade_light.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h index 697b9d13ca8..0857463ba53 100644 --- a/intern/cycles/kernel/integrator/shade_light.h +++ b/intern/cycles/kernel/integrator/shade_light.h @@ -63,7 +63,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg, const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); if (kernel_data.integrator.use_light_tree) { const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); - ls.pdf *= light_tree_pdf(kg, ray_P, N, ~ls.lamp); + ls.pdf *= light_tree_pdf(kg, state, ray_P, N, ~ls.lamp); } const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); light_eval *= mis_weight; diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index e9a27924969..0b32680c017 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -133,7 +133,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object); uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object); - pdf *= light_tree_pdf(kg, ray_P, N, sd->prim - prim_offset + lookup_offset); + pdf *= light_tree_pdf(kg, state, ray_P, N, sd->prim - prim_offset + lookup_offset); } float mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf); L *= mis_weight; diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index c15e6ebed37..0cdc5b58e8f 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -82,44 +82,20 @@ ccl_device float light_tree_node_importance(const float3 P, /* This is uniformly sampling the reservoir for now. */ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, - const float randu, - const float randv, - const float time, const float3 P, const float3 N, - const int bounce, - const uint32_t path_flag, int emitter_index) { - LightSample ls ccl_optional_struct_init; ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, emitter_index); - bool sampled = true; const int prim = kemitter->prim_id; - if (prim >= 0) { -/* Mesh light. */ -const int object = kemitter->mesh_light.object_id; - -/* Exclude synthetic meshes from shadow catcher pass. */ -if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && -!(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { - return 0.0f; -} - -const int shader_flag = kemitter->mesh_light.shader_flag; -triangle_light_sample(kg, prim, object, randu, randv, time, , P); -ls.shader |= shader_flag; -sampled = ls.pdf > 0.0f; - } - else { + /* Triangles are handled normally for now. */ + if (prim < 0) { const int lamp = -prim - 1; -if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - return 0.0f; -} - const ccl_global KernelLight *klight = _data_fetch(lights, lamp); +float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); if (klight->type == LIGHT_SPOT) { /* to-do: since spot light importance sampling isn't the best, @@ -141,14 +117,28 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, return 0.0f; } } -else { - sampled = light_sample(kg, lamp, randu, randv, P, path_flag, ); -} - } +else if (klight->type == LIGHT_AREA
[Bf-blender-cvs] [8414a4b36e5] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 8414a4b36e5a6b65776114e22bf0dcce31509f6d Author: Jeffrey Liu Date: Mon Aug 15 17:51:34 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB8414a4b36e5a6b65776114e22bf0dcce31509f6d Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [829b85b5fe3] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 829b85b5fe3581c562512918f02ec6834281c5a4 Author: Jeffrey Liu Date: Mon Aug 15 09:28:04 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB829b85b5fe3581c562512918f02ec6834281c5a4 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [96ee89e727f] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 96ee89e727f108968d59089d59bbc7a27480249d Author: Jeffrey Liu Date: Fri Aug 5 00:08:38 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB96ee89e727f108968d59089d59bbc7a27480249d Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [702a2d075e1] soc-2022-many-lights-sampling: Fix: light tree has artifacts with many lights
Commit: 702a2d075e141f6c5dfe6ea6a4e29a6a6e8c8d7a Author: Jeffrey Liu Date: Fri Aug 5 00:06:19 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB702a2d075e141f6c5dfe6ea6a4e29a6a6e8c8d7a Fix: light tree has artifacts with many lights This fix resolves artifacts when there are many lights. This is because it was sampling lights when the total importance was 0. === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index d44ed34cb15..c15e6ebed37 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -372,6 +372,12 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const float left_importance = light_tree_cluster_importance(kg, P, N, left); const float right_importance = light_tree_cluster_importance(kg, P, N, right); +const float total_importance = left_importance + right_importance; + +if (total_importance == 0.0f) { + stack_index--; + continue; +} float left_probability = left_importance / (left_importance + right_importance); if (*randu < left_probability) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [357ca8f128b] soc-2022-many-lights-sampling: Fix: light tree handles spotlights poorly
Commit: 357ca8f128b29542138ea818e2c7ceba28efe7cf Author: Jeffrey Liu Date: Thu Aug 4 13:47:54 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB357ca8f128b29542138ea818e2c7ceba28efe7cf Fix: light tree handles spotlights poorly This fix has a special case for spotlights, which will check if the point falls within the spotlight or not. === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index decf7db8fe8..d44ed34cb15 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -119,7 +119,31 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, return 0.0f; } -sampled = light_sample(kg, lamp, randu, randv, P, path_flag, ); +const ccl_global KernelLight *klight = _data_fetch(lights, lamp); + +if (klight->type == LIGHT_SPOT) { + /* to-do: since spot light importance sampling isn't the best, + * we have a special case to check that the point is inside the cone. */ + const float radius = klight->spot.radius; + const float cos_theta = klight->spot.spot_angle; + const float theta = fast_acosf(cos_theta); + const float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); + const float3 light_dir = make_float3( + klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]); + + const float h1 = radius * fast_sinf(theta); + const float d1 = radius * cos_theta; + const float h2 = d1 / fast_tanf(theta); + + const float3 apex = light_P - (h1 + h2) * light_dir; + const float3 apex_to_point = normalize(P - apex); + if (dot(apex_to_point, light_dir) < cos_theta) { +return 0.0f; + } +} +else { + sampled = light_sample(kg, lamp, randu, randv, P, path_flag, ); +} } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [fc82cb14167] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: fc82cb14167d1ef7397450f234802482bfaf9d65 Author: Jeffrey Liu Date: Thu Aug 4 13:48:50 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBfc82cb14167d1ef7397450f234802482bfaf9d65 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [605fb8571ea] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 605fb8571eaa3b316648ee1ae64d232aae36ddff Author: Jeffrey Liu Date: Thu Aug 4 10:29:41 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB605fb8571eaa3b316648ee1ae64d232aae36ddff Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f1cb3ebbe64] soc-2022-many-lights-sampling: Cycles: use light sample for weighting heuristic
Commit: f1cb3ebbe6465c86536dc4ecfc7e79ceb19b3112 Author: Jeffrey Liu Date: Tue Aug 2 23:10:35 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf1cb3ebbe6465c86536dc4ecfc7e79ceb19b3112 Cycles: use light sample for weighting heuristic === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 8e84d5a6fdb..decf7db8fe8 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -82,10 +82,51 @@ ccl_device float light_tree_node_importance(const float3 P, /* This is uniformly sampling the reservoir for now. */ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, + const float randu, + const float randv, + const float time, const float3 P, const float3 N, + const int bounce, + const uint32_t path_flag, int emitter_index) { + LightSample ls ccl_optional_struct_init; + ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, + emitter_index); + bool sampled = true; + const int prim = kemitter->prim_id; + if (prim >= 0) { +/* Mesh light. */ +const int object = kemitter->mesh_light.object_id; + +/* Exclude synthetic meshes from shadow catcher pass. */ +if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && +!(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { + return 0.0f; +} + +const int shader_flag = kemitter->mesh_light.shader_flag; +triangle_light_sample(kg, prim, object, randu, randv, time, , P); +ls.shader |= shader_flag; + +sampled = ls.pdf > 0.0f; + } + else { +const int lamp = -prim - 1; + +if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { + return 0.0f; +} + +sampled = light_sample(kg, lamp, randu, randv, P, path_flag, ); + } + + + if (sampled == 0.0f) { +return 0.0f; + } + return 1.0f; } @@ -114,10 +155,18 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, /* to-do: this is using a lot of the same calculations as the cluster importance, * so it may be better to compute these once and then hold on to it somewhere. */ -ccl_device float light_tree_should_split(KernelGlobals kg, +ccl_device bool light_tree_should_split(KernelGlobals kg, const float3 P, const ccl_global KernelLightTreeNode *knode) { + const float splitting_threshold = kernel_data.integrator.splitting_threshold; + if (splitting_threshold == 0.0f) { +return false; + } + else if (splitting_threshold == 1.0f) { +return true; + } + const float3 bbox_min = make_float3( knode->bounding_box_min[0], knode->bounding_box_min[1], knode->bounding_box_min[2]); const float3 bbox_max = make_float3( @@ -143,7 +192,7 @@ ccl_device float light_tree_should_split(KernelGlobals kg, const float total_variance = V_e * V_g + V_e * E_g * E_g + E_e * E_e * V_g; const float normalized_variance = sqrt(sqrt(1.0f / (1.0f + sqrt(total_variance; - return (normalized_variance < kernel_data.integrator.splitting_threshold); + return (normalized_variance < splitting_threshold); } ccl_device float light_tree_cluster_importance(KernelGlobals kg, @@ -253,7 +302,8 @@ ccl_device bool light_tree_sample(KernelGlobals kg, continue; } - const float light_weight = light_tree_emitter_reservoir_weight(kg, P, N, selected_light); + const float light_weight = light_tree_emitter_reservoir_weight( + kg, time, *randu, randv, P, N, bounce, path_flag, selected_light); if (light_weight == 0.0f) { stack_index--; continue; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [749ea10e057] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 749ea10e05722cf6bd0b2bfb56e0c4b890b06fc4 Author: Jeffrey Liu Date: Tue Aug 2 23:11:07 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB749ea10e05722cf6bd0b2bfb56e0c4b890b06fc4 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ef174481c89] soc-2022-many-lights-sampling: Fix: light tree splitting threshold description error
Commit: ef174481c89ffc1169ae809850ec028cf8468c99 Author: Jeffrey Liu Date: Mon Aug 1 11:44:50 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBef174481c89ffc1169ae809850ec028cf8468c99 Fix: light tree splitting threshold description error === M intern/cycles/blender/addon/properties.py === diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 4816a2a6854..09a1dfe8e7b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -481,7 +481,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): splitting_threshold: FloatProperty( name="Splitting", description="Amount of light tree emitters to consider at a time, from one light at 0.0, " -"to adaptively more lights as needed, to all branches at 1.0" +"to adaptively more lights as needed, to all branches at 1.0", min=0.0, max=1.0, default=0.85, ) ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [bdc1dbd54d1] soc-2022-many-lights-sampling: Cycles: update splitting threshold description
Commit: bdc1dbd54d10b0be301eb22b6882b779bbb7038a Author: Jeffrey Liu Date: Sun Jul 31 16:12:18 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBbdc1dbd54d10b0be301eb22b6882b779bbb7038a Cycles: update splitting threshold description === M intern/cycles/blender/addon/properties.py === diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 670bbcd3988..4816a2a6854 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -480,7 +480,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): splitting_threshold: FloatProperty( name="Splitting", -description="Amount of lights to sample at a time, from one light at 0.0, to adaptively more lights as needed, to all lights at 1.0", +description="Amount of light tree emitters to consider at a time, from one light at 0.0, " +"to adaptively more lights as needed, to all branches at 1.0" min=0.0, max=1.0, default=0.85, ) ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5f4597632b8] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 5f4597632b8abf7b69c2f860ba92db1c71c927bd Author: Jeffrey Liu Date: Sun Jul 31 16:12:50 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5f4597632b8abf7b69c2f860ba92db1c71c927bd Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ca7e09f7fc2] soc-2022-many-lights-sampling: Cycles: light tree adaptive splitting with weighted reservoir
Commit: ca7e09f7fc2d2beb4259aef9b48a1d368a72d249 Author: Jeffrey Liu Date: Sat Jul 30 18:12:12 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBca7e09f7fc2d2beb4259aef9b48a1d368a72d249 Cycles: light tree adaptive splitting with weighted reservoir This doesn't change anything on the user side, but finally takes the splitting threshold into consideration. Good for edge cases where the importance heuristic is not accurate enough. Currently implemented using a stack size of 32, and using the weighted reservoir sampling technique. Right now, weights are uniform from adaptive splitting, but plans are to actually take an actual light sample for better weighting. === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 4c39c97060e..8e84d5a6fdb 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -4,6 +4,9 @@ CCL_NAMESPACE_BEGIN +/* to-do: this seems like a relative expensive computation, and we can make it a lot cheaper + * by using a bounding sphere instead of a bounding box. This will be more inaccurate, but it + * might be fine when used along with the adaptive splitting. */ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, const float3 bbox_max, const float3 P, @@ -77,6 +80,15 @@ ccl_device float light_tree_node_importance(const float3 P, return importance; } +/* This is uniformly sampling the reservoir for now. */ +ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg, + const float3 P, + const float3 N, + int emitter_index) +{ + return 1.0f; +} + ccl_device float light_tree_emitter_importance(KernelGlobals kg, const float3 P, const float3 N, @@ -100,6 +112,40 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, P, N, bbox_min, bbox_max, bcone_axis, kemitter->theta_o, kemitter->theta_e, kemitter->energy); } +/* to-do: this is using a lot of the same calculations as the cluster importance, + * so it may be better to compute these once and then hold on to it somewhere. */ +ccl_device float light_tree_should_split(KernelGlobals kg, + const float3 P, + const ccl_global KernelLightTreeNode *knode) +{ + const float3 bbox_min = make_float3( + knode->bounding_box_min[0], knode->bounding_box_min[1], knode->bounding_box_min[2]); + const float3 bbox_max = make_float3( + knode->bounding_box_max[0], knode->bounding_box_max[1], knode->bounding_box_max[2]); + const float3 centroid = 0.5f * bbox_min + 0.5f * bbox_max; + + const float radius = len(bbox_max - centroid); + const float distance = len(P - centroid); + + if (distance < radius) { +return true; + } + + const float a = distance - radius; + const float b = distance + radius; + + const float E_g = 1.0f / (a * b); + const float E_e = knode->energy; + + /* This is a simplified version of the expression given in the paper. */ + const float V_g = (b - a) * (b - a) * E_g * E_g * E_g / 3.0f; + const float V_e = knode->energy_variance; + + const float total_variance = V_e * V_g + V_e * E_g * E_g + E_e * E_e * V_g; + const float normalized_variance = sqrt(sqrt(1.0f / (1.0f + sqrt(total_variance; + return (normalized_variance < kernel_data.integrator.splitting_threshold); +} + ccl_device float light_tree_cluster_importance(KernelGlobals kg, const float3 P, const float3 N, @@ -117,10 +163,51 @@ ccl_device float light_tree_cluster_importance(KernelGlobals kg, P, N, bbox_min, bbox_max, bcone_axis, knode->theta_o, knode->theta_e, knode->energy); } +ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, + float *randu, + const float3 P, + const float3 N, + const ccl_global KernelLightTreeNode *knode, + float *pdf_factor) +{ + /* Right now, sampling is done by incrementing the CDF by the PDF. + * However, we first need to calculate the total importance so that we can normalize the CDF. */ + float total_emitter_importance =
[Bf-blender-cvs] [015dbb494bd] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 015dbb494bd2b1d52dd7ff3d2ea035db3de72331 Author: Jeffrey Liu Date: Sat Jul 30 18:15:11 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB015dbb494bd2b1d52dd7ff3d2ea035db3de72331 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f9897d74624] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: f9897d74624220f6a838902cb2e87eb099880a27 Author: Jeffrey Liu Date: Sat Jul 23 13:06:31 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf9897d74624220f6a838902cb2e87eb099880a27 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [525cda0972a] soc-2022-many-lights-sampling: Fix: many lights oversamples subdivided surfaces
Commit: 525cda0972ac2ebe97d7ec46d74805687225a707 Author: Jeffrey Liu Date: Sat Jul 23 12:45:02 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB525cda0972ac2ebe97d7ec46d74805687225a707 Fix: many lights oversamples subdivided surfaces This issue is resolved by accounting for area in the energy calculation. This way subdivided surfaces will have the same total energy as a regular surface. === M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 2db19912f50..e05b1ca029f 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -204,20 +204,22 @@ float LightTreePrimitive::calculate_energy(Scene *scene) const strength = make_float3(1.0f); } -const Transform = object->get_tfm(); -float3 p[3] = {mesh->get_verts()[triangle.v[0]], + float3 p[3] = {mesh->get_verts()[triangle.v[0]], mesh->get_verts()[triangle.v[1]], mesh->get_verts()[triangle.v[2]]}; -for (int i = 0; i < 3; i++) { - p[i] = transform_point(, p[i]); +/* instanced mesh lights have not applied their transform at this point. + * in this case, these points have to be transformed to get the proper + * spatial bound. */ +if (!mesh->transform_applied) { + const Transform = object->get_tfm(); + for (int i = 0; i < 3; i++) { +p[i] = transform_point(, p[i]); + } } -// float area = triangle_area(p[0], p[1], p[2]); - -/* to-do: Past GSoC work also multiplies this by 4, but not sure why. Further investigation - * required. */ -// strength *= area * 4; +float area = triangle_area(p[0], p[1], p[2]); +strength *= area; } else { Light *lamp = scene->lights[lamp_id]; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [9a9873acc7c] soc-2022-many-lights-sampling: Fix: many lights oversamples area light outside of spread
Commit: 9a9873acc7c550554cd3f621ca613a60551238d7 Author: Jeffrey Liu Date: Sat Jul 23 13:05:11 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB9a9873acc7c550554cd3f621ca613a60551238d7 Fix: many lights oversamples area light outside of spread This issue was caused by the light tree construction assuming the emission profile of the area light would be equal to a constant value. This is resolved by setting it equal to half of the spread. === M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index e05b1ca029f..4aed50c6f4f 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -178,7 +178,7 @@ OrientationBounds LightTreePrimitive::calculate_bcone(Scene *scene) const } else if (type == LIGHT_AREA) { bcone.theta_o = 0; - bcone.theta_e = M_PI_2_F; + bcone.theta_e = lamp->get_spread() * 0.5f; } else { /* This should never be reached during construction. */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8ad56a0749e] soc-2022-many-lights-sampling: Fix: light tree fails with instanced objects
Commit: 8ad56a0749e0bab4ad0664cdf97798ba30be9af8 Author: Jeffrey Liu Date: Thu Jul 21 16:44:00 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB8ad56a0749e0bab4ad0664cdf97798ba30be9af8 Fix: light tree fails with instanced objects This fixes the issue with instanced objects. The issue was related to the fact that instanced objects were overwriting the same areas of the lookup table for the triangle to light tree array. === M intern/cycles/kernel/data_arrays.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h M intern/cycles/scene/object.cpp M intern/cycles/scene/scene.cpp M intern/cycles/scene/scene.h === diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h index a22200c58eb..28fcfb4a2cf 100644 --- a/intern/cycles/kernel/data_arrays.h +++ b/intern/cycles/kernel/data_arrays.h @@ -65,6 +65,7 @@ KERNEL_DATA_ARRAY(KernelLightTreeNode, light_tree_nodes) KERNEL_DATA_ARRAY(KernelLightTreeEmitter, light_tree_emitters) KERNEL_DATA_ARRAY(KernelLightTreeDistantEmitter, light_tree_distant_group) KERNEL_DATA_ARRAY(uint, light_to_tree) +KERNEL_DATA_ARRAY(uint, object_lookup_offset) KERNEL_DATA_ARRAY(uint, triangle_to_tree) /* particles */ diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 7d403a84c1b..56fbad6711a 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -87,7 +87,9 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, float3 ray_P = INTEGRATOR_STATE(state, ray, P); const float3 ray_D = INTEGRATOR_STATE(state, ray, D); const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); - pdf *= light_tree_pdf(kg, ray_P, N, sd->prim); + uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object); + uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object); + pdf *= light_tree_pdf(kg, ray_P, N, sd->prim - prim_offset + lookup_offset); } float mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf); L *= mis_weight; diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 3a193df9f17..8371bf71671 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -313,6 +313,7 @@ void LightManager::device_update_distribution(Device *device, bool light_tree_enabled = scene->integrator->get_use_light_tree(); vector light_prims; vector distant_lights; + vector object_lookup_offsets(scene->objects.size()); /* When we keep track of the light index, only contributing lights will be added to the device. * Therefore, we want to keep track of the light's index on the device. @@ -353,16 +354,19 @@ void LightManager::device_update_distribution(Device *device, if (progress.get_cancel()) return; -/* Count emissive triangles. */ -Mesh *mesh = static_cast(object->get_geometry()); -size_t mesh_num_triangles = mesh->num_triangles(); -total_triangles += mesh_num_triangles; - if (!object_usable_as_light(object)) { object_id++; continue; } +if (light_tree_enabled) { + object_lookup_offsets[object_id] = total_triangles; +} + +/* Count emissive triangles. */ +Mesh *mesh = static_cast(object->get_geometry()); +size_t mesh_num_triangles = mesh->num_triangles(); + for (size_t i = 0; i < mesh_num_triangles; i++) { int shader_index = mesh->get_shader()[i]; Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? @@ -374,7 +378,7 @@ void LightManager::device_update_distribution(Device *device, * triangles. Right now, point lights are the main concern. */ if (light_tree_enabled) { LightTreePrimitive light_prim; - light_prim.prim_id = i + mesh->prim_offset; + light_prim.prim_id = i; light_prim.object_id = object_id; light_prims.push_back(light_prim); } @@ -383,6 +387,7 @@ void LightManager::device_update_distribution(Device *device, } } +total_triangles += mesh_num_triangles; object_id++; } @@ -398,8 +403,13 @@ void LightManager::device_update_distribution(Device *device, /* We want to create separate arrays corresponding to triangles and lights, * which will be used to index back into the light tree for PDF calculations. */ uint *light_array = dscene->light_to_tree.alloc(num_lights); +uint *object_offsets = dscene->object_lookup_offset.alloc(object_lookup_offsets.size()); uint *triangle_
[Bf-blender-cvs] [5990bef329a] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 5990bef329ad5e00e859f9713454dc83fbc02456 Author: Jeffrey Liu Date: Thu Jul 21 16:46:38 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5990bef329ad5e00e859f9713454dc83fbc02456 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [d4f7f919016] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: d4f7f9190163841acc6f6168c1f380358fc50436 Author: Jeffrey Liu Date: Thu Jul 21 09:43:32 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBd4f7f9190163841acc6f6168c1f380358fc50436 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5174bcb1f02] soc-2022-many-lights-sampling: Fix: light tree calculations fail for translucent materials
Commit: 5174bcb1f029977ffb63c79b6dd2c595a187392f Author: Jeffrey Liu Date: Thu Jul 21 09:37:35 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5174bcb1f029977ffb63c79b6dd2c595a187392f Fix: light tree calculations fail for translucent materials This reverts an optimization made for opaque surfaces, where we assign zero importance to a light that's guaranteed to be behind a surface. The issue is that this fails for translucent surfaces. === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 0de3cbf9d8b..4c39c97060e 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -48,8 +48,13 @@ ccl_device float light_tree_node_importance(const float3 P, const float distance_squared = fmaxf(0.25f * len_squared(centroid - bbox_max), len_squared(centroid - P)); + /* to-do: should there be a different importance calculations for different surfaces? + * opaque surfaces could just return 0 importance in this case. */ const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); - const float theta_i = fast_acosf(dot(point_to_centroid, N)); + float theta_i = fast_acosf(dot(point_to_centroid, N)); + if (theta_i > M_PI_2_F) { +theta_i = M_PI_F - theta_i; + } const float theta_u = light_tree_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid); /* to-do: compare this with directly using fmaxf and cosf. */ @@ -61,11 +66,7 @@ ccl_device float light_tree_node_importance(const float3 P, const float cos_theta_prime = fast_cosf(theta_prime); float cos_theta_i_prime = 1.0f; - if (theta_i - theta_u > M_PI_2_F) { -/* If the lights are guaranteed to be completely behind the shading point, - * should we still perform further calculations? */ -return 0.0f; - } else if (theta_i - theta_u > 0.0f) { + if (theta_i - theta_u > 0.0f) { cos_theta_i_prime = fabsf(fast_cosf(theta_i - theta_u)); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [6406a4ea2ba] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 6406a4ea2baf05e22e6d19187f699bfb43cd9d99 Author: Jeffrey Liu Date: Tue Jul 19 23:20:36 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB6406a4ea2baf05e22e6d19187f699bfb43cd9d99 Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc intern/cycles/kernel/data_template.h index 000,b06ac62a5d8..cccb00c1adc mode 00,100644..100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@@ -1,0 -1,206 +1,211 @@@ + /* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + + #ifndef KERNEL_STRUCT_BEGIN + # define KERNEL_STRUCT_BEGIN(name, parent) + #endif + #ifndef KERNEL_STRUCT_END + # define KERNEL_STRUCT_END(name) + #endif + #ifndef KERNEL_STRUCT_MEMBER + # define KERNEL_STRUCT_MEMBER(parent, type, name) + #endif + + /* Background. */ + + KERNEL_STRUCT_BEGIN(KernelBackground, background) + /* xyz store direction, w the angle. float4 instead of float3 is used + * to ensure consistent padding/alignment across devices. */ + KERNEL_STRUCT_MEMBER(background, float4, sun) + /* Only shader index. */ + KERNEL_STRUCT_MEMBER(background, int, surface_shader) + KERNEL_STRUCT_MEMBER(background, int, volume_shader) + KERNEL_STRUCT_MEMBER(background, float, volume_step_size) + KERNEL_STRUCT_MEMBER(background, int, transparent) + KERNEL_STRUCT_MEMBER(background, float, transparent_roughness_squared_threshold) + /* Portal sampling. */ + KERNEL_STRUCT_MEMBER(background, float, portal_weight) + KERNEL_STRUCT_MEMBER(background, int, num_portals) + KERNEL_STRUCT_MEMBER(background, int, portal_offset) + /* Sun sampling. */ + KERNEL_STRUCT_MEMBER(background, float, sun_weight) + /* Importance map sampling. */ + KERNEL_STRUCT_MEMBER(background, float, map_weight) + KERNEL_STRUCT_MEMBER(background, int, map_res_x) + KERNEL_STRUCT_MEMBER(background, int, map_res_y) + /* Multiple importance sampling. */ + KERNEL_STRUCT_MEMBER(background, int, use_mis) + /* Lightgroup. */ + KERNEL_STRUCT_MEMBER(background, int, lightgroup) ++/* Light Index. */ ++KERNEL_STRUCT_MEMBER(background, int, light_index) + /* Padding. */ + KERNEL_STRUCT_MEMBER(background, int, pad1) + KERNEL_STRUCT_MEMBER(background, int, pad2) -KERNEL_STRUCT_MEMBER(background, int, pad3) + KERNEL_STRUCT_END(KernelBackground) + + /* BVH: own BVH2 if no native device acceleration struct used. */ + + KERNEL_STRUCT_BEGIN(KernelBVH, bvh) + KERNEL_STRUCT_MEMBER(bvh, int, root) + KERNEL_STRUCT_MEMBER(bvh, int, have_motion) + KERNEL_STRUCT_MEMBER(bvh, int, have_curves) + KERNEL_STRUCT_MEMBER(bvh, int, bvh_layout) + KERNEL_STRUCT_MEMBER(bvh, int, use_bvh_steps) + KERNEL_STRUCT_MEMBER(bvh, int, curve_subdivisions) + KERNEL_STRUCT_MEMBER(bvh, int, pad1) + KERNEL_STRUCT_MEMBER(bvh, int, pad2) + KERNEL_STRUCT_END(KernelBVH) + + /* Film. */ + + KERNEL_STRUCT_BEGIN(KernelFilm, film) + /* XYZ to rendering color space transform. float4 instead of float3 to + * ensure consistent padding/alignment across devices. */ + KERNEL_STRUCT_MEMBER(film, float4, xyz_to_r) + KERNEL_STRUCT_MEMBER(film, float4, xyz_to_g) + KERNEL_STRUCT_MEMBER(film, float4, xyz_to_b) + KERNEL_STRUCT_MEMBER(film, float4, rgb_to_y) + /* Rec709 to rendering color space. */ + KERNEL_STRUCT_MEMBER(film, float4, rec709_to_r) + KERNEL_STRUCT_MEMBER(film, float4, rec709_to_g) + KERNEL_STRUCT_MEMBER(film, float4, rec709_to_b) + KERNEL_STRUCT_MEMBER(film, int, is_rec709) + /* Exposuse. */ + KERNEL_STRUCT_MEMBER(film, float, exposure) + /* Passed used. */ + KERNEL_STRUCT_MEMBER(film, int, pass_flag) + KERNEL_STRUCT_MEMBER(film, int, light_pass_flag) + /* Pass offsets. */ + KERNEL_STRUCT_MEMBER(film, int, pass_stride) + KERNEL_STRUCT_MEMBER(film, int, pass_combined) + KERNEL_STRUCT_MEMBER(film, int, pass_depth) + KERNEL_STRUCT_MEMBER(film, int, pass_position) + KERNEL_STRUCT_MEMBER(film, int, pass_normal) + KERNEL_STRUCT_MEMBER(film, int, pass_roughness) + KERNEL_STRUCT_MEMBER(film, int, pass_motion) + KERNEL_STRUCT_MEMBER(film, int, pass_motion_weight) + KERNEL_STRUCT_MEMBER(film, int, pass_uv) + KERNEL_STRUCT_MEMBER(film, int, pass_object_id) + KERNEL_STRUCT_MEMBER(film, int, pass_material_id) + KERNEL_STRUCT_MEMBER(film, int, pass_diffuse_color) + KERNEL_STRUCT_MEMBER(film, int, pass_glossy_color) + KERNEL_STRUCT_MEMBER(film, int, pass_transmission_color) + KERNEL_STRUCT_MEMBER(film, int, pass_diffuse_indirect) + KERNEL_STRUCT_MEMBER(film, int, pass_glossy_indirect) + KERNEL_STRUCT_MEMBER(film, int, pass_transmission_indirect) + KERNEL_STRUCT_MEMBER(film, int, pass_volume_indirect) + KERNEL_STRUCT_MEMBER(film, int, pass_diffuse_direct) + KERNEL_STRUCT_MEMBER(film, int, pass_glossy_direct) + KERNEL_STRUCT_MEMBER(film, int, pass_transmission_direct) + KERNEL_STRUCT_MEMBER(film, int, pass_volume_direct) + KERNEL_STRUCT_MEMBER(film, int, pass_emission
[Bf-blender-cvs] [92e4d602ea2] soc-2022-many-lights-sampling: Fix: align KernelIntegrator and fix MIS
Commit: 92e4d602ea27b9574dd814d8758b2635161487ad Author: Jeffrey Liu Date: Tue Jul 19 20:28:45 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB92e4d602ea27b9574dd814d8758b2635161487ad Fix: align KernelIntegrator and fix MIS === M intern/cycles/kernel/data_template.h M intern/cycles/kernel/integrator/shade_surface.h === diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index cccb00c1adc..7339396e92c 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -197,6 +197,7 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_light_tree) KERNEL_STRUCT_MEMBER(integrator, float, splitting_threshold) /* Padding */ KERNEL_STRUCT_MEMBER(integrator, int, pad1) +KERNEL_STRUCT_MEMBER(integrator, int, pad2) KERNEL_STRUCT_END(KernelIntegrator) /* SVM. For shader specialization. */ diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 13c5e4d780e..7d403a84c1b 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -86,7 +86,6 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, if (kernel_data.integrator.use_light_tree) { float3 ray_P = INTEGRATOR_STATE(state, ray, P); const float3 ray_D = INTEGRATOR_STATE(state, ray, D); - ray_P -= ray_D * mis_ray_t; const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); pdf *= light_tree_pdf(kg, ray_P, N, sd->prim); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ed300ec3ee3] soc-2022-many-lights-sampling: Fix: use floats explicitly in light tree
Commit: ed300ec3ee3ecf937e97211b4f8481f078a8b459 Author: Jeffrey Liu Date: Mon Jul 18 09:29:01 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBed300ec3ee3ecf937e97211b4f8481f078a8b459 Fix: use floats explicitly in light tree === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 5d9dd069b73..0de3cbf9d8b 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -45,7 +45,7 @@ ccl_device float light_tree_node_importance(const float3 P, /* Since we're not using the splitting heuristic, we clamp * the distance to half the radius of the cluster. */ - const float distance_squared = fmaxf(0.25 * len_squared(centroid - bbox_max), + const float distance_squared = fmaxf(0.25f * len_squared(centroid - bbox_max), len_squared(centroid - P)); const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); @@ -56,7 +56,7 @@ ccl_device float light_tree_node_importance(const float3 P, /* Avoid using cosine until needed. */ const float theta_prime = fmaxf(theta - theta_o - theta_u, 0.0f); if (theta_prime >= theta_e) { -return 0; +return 0.0f; } const float cos_theta_prime = fast_cosf(theta_prime); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [7de3f44f79d] soc-2022-many-lights-sampling: Fix: light tree node partitioning
Commit: 7de3f44f79dc93b5b8e53cb43365bc4494256901 Author: Jeffrey Liu Date: Sat Jul 16 13:06:45 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB7de3f44f79dc93b5b8e53cb43365bc4494256901 Fix: light tree node partitioning This fixes the partitioning of the light tree primitives. Previously, the construction was not calculating the splitting dimension properly. === M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index c0676f508e3..2c3c8cb880f 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -357,7 +357,7 @@ LightTreeBuildNode *LightTree::recursive_build(vector * This is an O(n) algorithm where we iterate from the left and right side, * and swaps the appropriate left and right elements until complete. */ int left = start, right = end - 1; - float bounding_dimension = min_bucket * (centroid_bounds.size()[min_dim] / + float bounding_dimension = (min_bucket + 1) * (centroid_bounds.size()[min_dim] / LightTreeBucketInfo::num_buckets) + centroid_bounds.min[min_dim]; while (left < right) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [37e651e62c8] soc-2022-many-lights-sampling: Fix: light tree random number usage
Commit: 37e651e62c80b669f3b73a52e694caef85969641 Author: Jeffrey Liu Date: Sat Jul 16 23:40:42 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB37e651e62c80b669f3b73a52e694caef85969641 Fix: light tree random number usage This rescales the random numbers that are passed as arguments, rather than calling the random number generator again. === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 03d412d69ec..5d9dd069b73 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -54,18 +54,18 @@ ccl_device float light_tree_node_importance(const float3 P, /* to-do: compare this with directly using fmaxf and cosf. */ /* Avoid using cosine until needed. */ - const float theta_prime = fmaxf(theta - theta_o - theta_u, 0); + const float theta_prime = fmaxf(theta - theta_o - theta_u, 0.0f); if (theta_prime >= theta_e) { return 0; } const float cos_theta_prime = fast_cosf(theta_prime); - float cos_theta_i_prime = 1; + float cos_theta_i_prime = 1.0f; if (theta_i - theta_u > M_PI_2_F) { /* If the lights are guaranteed to be completely behind the shading point, * should we still perform further calculations? */ -cos_theta_i_prime = 0; - } else if (theta_i - theta_u > 0) { +return 0.0f; + } else if (theta_i - theta_u > 0.0f) { cos_theta_i_prime = fabsf(fast_cosf(theta_i - theta_u)); } @@ -121,7 +121,7 @@ ccl_device float light_tree_cluster_importance(KernelGlobals kg, template ccl_device int light_tree_sample(KernelGlobals kg, ccl_private const RNGState *rng_state, - float randu, + float *randu, const float randv, const float time, const float3 N, @@ -137,7 +137,6 @@ ccl_device int light_tree_sample(KernelGlobals kg, int index = 0; /* to-do: is it better to generate a new random sample for each step of the traversal? */ - float tree_u = path_state_rng_1D(kg, rng_state, 1); const ccl_global KernelLightTreeNode *knode = _data_fetch(light_tree_nodes, index); while (knode->child_index > 0) { /* At an interior node, the left child is directly next to the parent, @@ -149,17 +148,17 @@ ccl_device int light_tree_sample(KernelGlobals kg, const float right_importance = light_tree_cluster_importance(kg, P, N, right); float left_probability = left_importance / (left_importance + right_importance); -if (tree_u < left_probability) { +if (*randu < left_probability) { index = index + 1; knode = left; - tree_u = tree_u / left_probability; + *randu = *randu / left_probability; *pdf_factor *= left_probability; } else { index = knode->child_index; knode = right; - tree_u = (tree_u - left_probability) / (1 - left_probability); - *pdf_factor *= (1 - left_probability); + *randu = (*randu - left_probability) / (1.0f - left_probability); + *pdf_factor *= (1.0f - left_probability); } } @@ -177,15 +176,15 @@ ccl_device int light_tree_sample(KernelGlobals kg, } /* Once we have the total importance, we can normalize the CDF and sample it. */ - const float inv_total_importance = 1 / total_emitter_importance; + const float inv_total_importance = 1.0f / total_emitter_importance; float emitter_cdf = 0.0f; for (int i = 0; i < knode->num_prims; i++) { const int prim_index = -knode->child_index + i; /* to-do: is there any way to cache these values, so that recalculation isn't needed? */ const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) * inv_total_importance; -emitter_cdf += emitter_pdf; -if (tree_u < emitter_cdf) { +if (*randu < emitter_cdf + emitter_pdf) { + *randu = (*randu - emitter_cdf) / emitter_pdf; *pdf_factor *= emitter_pdf; ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch( light_tree_emitters, prim_index); @@ -205,7 +204,7 @@ ccl_device int light_tree_sample(KernelGlobals kg, } const int shader_flag = kemitter->mesh_light.shader_flag; -triangle_light_sample(kg, prim, object, randu, randv, time, ls, P); +triangle_light_sample(kg, prim, object, *randu, randv, time, ls, P); ls->shader |= shader_flag; return (ls->pdf > 0.0f); @@ -217,8 +216,9 @@ ccl_device int light_tree_sample(KernelGlobals kg, return false; } - return light_sample(kg, lamp, randu, randv, P, path_
[Bf-blender-cvs] [a7480b65da8] soc-2022-many-lights-sampling: Cycles: update light tree importance heuristics
Commit: a7480b65da816853fa806d008941f16d88b2d1cf Author: Jeffrey Liu Date: Sat Jul 16 13:17:10 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBa7480b65da816853fa806d008941f16d88b2d1cf Cycles: update light tree importance heuristics This uses the maximum light primitive energy when comparing between the light tree and the distant lights. It also uses the bounding box to compute distance when necessary. === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 6ba2cec6804..03d412d69ec 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -45,7 +45,8 @@ ccl_device float light_tree_node_importance(const float3 P, /* Since we're not using the splitting heuristic, we clamp * the distance to half the radius of the cluster. */ - const float distance_squared = len_squared(centroid - P); + const float distance_squared = fmaxf(0.25 * len_squared(centroid - bbox_max), + len_squared(centroid - P)); const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); const float theta_i = fast_acosf(dot(point_to_centroid, N)); diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 15cbfc36d7a..3a193df9f17 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -404,14 +404,11 @@ void LightManager::device_update_distribution(Device *device, const vector _bvh = light_tree.get_nodes(); KernelLightTreeNode *light_tree_nodes = dscene->light_tree_nodes.alloc(linearized_bvh.size()); KernelLightTreeEmitter *light_tree_emitters = dscene->light_tree_emitters.alloc(light_prims.size()); -float light_tree_energy = 0.0f; +float max_light_tree_energy = 0.0f; for (int index = 0; index < linearized_bvh.size(); index++) { const PackedLightTreeNode = linearized_bvh[index]; light_tree_nodes[index].energy = node.energy; - if (index == 0) { -light_tree_energy = node.energy; - } for (int i = 0; i < 3; i++) { light_tree_nodes[index].bounding_box_min[i] = node.bbox.min[i]; @@ -436,6 +433,10 @@ void LightManager::device_update_distribution(Device *device, float energy = prim.calculate_energy(scene); light_tree_emitters[emitter_index].energy = energy; + if (energy > max_light_tree_energy) { +max_light_tree_energy = energy; + } + for (int i = 0; i < 3; i++) { light_tree_emitters[emitter_index].bounding_box_min[i] = bbox.min[i]; light_tree_emitters[emitter_index].bounding_box_max[i] = bbox.max[i]; @@ -489,13 +490,19 @@ void LightManager::device_update_distribution(Device *device, } } +/* We set the parent node's energy to be the average energy, + * which is used for deciding between the tree and distant lights. */ +if (max_light_tree_energy > 0.0f) { + light_tree_nodes[0].energy = max_light_tree_energy; +} + /* We also add distant lights to a separate group. */ KernelLightTreeDistantEmitter *light_tree_distant_group = dscene->light_tree_distant_group.alloc(num_distant_lights + 1); /* We use OrientationBounds here to */ OrientationBounds distant_light_bounds = OrientationBounds::empty; -float distant_light_energy = 0.0f; +float max_distant_light_energy = 0.0f; for (int index = 0; index < num_distant_lights; index++) { LightTreePrimitive prim = distant_lights[index]; Light *light = scene->lights[prim.lamp_id]; @@ -532,12 +539,15 @@ void LightManager::device_update_distribution(Device *device, light_tree_distant_group[index].energy = energy; light_array[~prim.prim_id] = index; - distant_light_energy += energy; + + if (energy > max_distant_light_energy) { +max_distant_light_energy = energy; + } } /* The net OrientationBounds contain bounding information about all the distant lights. */ light_tree_distant_group[num_distant_lights].prim_id = -1; -light_tree_distant_group[num_distant_lights].energy = distant_light_energy; +light_tree_distant_group[num_distant_lights].energy = max_distant_light_energy; for (int i = 0; i < 3; i++) { light_tree_distant_group[num_distant_lights].direction[i] = distant_light_bounds.axis[i]; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [4a0a2e1ba55] soc-2022-many-lights-sampling: Fix: explicitly use floats for constant values
Commit: 4a0a2e1ba55a4d05189eb77c7ec190991260c4ee Author: Jeffrey Liu Date: Wed Jul 13 01:31:59 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB4a0a2e1ba55a4d05189eb77c7ec190991260c4ee Fix: explicitly use floats for constant values === M intern/cycles/kernel/light/light.h === diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index 40454ae6e63..06fc3a15c51 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -670,7 +670,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, if (has_motion) { triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V); const float area_pre = (kernel_data.integrator.use_light_tree) ? - 1.0 : + 1.0f : triangle_area(V[0], V[1], V[2]); pdf *= area_pre / area; } @@ -838,7 +838,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg, if (has_motion) { triangle_world_space_vertices(kg, object, prim, -1.0f, V); const float area_pre = (kernel_data.integrator.use_light_tree) ? - 1.0 : + 1.0f : triangle_area(V[0], V[1], V[2]); ls->pdf = ls->pdf * area_pre / area; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [7d242f7ef30] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 7d242f7ef30124079fc9dc7c274ea13b9f2c9919 Author: Jeffrey Liu Date: Wed Jul 13 01:26:58 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB7d242f7ef30124079fc9dc7c274ea13b9f2c9919 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [34eb8571601] soc-2022-many-lights-sampling: Fix: light tree triangle calculations
Commit: 34eb8571601e2971c91a0dd50ce30a3eda4366e7 Author: Jeffrey Liu Date: Wed Jul 13 01:25:25 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB34eb8571601e2971c91a0dd50ce30a3eda4366e7 Fix: light tree triangle calculations This fixes a variety of issues with triangles in the sampling. This includes incorrect normal calculations and incorrect PDF calculations. ` === M intern/cycles/kernel/light/light.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index c81b6db42fd..40454ae6e63 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -658,17 +658,25 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, } else { float pdf = triangle_light_pdf_area(kg, sd->Ng, sd->I, t); -if (has_motion) { - const float area = 0.5f * len(N); - if (UNLIKELY(area == 0.0f)) { -return 0.0f; - } +const float area = 0.5f * len(N); +if (UNLIKELY(area == 0.0f)) { + return 0.0f; +} + +if (area != 0.0f) { /* scale the PDF. * area = the area the sample was taken from * area_pre = the are from which pdf_triangles was calculated from */ - triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V); - const float area_pre = (kernel_data.integrator.use_light_tree) ? 1.0 : triangle_area(V[0], V[1], V[2]); - pdf = pdf * area_pre / area; + if (has_motion) { +triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V); +const float area_pre = (kernel_data.integrator.use_light_tree) ? + 1.0 : + triangle_area(V[0], V[1], V[2]); +pdf *= area_pre / area; + } + else if (kernel_data.integrator.use_light_tree) { +pdf /= area; + } } return pdf; @@ -823,15 +831,20 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg, /* compute incoming direction, distance and pdf */ ls->D = normalize_len(ls->P - P, >t); ls->pdf = triangle_light_pdf_area(kg, ls->Ng, -ls->D, ls->t); -if (has_motion && area != 0.0f) { +if (area != 0.0f) { /* scale the PDF. * area = the area the sample was taken from * area_pre = the are from which pdf_triangles was calculated from */ - triangle_world_space_vertices(kg, object, prim, -1.0f, V); - const float area_pre = (kernel_data.integrator.use_light_tree) ? - 1.0 : - triangle_area(V[0], V[1], V[2]); - ls->pdf = ls->pdf * area_pre / area; + if (has_motion) { +triangle_world_space_vertices(kg, object, prim, -1.0f, V); +const float area_pre = (kernel_data.integrator.use_light_tree) ? + 1.0 : + triangle_area(V[0], V[1], V[2]); +ls->pdf = ls->pdf * area_pre / area; + } + else if (kernel_data.integrator.use_light_tree) { +ls->pdf = ls->pdf / area; + } } ls->u = u; ls->v = v; diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 0ba28982e91..6ba2cec6804 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -151,7 +151,7 @@ ccl_device int light_tree_sample(KernelGlobals kg, if (tree_u < left_probability) { index = index + 1; knode = left; - tree_u = tree_u * left_probability; + tree_u = tree_u / left_probability; *pdf_factor *= left_probability; } else { diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index fd73114f969..c0676f508e3 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -149,7 +149,12 @@ OrientationBounds LightTreePrimitive::calculate_bcone(Scene *scene) const } } -float3 normal = triangle.compute_normal(p); +float3 normal = cross(p[1] - p[0], p[2] - p[0]); +const float normlen = len(normal); +if (normlen == 0.0f) { + normal = make_float3(1.0f, 0.0f, 0.0f); +} +normal = normal / normlen; bcone.axis = normal; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [360b3dad980] soc-2022-many-lights-sampling: Fix: toggling light tree crashes Cycles viewport
Commit: 360b3dad9801133712d20fc8c5514b707ab8e690 Author: Jeffrey Liu Date: Tue Jul 12 00:08:46 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB360b3dad9801133712d20fc8c5514b707ab8e690 Fix: toggling light tree crashes Cycles viewport There were a few issues involved with toggling the light tree setting in a Cycles vieweport. This was because the light manager wasn't tagged to update, so the distribution was not constructed correctly. === M intern/cycles/blender/sync.cpp M release/datafiles/locale M release/scripts/addons === diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index c5e048ede9b..cffd05d38ab 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -345,6 +345,10 @@ void BlenderSync::sync_integrator(BL::ViewLayer _view_layer, bool background) integrator->set_use_light_tree(get_boolean(cscene, "use_light_tree")); integrator->set_splitting_threshold(get_float(cscene, "splitting_threshold")); + if (integrator->use_light_tree_is_modified()) { +scene->light_manager->tag_update(scene, LightManager::UPDATE_ALL); + } + SamplingPattern sampling_pattern = (SamplingPattern)get_enum( cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); integrator->set_sampling_pattern(sampling_pattern); diff --git a/release/datafiles/locale b/release/datafiles/locale index 055bc5223c1..9a85b137951 16 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 055bc5223c1cd249e32ccbc8e8796ba9925c8c33 +Subproject commit 9a85b13795157560b319235c63f5a13b0107ba41 diff --git a/release/scripts/addons b/release/scripts/addons index 403b95ef6ff..807a64cdfc5 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 403b95ef6ff38918de966ed2a5843cfa3274a58b +Subproject commit 807a64cdfc50de1cfb263f2eb68680feddb66ec7 ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [c7465916d91] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: c7465916d91d26bc9165bfb09fb032289e64b2b2 Author: Jeffrey Liu Date: Tue Jul 12 00:32:14 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBc7465916d91d26bc9165bfb09fb032289e64b2b2 Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc release/scripts/addons index 807a64cdfc5,7a8502871c3..d2325587d73 --- a/release/scripts/addons +++ b/release/scripts/addons @@@ -1,1 -1,1 +1,1 @@@ - Subproject commit 807a64cdfc50de1cfb263f2eb68680feddb66ec7 -Subproject commit 7a8502871c34db0343cc7de52d6b49b15a84238a ++Subproject commit d2325587d73bc825986af3a1baba51cb4a9ce355 ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [7b3c1a203ef] soc-2022-many-lights-sampling: Cycles: update distant light importance heuristics
Commit: 7b3c1a203efdecf08d0aa041a76a984f2d72d870 Author: Jeffrey Liu Date: Sat Jul 9 16:01:03 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB7b3c1a203efdecf08d0aa041a76a984f2d72d870 Cycles: update distant light importance heuristics === M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 1b9e5d3806b..0ba28982e91 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -69,7 +69,7 @@ ccl_device float light_tree_node_importance(const float3 P, } /* to-do: find a good approximation for this value. */ - const float f_a = 1; + const float f_a = 1.0f; float importance = f_a * cos_theta_i_prime * energy / distance_squared * cos_theta_prime; return importance; @@ -225,8 +225,6 @@ ccl_device int light_tree_sample(KernelGlobals kg, return -1; } -/* to-do: assign relative importances for the background and distant lights. - * Can we somehow adjust the importance measure to account for these as well? */ ccl_device float light_tree_distant_light_importance(KernelGlobals kg, const float3 P, const float3 N, @@ -234,7 +232,28 @@ ccl_device float light_tree_distant_light_importance(KernelGlobals kg, { ccl_global const KernelLightTreeDistantEmitter *kdistant = _data_fetch( light_tree_distant_group, index); - return kdistant->energy; + + if (kdistant->energy == 0.0f) { +return 0.0f; + } + + const float3 light_axis = make_float3( + kdistant->direction[0], kdistant->direction[1], kdistant->direction[2]); + const float theta = fast_acosf(dot(N, light_axis)); + const float theta_i_prime = theta - kdistant->bounding_radius; + + float cos_theta_i_prime = 1; + if (theta_i_prime > M_PI_2_F) { +return 0.0f; + } else if (theta - kdistant->bounding_radius > 0) { +cos_theta_i_prime = fast_cosf(theta - kdistant->bounding_radius); + } + + /* to-do: find a good value for this. */ + const float f_a = 1.0f; + float importance = f_a * cos_theta_i_prime * kdistant->energy; + + return importance; } template @@ -286,7 +305,16 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, /* We need to be able to find the probability of selecting a given light, for MIS. */ ccl_device float light_tree_pdf(KernelGlobals kg, const float3 P, const float3 N, const int prim) { - float pdf = kernel_data.integrator.pdf_light_tree; + float distant_light_importance = light_tree_distant_light_importance( + kg, P, N, kernel_data.integrator.num_distant_lights); + float light_tree_importance = 0.0f; + if (kernel_data.integrator.num_distribution > kernel_data.integrator.num_distant_lights) { +const ccl_global KernelLightTreeNode *kroot = _data_fetch(light_tree_nodes, 0); +light_tree_importance = light_tree_cluster_importance(kg, P, N, kroot); + } + const float total_group_importance = light_tree_importance + distant_light_importance; + assert(total_group_importance != 0.0f); + float pdf = light_tree_importance / total_group_importance; const int emitter = (prim >= 0) ? kernel_data_fetch(triangle_to_tree, prim) : kernel_data_fetch(light_to_tree, ~prim); @@ -351,7 +379,16 @@ ccl_device float distant_lights_pdf(KernelGlobals kg, const float3 N, const int prim) { - float pdf = (1 - kernel_data.integrator.pdf_light_tree); + float distant_light_importance = light_tree_distant_light_importance( + kg, P, N, kernel_data.integrator.num_distant_lights); + float light_tree_importance = 0.0f; + if (kernel_data.integrator.num_distribution > kernel_data.integrator.num_distant_lights) { +const ccl_global KernelLightTreeNode *kroot = _data_fetch(light_tree_nodes, 0); +light_tree_importance = light_tree_cluster_importance(kg, P, N, kroot); + } + const float total_group_importance = light_tree_importance + distant_light_importance; + assert(total_group_importance != 0.0f); + float pdf = distant_light_importance / total_group_importance; /* The light_to_tree array doubles as a lookup table for * both the light tree as well as the distant lights group.*/ @@ -383,16 +420,31 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, const uint32_t path_flag, ccl_private LightSample *ls) { + float distant_light_importance = light_tree_distant_light_importance( + kg, P, N,
[Bf-blender-cvs] [a5da06c4160] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: a5da06c4160985bbb9aefa515c7cf5e90610691d Author: Jeffrey Liu Date: Sat Jul 9 16:01:34 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBa5da06c4160985bbb9aefa515c7cf5e90610691d Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [2c48ba0244f] soc-2022-many-lights-sampling: Fix: various Cycles light tree importance issues
Commit: 2c48ba0244fd21d8976ab8faf4a1e653f75dbc71 Author: Jeffrey Liu Date: Sat Jul 9 00:55:00 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB2c48ba0244fd21d8976ab8faf4a1e653f75dbc71 Fix: various Cycles light tree importance issues This fixes a variety of Cycles light tree importance issues, namely issues with bounding cone construction and usage. Some of the heuristics have also been adjusted for better results (tentatively). The next step is to determine a better heuristic for distant lights. === M intern/cycles/kernel/integrator/shade_light.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/light/light.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h index 4053e01737c..0e925f73afe 100644 --- a/intern/cycles/kernel/integrator/shade_light.h +++ b/intern/cycles/kernel/integrator/shade_light.h @@ -74,7 +74,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg, const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); if (kernel_data.integrator.use_light_tree) { const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); - ls.pdf *= light_tree_pdf(kg, ray_P, N, ~isect.prim); + ls.pdf *= light_tree_pdf(kg, ray_P, N, ~ls.lamp); } const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); light_eval *= mis_weight; diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index a01b03ad9d0..b172b3d2e03 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -78,13 +78,16 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, # endif { const float bsdf_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); -const float t = sd->ray_length + INTEGRATOR_STATE(state, path, mis_ray_t); +const float mis_ray_t = INTEGRATOR_STATE(state, path, mis_ray_t); +const float t = sd->ray_length + mis_ray_t; /* Multiple importance sampling, get triangle light pdf, * and compute weight with respect to BSDF pdf. */ float pdf = triangle_light_pdf(kg, sd, t); if (kernel_data.integrator.use_light_tree) { - const float3 ray_P = INTEGRATOR_STATE(state, ray, P); + float3 ray_P = INTEGRATOR_STATE(state, ray, P); + const float3 ray_D = INTEGRATOR_STATE(state, ray, D); + ray_P -= ray_D * mis_ray_t; const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); pdf *= light_tree_pdf(kg, ray_P, N, sd->prim); } diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index e9140298257..c81b6db42fd 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -796,6 +796,10 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg, triangle_world_space_vertices(kg, object, prim, -1.0f, V); area = triangle_area(V[0], V[1], V[2]); } + + if (kernel_data.integrator.use_light_tree) { +area = 1.0f; + } const float pdf = area * kernel_data.integrator.pdf_triangles; ls->pdf = pdf / solid_angle; } @@ -824,7 +828,9 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg, * area = the area the sample was taken from * area_pre = the are from which pdf_triangles was calculated from */ triangle_world_space_vertices(kg, object, prim, -1.0f, V); - const float area_pre = triangle_area(V[0], V[1], V[2]); + const float area_pre = (kernel_data.integrator.use_light_tree) ? + 1.0 : + triangle_area(V[0], V[1], V[2]); ls->pdf = ls->pdf * area_pre / area; } ls->u = u; diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 4df1dd7adc7..1b9e5d3806b 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -45,8 +45,7 @@ ccl_device float light_tree_node_importance(const float3 P, /* Since we're not using the splitting heuristic, we clamp * the distance to half the radius of the cluster. */ - const float distance_squared = fminf(len_squared(centroid - P), - 0.25f * len_squared(bbox_max - centroid)); + const float distance_squared = len_squared(centroid - P); const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); const float theta_i = fast_acosf(dot(point_to_centroid, N)); @@ -61,7 +60,11 @@ ccl_device float light_tree_node_importance(const float3 P, const float cos_th
[Bf-blender-cvs] [f5baeadee9c] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: f5baeadee9c1effedae994d5a5d31ef02774299d Author: Jeffrey Liu Date: Sat Jul 9 00:56:54 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf5baeadee9c1effedae994d5a5d31ef02774299d Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f1f5144c9a9] soc-2022-many-lights-sampling: Fix: light tree crashes with no primitives
Commit: f1f5144c9a9ba5b7e3f9d051a1f4e08c5170f0e0 Author: Jeffrey Liu Date: Fri Jul 8 10:34:56 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf1f5144c9a9ba5b7e3f9d051a1f4e08c5170f0e0 Fix: light tree crashes with no primitives === M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 9496c865774..17a9e8ac8f4 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -246,6 +246,10 @@ void LightTreeBuildNode::init_interior(LightTreeBuildNode *c0, LightTreeBuildNod LightTree::LightTree(const vector , Scene *scene, uint max_lights_in_leaf) { + if (prims.size() == 0) { +return; + } + prims_ = prims; scene_ = scene; max_lights_in_leaf_ = max_lights_in_leaf; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ec81cfab34f] soc-2022-many-lights-sampling: Cycles: implement calculation for light tree pdf
Commit: ec81cfab34f5cb3fd495f439c114744ea7eeddca Author: Jeffrey Liu Date: Thu Jul 7 15:28:56 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBec81cfab34f5cb3fd495f439c114744ea7eeddca Cycles: implement calculation for light tree pdf === M intern/cycles/kernel/data_arrays.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h M intern/cycles/scene/scene.cpp M intern/cycles/scene/scene.h === diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h index 42e6e88509d..a22200c58eb 100644 --- a/intern/cycles/kernel/data_arrays.h +++ b/intern/cycles/kernel/data_arrays.h @@ -64,6 +64,8 @@ KERNEL_DATA_ARRAY(float2, light_background_conditional_cdf) KERNEL_DATA_ARRAY(KernelLightTreeNode, light_tree_nodes) KERNEL_DATA_ARRAY(KernelLightTreeEmitter, light_tree_emitters) KERNEL_DATA_ARRAY(KernelLightTreeDistantEmitter, light_tree_distant_group) +KERNEL_DATA_ARRAY(uint, light_to_tree) +KERNEL_DATA_ARRAY(uint, triangle_to_tree) /* particles */ KERNEL_DATA_ARRAY(KernelParticle, particles) diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 57f2792cc35..cf7e9c2ee18 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -243,7 +243,7 @@ ccl_device int light_tree_sample(KernelGlobals kg, /* We should never reach this point. */ assert(false); - return false; + return -1; } /* to-do: assign relative importances for the background and distant lights. @@ -289,7 +289,7 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, ccl_global const KernelLightTreeDistantEmitter *kdistant = _data_fetch( light_tree_distant_group, i); - const int lamp = -kdistant->prim_id - 1; + const int lamp = kdistant->prim_id; if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { return false; @@ -298,6 +298,10 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, return light_sample(kg, lamp, randu, randv, P, path_flag, ls); } } + + /* We should never reach this point. */ + assert(false); + return -1; } ccl_device bool light_tree_sample_from_position(KernelGlobals kg, @@ -329,4 +333,81 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, return ret; } +/* We need to be able to find the probability of selecting a given light, for MIS. */ +ccl_device float light_tree_pdf(KernelGlobals kg, const float3 P, const float3 N, const int prim) +{ + float pdf = kernel_data.integrator.pdf_light_tree; + + const int emitter = (prim >= 0) ? kernel_data_fetch(triangle_to_tree, prim) : kernel_data_fetch(light_to_tree, ~prim); + ccl_global const KernelLightTreeEmitter* kemitter = _data_fetch(light_tree_emitters, + emitter); + int parent = kemitter->parent_index; + ccl_global const KernelLightTreeNode* kleaf = _data_fetch(light_tree_nodes, parent); + + /* First, we find the probability of selecting the primitive out of the leaf node. */ + float total_importance = 0.0f; + float emitter_importance = 0.0f; + for (int i = 0; i < kleaf->num_prims; i++) { +int prim = i - kleaf->child_index; /* At a leaf node, the negative value is the index into first prim. */ +const float importance = light_tree_emitter_importance(kg, P, N, prim); +if (i == emitter) { + emitter_importance = importance; +} +total_importance += importance; + } + pdf *= emitter_importance / total_importance; + + /* Next, we find the probability of traversing to that leaf node. */ + int child_index = parent; + parent = kleaf->parent_index; + while (parent != -1) { +const ccl_global KernelLightTreeNode *kparent = _data_fetch(light_tree_nodes, parent); + +const int left_index = parent + 1; +const int right_index = kparent->child_index; +const ccl_global KernelLightTreeNode *kleft = _data_fetch(light_tree_nodes, left_index); +const ccl_global KernelLightTreeNode *kright = _data_fetch(light_tree_nodes, right_index); + +const float left_importance = light_tree_cluster_importance(kg, P, N, kleft); +const float right_importance = light_tree_cluster_importance(kg, P, N, kright); +const float left_probability = left_importance / (left_importance + right_importance); + +/* If the child index matches the left index, then we must've traversed left, otherwise right. */ +if (left_index == child_index) { + pdf *= left_probability; +} +else { + pdf *= (1 - left_probability); +} + +child_index = pa
[Bf-blender-cvs] [bbf4c9d6475] soc-2022-many-lights-sampling: Cycles: update MIS calculations when light tree is enabled
Commit: bbf4c9d6475518976f59b4d78e17a455ecc89c7f Author: Jeffrey Liu Date: Thu Jul 7 16:49:34 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBbbf4c9d6475518976f59b4d78e17a455ecc89c7f Cycles: update MIS calculations when light tree is enabled === M intern/cycles/kernel/integrator/shade_background.h M intern/cycles/kernel/integrator/shade_light.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/integrator/state_template.h M intern/cycles/kernel/light/light.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/background.cpp M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h index 4791a963ae6..495bcb1cdaa 100644 --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@ -6,6 +6,7 @@ #include "kernel/film/accumulate.h" #include "kernel/integrator/shader_eval.h" #include "kernel/light/light.h" +#include "kernel/light/light_tree.h" #include "kernel/light/sample.h" CCL_NAMESPACE_BEGIN @@ -66,7 +67,11 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg, /* multiple importance sampling, get background light pdf for ray * direction, and compute weight with respect to BSDF pdf */ -const float pdf = background_light_pdf(kg, ray_P - ray_D * mis_ray_t, ray_D); +float pdf = background_light_pdf(kg, ray_P - ray_D * mis_ray_t, ray_D); +if (kernel_data.integrator.use_light_tree) { + const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); + pdf *= distant_lights_pdf(kg, ray_P, N, kernel_data.background.light_index); +} const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf); L *= mis_weight; } @@ -180,6 +185,11 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg, /* multiple importance sampling, get regular light pdf, * and compute weight with respect to BSDF pdf */ const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); +if (kernel_data.integrator.use_light_tree) { + const float3 ray_P = INTEGRATOR_STATE(state, ray, P); + const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); + ls.pdf *= distant_lights_pdf(kg, ray_P, N, lamp); +} const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); light_eval *= mis_weight; } diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h index be926c78439..4053e01737c 100644 --- a/intern/cycles/kernel/integrator/shade_light.h +++ b/intern/cycles/kernel/integrator/shade_light.h @@ -72,6 +72,10 @@ ccl_device_inline void integrate_light(KernelGlobals kg, /* multiple importance sampling, get regular light pdf, * and compute weight with respect to BSDF pdf */ const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); +if (kernel_data.integrator.use_light_tree) { + const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); + ls.pdf *= light_tree_pdf(kg, ray_P, N, ~isect.prim); +} const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); light_eval *= mis_weight; } diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index ca44daad5cf..a01b03ad9d0 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -83,6 +83,11 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, /* Multiple importance sampling, get triangle light pdf, * and compute weight with respect to BSDF pdf. */ float pdf = triangle_light_pdf(kg, sd, t); +if (kernel_data.integrator.use_light_tree) { + const float3 ray_P = INTEGRATOR_STATE(state, ray, P); + const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n); + pdf *= light_tree_pdf(kg, ray_P, N, sd->prim); +} float mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf); L *= mis_weight; } @@ -364,6 +369,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( else { INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = bsdf_pdf; INTEGRATOR_STATE_WRITE(state, path, mis_ray_t) = 0.0f; +INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N; INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf( bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf)); } diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cyc
[Bf-blender-cvs] [0f7bafed382] soc-2022-many-lights-sampling: Cycles: re-implement distant lights in many lights sampling
Commit: 0f7bafed3826f09e2c96126bd401de5e0540e038 Author: Jeffrey Liu Date: Sat Jul 2 13:55:19 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB0f7bafed3826f09e2c96126bd401de5e0540e038 Cycles: re-implement distant lights in many lights sampling This uses a basic heuristic to determine whether Cycles should sample from the distant lights group or the light tree, using the total energy. A better solution would be to compute some importance value. === M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 9cf601407b7..57f2792cc35 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -248,8 +248,6 @@ ccl_device int light_tree_sample(KernelGlobals kg, /* to-do: assign relative importances for the background and distant lights. * Can we somehow adjust the importance measure to account for these as well? */ - -/* ccl_device float light_tree_distant_light_importance(KernelGlobals kg, const float3 P, const float3 N, @@ -301,7 +299,6 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, } } } -*/ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, ccl_private const RNGState *rng_state, @@ -314,45 +311,19 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, const uint32_t path_flag, ccl_private LightSample *ls) { - /* - const int num_distant_lights = kernel_data.integrator.num_distant_lights; - const int num_light_tree_prims = kernel_data.integrator.num_distribution - num_distant_lights; - */ - float pdf_factor = 1.0f; - bool ret = light_tree_sample( -kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); - /* - bool ret = false; - if (num_distant_lights == 0) { + bool ret; + float tree_u = path_state_rng_1D(kg, rng_state, 1); + if (tree_u < kernel_data.integrator.pdf_light_tree) { +pdf_factor *= kernel_data.integrator.pdf_light_tree; ret = light_tree_sample( kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); } - else if (num_light_tree_prims == 0) { + else { +pdf_factor *= (1 - kernel_data.integrator.pdf_light_tree); ret = light_tree_sample_distant_lights( kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); } - else { -const ccl_global KernelLightTreeNode *knode = _data_fetch(light_tree_nodes, 0); -const float light_tree_importance = light_tree_cluster_importance(kg, P, N, knode); -const float distant_light_importance = light_tree_distant_light_importance(kg, P, N, num_distant_lights); - -const float light_tree_probability = light_tree_importance / - (light_tree_importance + - distant_light_importance); - -if (randu < light_tree_probability) { - ret = light_tree_sample( - kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); - pdf_factor *= light_tree_probability; -} -else { - ret = light_tree_sample_distant_lights( - kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); - pdf_factor *= (1 - light_tree_probability); -} - } - */ ls->pdf *= pdf_factor; return ret; diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index f360940b54a..3e9fcd19609 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1300,11 +1300,12 @@ typedef struct KernelIntegrator { int direct_light_sampling_type; /* Light tree. */ + float pdf_light_tree; int use_light_tree; float splitting_threshold; /* padding */ - int pad1, pad2; + int pad1; } KernelIntegrator; static_assert_align(KernelIntegrator, 16); diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index c7f252d13f9..242665387ca 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -383,7 +383,11 @@ void LightManager::device_update_distribution(Device *device, object_id++; } - if (light_tree_enabled) { + size_t num_distribution = num_triangles + num_lights; + VLOG_INFO << "Total " << num_distribution << " of light distribution primitives."; + + float pdf_light_tree = 0.0f; + if (light_tree_enabled && num_distribution > 0) { /* For now, we'll start w
[Bf-blender-cvs] [2c4a03c6b4d] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 2c4a03c6b4d5bcaff7128b66785575e77afbe467 Author: Jeffrey Liu Date: Sat Jul 2 13:57:40 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB2c4a03c6b4d5bcaff7128b66785575e77afbe467 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [3642fba679c] soc-2022-many-lights-sampling: Fix: Cycles light tree triangle sampling
Commit: 3642fba679c1300d21524a2d645c88a622d42eab Author: Jeffrey Liu Date: Fri Jul 1 11:01:02 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB3642fba679c1300d21524a2d645c88a622d42eab Fix: Cycles light tree triangle sampling This currently reverts some of the distant light sampling changes, so that I could isolate the issues with triangle light sampling. The fix ensures that the light distribution still computes the correct cdf (if needed), and removes the light tree kernel's dependency on the light distribution. This also corrects the triangle PDFs. === M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 679dcda39f9..9cf601407b7 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -185,16 +185,16 @@ ccl_device int light_tree_sample(KernelGlobals kg, emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; - ccl_global const KernelLightDistribution *kdistribution = _data_fetch( - light_distribution, prim_index); + ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch( + light_tree_emitters, prim_index); /* to-do: this is the same code as light_distribution_sample, except the index is determined * differently. Would it be better to refactor this into a separate function? */ - const int prim = kdistribution->prim; + const int prim = kemitter->prim_id; if (prim >= 0) { /* Mesh light. */ -const int object = kdistribution->mesh_light.object_id; +const int object = kemitter->mesh_light.object_id; /* Exclude synthetic meshes from shadow catcher pass. */ if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && @@ -202,9 +202,32 @@ ccl_device int light_tree_sample(KernelGlobals kg, return false; } -const int shader_flag = kdistribution->mesh_light.shader_flag; +const int shader_flag = kemitter->mesh_light.shader_flag; triangle_light_sample(kg, prim, object, randu, randv, time, ls, P); ls->shader |= shader_flag; + +/* triangle_light sample also multiplies the pdf by the triangle's area + * because of the precomputed light distribution PDF. + * We need to reverse this because it's not needed here.*/ +float area = 0.0f; + +float3 V[3]; +bool has_motion = triangle_world_space_vertices(kg, object, prim, time, V); + +const float3 e0 = V[1] - V[0]; +const float3 e1 = V[2] - V[0]; +const float3 e2 = V[2] - V[1]; + +const float3 N0 = cross(e0, e1); +if (has_motion) { + /* get the center frame vertices, this is what the PDF was calculated from */ + triangle_world_space_vertices(kg, object, prim, -1.0f, V); + area = triangle_area(V[0], V[1], V[2]); +} +else { + area = 0.5f * len(N0); +} +ls->pdf /= area; return (ls->pdf > 0.0f); } @@ -225,6 +248,8 @@ ccl_device int light_tree_sample(KernelGlobals kg, /* to-do: assign relative importances for the background and distant lights. * Can we somehow adjust the importance measure to account for these as well? */ + +/* ccl_device float light_tree_distant_light_importance(KernelGlobals kg, const float3 P, const float3 N, @@ -276,6 +301,7 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, } } } +*/ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, ccl_private const RNGState *rng_state, @@ -288,10 +314,15 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, const uint32_t path_flag, ccl_private LightSample *ls) { + /* const int num_distant_lights = kernel_data.integrator.num_distant_lights; const int num_light_tree_prims = kernel_data.integrator.num_distribution - num_distant_lights; + */ float pdf_factor = 1.0f; + bool ret = light_tree_sample( +kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); + /* bool ret = false; if (num_distant_lights == 0) { ret = light_tree_sample( @@ -321,6 +352,7 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, pdf_factor *= (1 - light_tree_probability); } } + */ ls->pd
[Bf-blender-cvs] [3f81ab1d0ec] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 3f81ab1d0ecf71bdf55fd24c2d2d0a7e8fa310ee Author: Jeffrey Liu Date: Fri Jul 1 11:05:53 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB3f81ab1d0ecf71bdf55fd24c2d2d0a7e8fa310ee Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [dd622af6131] soc-2022-many-lights-sampling: Fix: free Cycles device distant group
Commit: dd622af6131ad56e292dff3ca1d3a4c0a1345ab4 Author: Jeffrey Liu Date: Sat Jun 25 16:20:25 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBdd622af6131ad56e292dff3ca1d3a4c0a1345ab4 Fix: free Cycles device distant group === M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index a7b49bbff65..298477e2d6d 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -1054,7 +1054,6 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc klights[light_index].co[1] = co.y; klights[light_index].co[2] = co.z; - klights[light_index].area.axisu[0] = axisu.x; klights[light_index].area.axisu[1] = axisu.y; klights[light_index].area.axisu[2] = axisu.z; @@ -1210,6 +1209,8 @@ void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_ba /* to-do: check if the light tree member variables need to be wrapped in a conditional too*/ dscene->light_tree_nodes.free(); dscene->light_tree_emitters.free(); + dscene->light_tree_distant_group.free(); + dscene->light_distribution.free(); dscene->lights.free(); if (free_background) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [fe8897ad4cd] soc-2022-many-lights-sampling: Cycles: support distant lights in tree
Commit: fe8897ad4cdb2e9cbe25f3ecbd7289fffaa53b63 Author: Jeffrey Liu Date: Sat Jun 25 16:00:31 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBfe8897ad4cdb2e9cbe25f3ecbd7289fffaa53b63 Cycles: support distant lights in tree This is the initial support for sampling distant lights. The heuristic needs to be adjusted but it works in basic cases. === M intern/cycles/kernel/data_arrays.h M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/scene.cpp M intern/cycles/scene/scene.h === diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h index 978e45f07b7..42e6e88509d 100644 --- a/intern/cycles/kernel/data_arrays.h +++ b/intern/cycles/kernel/data_arrays.h @@ -63,6 +63,7 @@ KERNEL_DATA_ARRAY(float2, light_background_conditional_cdf) /* light tree */ KERNEL_DATA_ARRAY(KernelLightTreeNode, light_tree_nodes) KERNEL_DATA_ARRAY(KernelLightTreeEmitter, light_tree_emitters) +KERNEL_DATA_ARRAY(KernelLightTreeDistantEmitter, light_tree_distant_group) /* particles */ KERNEL_DATA_ARRAY(KernelParticle, particles) diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 788c2ccf90d..679dcda39f9 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -30,7 +30,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, /* This is the general function for calculating the importance of either a cluster or an emitter. * Both of the specialized functions obtain the necessary data before calling this function. - * to-do: find a better way to handle this? */ + * to-do: find a better way to handle this? or rename it to be more clear? */ ccl_device float light_tree_node_importance(const float3 P, const float3 N, const float3 bbox_min, @@ -112,11 +112,10 @@ ccl_device float light_tree_cluster_importance(KernelGlobals kg, P, N, bbox_min, bbox_max, bcone_axis, knode->theta_o, knode->theta_e, knode->energy); } - /* to-do: for now, we're not going to worry about being in a volume for now, * but this seems to be a good way to differentiate whether we're in a volume or not. */ template -ccl_device bool light_tree_sample(KernelGlobals kg, +ccl_device int light_tree_sample(KernelGlobals kg, ccl_private const RNGState *rng_state, float randu, const float randv, @@ -186,11 +185,11 @@ ccl_device bool light_tree_sample(KernelGlobals kg, emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; - ccl_global const KernelLightDistribution *kdistribution = _data_fetch(light_distribution, - prim_index); + ccl_global const KernelLightDistribution *kdistribution = _data_fetch( + light_distribution, prim_index); - /* to-do: this is the same code as light_distribution_sample, except the index is determined differently. - * Would it be better to refactor this into a separate function? */ + /* to-do: this is the same code as light_distribution_sample, except the index is determined + * differently. Would it be better to refactor this into a separate function? */ const int prim = kdistribution->prim; if (prim >= 0) { @@ -224,6 +223,60 @@ ccl_device bool light_tree_sample(KernelGlobals kg, return false; } +/* to-do: assign relative importances for the background and distant lights. + * Can we somehow adjust the importance measure to account for these as well? */ +ccl_device float light_tree_distant_light_importance(KernelGlobals kg, + const float3 P, + const float3 N, + const int index) +{ + ccl_global const KernelLightTreeDistantEmitter *kdistant = _data_fetch( + light_tree_distant_group, index); + return kdistant->energy; +} + +template +ccl_device int light_tree_sample_distant_lights(KernelGlobals kg, +ccl_private const RNGState *rng_state, +float randu, +const float randv, +const float time, +const float3 N, +const float3 P, +
[Bf-blender-cvs] [79089da5a25] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 79089da5a2574f2289bba7b360c609129bf9d2fa Author: Jeffrey Liu Date: Sat Jun 25 16:15:34 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB79089da5a2574f2289bba7b360c609129bf9d2fa Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc release/scripts/addons index 038db9d607b,c51e0bb1793..807a64cdfc5 --- a/release/scripts/addons +++ b/release/scripts/addons @@@ -1,1 -1,1 +1,1 @@@ - Subproject commit 038db9d607b352f6a7391c5a6b3ab906692c9421 -Subproject commit c51e0bb1793c44c7a1b7435593dd5022cf7c8eec ++Subproject commit 807a64cdfc50de1cfb263f2eb68680feddb66ec7 ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [63c23dff931] soc-2022-many-lights-sampling: Fix: Blender crashes with emissive triangles
Commit: 63c23dff931ee269e37ed6549d0b4d57ed85d909 Author: Jeffrey Liu Date: Wed Jun 22 03:23:06 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB63c23dff931ee269e37ed6549d0b4d57ed85d909 Fix: Blender crashes with emissive triangles This is related to the light-tree implementation. The issue most often happens when the emissive material is just added and the preview material is then rendered. The crash is caused by iterating through the wrong thing. We are now iterating through emissive primitives, and many of these primitives correspond to the same object. However, the inner loop was still iterating through all triangles of the object, so it was iterating through the same object multiple times. === M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 3035a2e3138..97f0e98633f 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -444,37 +444,28 @@ void LightManager::device_update_distribution(Device *, shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER; } -size_t mesh_num_triangles = mesh->num_triangles(); -for (size_t i = 0; i < mesh_num_triangles; i++) { - int shader_index = mesh->get_shader()[i]; - Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? - static_cast(mesh->get_used_shaders()[shader_index]) : - scene->default_surface; - - if (shader->get_use_mis() && shader->has_surface_emission) { -distribution[offset].totarea = totarea; -distribution[offset].prim = prim.prim_id; -distribution[offset].mesh_light.shader_flag = shader_flag; -distribution[offset].mesh_light.object_id = prim.object_id; -offset++; - -Mesh::Triangle t = mesh->get_triangle(i); -if (!t.valid(>get_verts()[0])) { - continue; -} -float3 p1 = mesh->get_verts()[t.v[0]]; -float3 p2 = mesh->get_verts()[t.v[1]]; -float3 p3 = mesh->get_verts()[t.v[2]]; - -if (!transform_applied) { - p1 = transform_point(, p1); - p2 = transform_point(, p2); - p3 = transform_point(, p3); -} - -totarea += triangle_area(p1, p2, p3); - } +distribution[offset].totarea = totarea; +distribution[offset].prim = prim.prim_id; +distribution[offset].mesh_light.shader_flag = shader_flag; +distribution[offset].mesh_light.object_id = prim.object_id; +offset++; + +int triangle_index = prim.prim_id - mesh->prim_offset; +Mesh::Triangle t = mesh->get_triangle(triangle_index); +if (!t.valid(>get_verts()[0])) { + continue; } +float3 p1 = mesh->get_verts()[t.v[0]]; +float3 p2 = mesh->get_verts()[t.v[1]]; +float3 p3 = mesh->get_verts()[t.v[2]]; + +if (!transform_applied) { + p1 = transform_point(, p1); + p2 = transform_point(, p2); + p3 = transform_point(, p3); +} + +totarea += triangle_area(p1, p2, p3); } float trianglearea = totarea; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [0fc2bb43aa4] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 0fc2bb43aa42f877e3b4666a81545e1cba4d9d3a Author: Jeffrey Liu Date: Wed Jun 22 03:29:24 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB0fc2bb43aa42f877e3b4666a81545e1cba4d9d3a Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [3dead138450] soc-2022-many-lights-sampling: Cleanup: unused members in light tree struct
Commit: 3dead13845057a417cf5c8d198bca9c366b3e4d1 Author: Jeffrey Liu Date: Wed Jun 22 01:42:20 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB3dead13845057a417cf5c8d198bca9c366b3e4d1 Cleanup: unused members in light tree struct === M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M release/scripts/addons === diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 5a5e1bcc220..474a6966ae5 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1538,12 +1538,6 @@ typedef struct KernelLightTreeEmitter { /* Energy. */ float energy; - - /* If this is positive, this is a triangle. Otherwise, it's a light source. */ - int prim_id; - - /* Padding. */ - int pad1, pad2, pad3; } KernelLightTreeEmitter; static_assert_align(KernelLightTreeEmitter, 16); diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index e46c76594f4..3035a2e3138 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -393,8 +393,6 @@ void LightManager::device_update_distribution(Device *, } light_tree_emitters[index].theta_o = bcone.theta_o; light_tree_emitters[index].theta_e = bcone.theta_e; - - light_tree_emitters[index].prim_id = prim.prim_id; } dscene->light_tree_emitters.copy_to_device(); } diff --git a/release/scripts/addons b/release/scripts/addons index 5902265f1e5..038db9d607b 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 5902265f1e5aaeca3781ea15f994bdf0b3cb054d +Subproject commit 038db9d607b352f6a7391c5a6b3ab906692c9421 ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f1feff40c0a] soc-2022-many-lights-sampling: Fix: Cycles light tree kernel compiler errors
Commit: f1feff40c0aa30615fdca48016e59ace2785dc26 Author: Jeffrey Liu Date: Tue Jun 21 00:38:32 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf1feff40c0aa30615fdca48016e59ace2785dc26 Fix: Cycles light tree kernel compiler errors === M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 2016c00434c..78ad9dedad8 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -115,7 +115,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, float light_u, light_v; path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, _u, _v); -if (kg->__data.integrator.use_light_tree) { +if (kg->data.integrator.use_light_tree) { if (!light_tree_sample_from_position( kg, rng_state, light_u, light_v, sd->time, sd->P, sd->N, bounce, path_flag, )) { return; diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index ebc6d8280a2..788c2ccf90d 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -77,8 +77,8 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, const float3 N, int emitter_index) { - ccl_global const KernelLightTreeEmitter *kemitter = _tex_fetch(__light_tree_emitters, - emitter_index); + ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, + emitter_index); /* Convert the data from the struct into float3 for calculations. */ const float3 bbox_min = make_float3(kemitter->bounding_box_min[0], @@ -136,12 +136,12 @@ ccl_device bool light_tree_sample(KernelGlobals kg, /* to-do: is it better to generate a new random sample for each step of the traversal? */ float tree_u = path_state_rng_1D(kg, rng_state, 1); - const ccl_global KernelLightTreeNode *knode = _tex_fetch(__light_tree_nodes, index); + const ccl_global KernelLightTreeNode *knode = _data_fetch(light_tree_nodes, index); while (knode->child_index > 0) { /* At an interior node, the left child is directly next to the parent, * while the right child is stored as the child index. */ -const ccl_global KernelLightTreeNode *left = _tex_fetch(__light_tree_nodes, index + 1); -const ccl_global KernelLightTreeNode *right = _tex_fetch(__light_tree_nodes, knode->child_index); +const ccl_global KernelLightTreeNode *left = _data_fetch(light_tree_nodes, index + 1); +const ccl_global KernelLightTreeNode *right = _data_fetch(light_tree_nodes, knode->child_index); const float left_importance = light_tree_cluster_importance(kg, P, N, left); const float right_importance = light_tree_cluster_importance(kg, P, N, right); @@ -186,8 +186,8 @@ ccl_device bool light_tree_sample(KernelGlobals kg, emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; - ccl_global const KernelLightDistribution *kdistribution = _tex_fetch(__light_distribution, - prim_index); + ccl_global const KernelLightDistribution *kdistribution = _data_fetch(light_distribution, + prim_index); /* to-do: this is the same code as light_distribution_sample, except the index is determined differently. * Would it be better to refactor this into a separate function? */ @@ -199,7 +199,7 @@ ccl_device bool light_tree_sample(KernelGlobals kg, /* Exclude synthetic meshes from shadow catcher pass. */ if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && -!(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { +!(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { return false; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b323b40af64] soc-2022-many-lights-sampling: Cycles: support emissive triangles in light tree
Commit: b323b40af648c2a46bf1193c16ecc35916f26dba Author: Jeffrey Liu Date: Tue Jun 21 00:05:55 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBb323b40af648c2a46bf1193c16ecc35916f26dba Cycles: support emissive triangles in light tree === M intern/cycles/kernel/light/light_tree.h M intern/cycles/kernel/textures.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/scene.cpp M intern/cycles/scene/scene.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 1c9684e006c..ebc6d8280a2 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -77,29 +77,22 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, const float3 N, int emitter_index) { - ccl_global const KernelLightDistribution *kdistribution = _tex_fetch(__light_distribution, - emitter_index); - const int prim = kdistribution->prim; + ccl_global const KernelLightTreeEmitter *kemitter = _tex_fetch(__light_tree_emitters, + emitter_index); - if (prim >= 0) { -/* to-do: handle case for mesh lights. */ - } - - /* If we're not at a mesh light, then we should be at a point, spot, or area light. */ - const int lamp = -prim - 1; - const ccl_global KernelLight *klight = _tex_fetch(__lights, lamp); - const float radius = klight->spot.radius; - const float3 bbox_min = make_float3( - klight->co[0] - radius, klight->co[1] - radius, klight->co[2] - radius); - const float3 bbox_max = make_float3( - klight->co[0] + radius, klight->co[1] + radius, klight->co[2] + radius); - const float3 bcone_axis = make_float3( - klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]); - const float3 rgb_strength = make_float3( - klight->strength[0], klight->strength[1], klight->strength[2]); + /* Convert the data from the struct into float3 for calculations. */ + const float3 bbox_min = make_float3(kemitter->bounding_box_min[0], + kemitter->bounding_box_min[1], + kemitter->bounding_box_min[2]); + const float3 bbox_max = make_float3(kemitter->bounding_box_max[0], + kemitter->bounding_box_max[1], + kemitter->bounding_box_max[2]); + const float3 bcone_axis = make_float3(kemitter->bounding_cone_axis[0], +kemitter->bounding_cone_axis[1], +kemitter->bounding_cone_axis[2]); return light_tree_node_importance( - P, N, bbox_min, bbox_max, bcone_axis, M_PI_F, M_PI_2_F, linear_rgb_to_gray(kg, rgb_strength)); + P, N, bbox_min, bbox_max, bcone_axis, kemitter->theta_o, kemitter->theta_e, kemitter->energy); } ccl_device float light_tree_cluster_importance(KernelGlobals kg, @@ -193,10 +186,36 @@ ccl_device bool light_tree_sample(KernelGlobals kg, emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; - if (UNLIKELY(light_select_reached_max_bounces(kg, prim_index, bounce))) { + ccl_global const KernelLightDistribution *kdistribution = _tex_fetch(__light_distribution, + prim_index); + + /* to-do: this is the same code as light_distribution_sample, except the index is determined differently. + * Would it be better to refactor this into a separate function? */ + const int prim = kdistribution->prim; + + if (prim >= 0) { +/* Mesh light. */ +const int object = kdistribution->mesh_light.object_id; + +/* Exclude synthetic meshes from shadow catcher pass. */ +if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && +!(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { + return false; +} + +const int shader_flag = kdistribution->mesh_light.shader_flag; +triangle_light_sample(kg, prim, object, randu, randv, time, ls, P); +ls->shader |= shader_flag; +return (ls->pdf > 0.0f); + } + + const int lamp = -prim - 1; + + if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { return false; } - return light_sample(kg, prim_index, randu, randv, P, path_flag, ls);
[Bf-blender-cvs] [02239aca42c] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 02239aca42cbc452993e501266d76600090a3b12 Author: Jeffrey Liu Date: Tue Jun 21 00:14:40 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB02239aca42cbc452993e501266d76600090a3b12 Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc intern/cycles/kernel/data_arrays.h index 000,7205f728088..978e45f07b7 mode 00,100644..100644 --- a/intern/cycles/kernel/data_arrays.h +++ b/intern/cycles/kernel/data_arrays.h @@@ -1,0 -1,82 +1,86 @@@ + /* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + + #ifndef KERNEL_DATA_ARRAY + # define KERNEL_DATA_ARRAY(type, name) + #endif + + /* BVH2, not used for OptiX or Embree. */ + KERNEL_DATA_ARRAY(float4, bvh_nodes) + KERNEL_DATA_ARRAY(float4, bvh_leaf_nodes) + KERNEL_DATA_ARRAY(uint, prim_type) + KERNEL_DATA_ARRAY(uint, prim_visibility) + KERNEL_DATA_ARRAY(uint, prim_index) + KERNEL_DATA_ARRAY(uint, prim_object) + KERNEL_DATA_ARRAY(uint, object_node) + KERNEL_DATA_ARRAY(float2, prim_time) + + /* objects */ + KERNEL_DATA_ARRAY(KernelObject, objects) + KERNEL_DATA_ARRAY(Transform, object_motion_pass) + KERNEL_DATA_ARRAY(DecomposedTransform, object_motion) + KERNEL_DATA_ARRAY(uint, object_flag) + KERNEL_DATA_ARRAY(float, object_volume_step) + KERNEL_DATA_ARRAY(uint, object_prim_offset) + + /* cameras */ + KERNEL_DATA_ARRAY(DecomposedTransform, camera_motion) + + /* triangles */ + KERNEL_DATA_ARRAY(uint, tri_shader) + KERNEL_DATA_ARRAY(packed_float3, tri_vnormal) + KERNEL_DATA_ARRAY(uint4, tri_vindex) + KERNEL_DATA_ARRAY(uint, tri_patch) + KERNEL_DATA_ARRAY(float2, tri_patch_uv) + KERNEL_DATA_ARRAY(packed_float3, tri_verts) + + /* curves */ + KERNEL_DATA_ARRAY(KernelCurve, curves) + KERNEL_DATA_ARRAY(float4, curve_keys) + KERNEL_DATA_ARRAY(KernelCurveSegment, curve_segments) + + /* patches */ + KERNEL_DATA_ARRAY(uint, patches) + + /* pointclouds */ + KERNEL_DATA_ARRAY(float4, points) + KERNEL_DATA_ARRAY(uint, points_shader) + + /* attributes */ + KERNEL_DATA_ARRAY(AttributeMap, attributes_map) + KERNEL_DATA_ARRAY(float, attributes_float) + KERNEL_DATA_ARRAY(float2, attributes_float2) + KERNEL_DATA_ARRAY(packed_float3, attributes_float3) + KERNEL_DATA_ARRAY(float4, attributes_float4) + KERNEL_DATA_ARRAY(uchar4, attributes_uchar4) + + /* lights */ + KERNEL_DATA_ARRAY(KernelLightDistribution, light_distribution) + KERNEL_DATA_ARRAY(KernelLight, lights) + KERNEL_DATA_ARRAY(float2, light_background_marginal_cdf) + KERNEL_DATA_ARRAY(float2, light_background_conditional_cdf) + ++/* light tree */ ++KERNEL_DATA_ARRAY(KernelLightTreeNode, light_tree_nodes) ++KERNEL_DATA_ARRAY(KernelLightTreeEmitter, light_tree_emitters) ++ + /* particles */ + KERNEL_DATA_ARRAY(KernelParticle, particles) + + /* shaders */ + KERNEL_DATA_ARRAY(uint4, svm_nodes) + KERNEL_DATA_ARRAY(KernelShader, shaders) + + /* lookup tables */ + KERNEL_DATA_ARRAY(float, lookup_table) + + /* sobol */ + KERNEL_DATA_ARRAY(float, sample_pattern_lut) + + /* image textures */ + KERNEL_DATA_ARRAY(TextureInfo, texture_info) + + /* ies lights */ + KERNEL_DATA_ARRAY(float, ies) + + #undef KERNEL_DATA_ARRAY diff --cc intern/cycles/scene/scene.cpp index b4a57f77552,1fcc3331337..85050c99518 --- a/intern/cycles/scene/scene.cpp +++ b/intern/cycles/scene/scene.cpp @@@ -34,51 -34,49 +34,51 @@@ CCL_NAMESPACE_BEGIN DeviceScene::DeviceScene(Device *device) - : bvh_nodes(device, "__bvh_nodes", MEM_GLOBAL), - bvh_leaf_nodes(device, "__bvh_leaf_nodes", MEM_GLOBAL), - object_node(device, "__object_node", MEM_GLOBAL), - prim_type(device, "__prim_type", MEM_GLOBAL), - prim_visibility(device, "__prim_visibility", MEM_GLOBAL), - prim_index(device, "__prim_index", MEM_GLOBAL), - prim_object(device, "__prim_object", MEM_GLOBAL), - prim_time(device, "__prim_time", MEM_GLOBAL), - tri_verts(device, "__tri_verts", MEM_GLOBAL), - tri_shader(device, "__tri_shader", MEM_GLOBAL), - tri_vnormal(device, "__tri_vnormal", MEM_GLOBAL), - tri_vindex(device, "__tri_vindex", MEM_GLOBAL), - tri_patch(device, "__tri_patch", MEM_GLOBAL), - tri_patch_uv(device, "__tri_patch_uv", MEM_GLOBAL), - curves(device, "__curves", MEM_GLOBAL), - curve_keys(device, "__curve_keys", MEM_GLOBAL), - curve_segments(device, "__curve_segments", MEM_GLOBAL), - patches(device, "__patches", MEM_GLOBAL), - points(device, "__points", MEM_GLOBAL), - points_shader(device, "__points_shader", MEM_GLOBAL), - objects(device, "__objects", MEM_GLOBAL), - object_motion_pass(device, "__object_m
[Bf-blender-cvs] [0427a0d4808] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 0427a0d4808cebad8bc7797c3d820dc2cec6322d Author: Jeffrey Liu Date: Sun Jun 19 02:11:26 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB0427a0d4808cebad8bc7797c3d820dc2cec6322d Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5bae09c1c74] soc-2022-many-lights-sampling: Cycles: support spot and area lights in light tree
Commit: 5bae09c1c742c70162781a414ce8eba6b3d97a23 Author: Jeffrey Liu Date: Sun Jun 19 02:10:01 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5bae09c1c742c70162781a414ce8eba6b3d97a23 Cycles: support spot and area lights in light tree === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M release/scripts/addons === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 87c49ebc30c..1c9684e006c 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -84,28 +84,22 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg, if (prim >= 0) { /* to-do: handle case for mesh lights. */ } - else { -const int lamp = -prim - 1; -const ccl_global KernelLight *klight = _tex_fetch(__lights, lamp); -if (klight->type == LIGHT_POINT) { - const float radius = klight->spot.radius; - const float3 bbox_min = make_float3( - klight->co[0] - radius, klight->co[1] - radius, klight->co[2] - radius); - const float3 bbox_max = make_float3( - klight->co[0] + radius, klight->co[1] + radius, klight->co[2] + radius); - const float3 rgb_strength = make_float3( - klight->strength[0], klight->strength[1], klight->strength[2]); - - /* to-do: only the radius and invarea from the spotlight properties is used for a point light, - * but we still need to choose an arbitrary direction. Maybe this can be replaced with something else? */ - const float3 bcone_axis = make_float3( - klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]); - - return light_tree_node_importance( - P, N, bbox_min, bbox_max, bcone_axis, M_PI_F, M_PI_2_F, linear_rgb_to_gray(kg, rgb_strength)); -} - } + /* If we're not at a mesh light, then we should be at a point, spot, or area light. */ + const int lamp = -prim - 1; + const ccl_global KernelLight *klight = _tex_fetch(__lights, lamp); + const float radius = klight->spot.radius; + const float3 bbox_min = make_float3( + klight->co[0] - radius, klight->co[1] - radius, klight->co[2] - radius); + const float3 bbox_max = make_float3( + klight->co[0] + radius, klight->co[1] + radius, klight->co[2] + radius); + const float3 bcone_axis = make_float3( + klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]); + const float3 rgb_strength = make_float3( + klight->strength[0], klight->strength[1], klight->strength[2]); + + return light_tree_node_importance( + P, N, bbox_min, bbox_max, bcone_axis, M_PI_F, M_PI_2_F, linear_rgb_to_gray(kg, rgb_strength)); } ccl_device float light_tree_cluster_importance(KernelGlobals kg, @@ -208,6 +202,7 @@ ccl_device bool light_tree_sample(KernelGlobals kg, /* We should never reach this point. */ assert(false); + return false; } ccl_device bool light_tree_sample_from_position(KernelGlobals kg, diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 84c4f63a2fb..e9407554cbe 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -288,6 +288,7 @@ void LightManager::device_update_distribution(Device *, int scene_light_index = 0; foreach (Light *light, scene->lights) { if (light->is_enabled) { + /* to-do: make sure not to add background lights to the light tree once those scenes are tested. */ LightTreePrimitive light_prim; light_prim.prim_id = ~device_light_index; /* -prim_id - 1 is a light source index. */ light_prim.lamp_id = scene_light_index; diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index d50f257e6c7..22930586d43 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -60,28 +60,93 @@ OrientationBounds merge(const OrientationBounds& cone_a, BoundBox LightTreePrimitive::calculate_bbox(Scene *scene) const { BoundBox bbox = BoundBox::empty; - Light *lamp = scene->lights[lamp_id]; - /* A point light can emit light from any point within its radius. */ - bbox.grow(lamp->get_co() - make_float3(lamp->get_size())); - bbox.grow(lamp->get_co() + make_float3(lamp->get_size())); + + if (prim_id >= 0) { +/* to-do: handle mesh lights in the future. */ + } + else { +Light *lamp = scene->lights[lamp_id]; +LightType type = lamp->get_light_type(); +const float3 center = lamp->get_co(); +const float size = lamp->get_size(); + +if (type == LIGHT_POINT || type == LIGHT_SPOT) { + /* Point and spot lights can emit light from any point within its ra
[Bf-blender-cvs] [282c5a6f980] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 282c5a6f9805d2b6efb153e895168a34388f9176 Author: Jeffrey Liu Date: Sat Jun 18 04:40:11 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB282c5a6f9805d2b6efb153e895168a34388f9176 Merge branch 'master' into soc-2022-many-lights-sampling === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [59fffd32626] soc-2022-many-lights-sampling: Fix: Cycles light tree construction/traversal bugs
Commit: 59fffd326262122d291829188a3ec75f04c53980 Author: Jeffrey Liu Date: Sat Jun 18 04:01:50 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB59fffd326262122d291829188a3ec75f04c53980 Fix: Cycles light tree construction/traversal bugs === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 7cff13b7c97..87c49ebc30c 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -21,7 +21,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, corners[6] = make_float3(bbox_max.x, bbox_max.y, bbox_min.z); corners[7] = bbox_max; for (int i = 0; i < 8; ++i) { -float3 point_to_corner = normalize(P - corners[i]); +float3 point_to_corner = normalize(corners[i] - P); const float cos_theta_u = dot(point_to_centroid, point_to_corner); theta_u = fmaxf(fast_acosf(cos_theta_u), theta_u); } @@ -41,9 +41,12 @@ ccl_device float light_tree_node_importance(const float3 P, const float energy) { const float3 centroid = 0.5f * bbox_min + 0.5f * bbox_max; - const float3 point_to_centroid = normalize(P - centroid); + const float3 point_to_centroid = normalize(centroid - P); - const float distance_squared = len_squared(P - centroid); + /* Since we're not using the splitting heuristic, we clamp + * the distance to half the radius of the cluster. */ + const float distance_squared = fminf(len_squared(centroid - P), + 0.25f * len_squared(bbox_max - centroid)); const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); const float theta_i = fast_acosf(dot(point_to_centroid, N)); @@ -51,17 +54,15 @@ ccl_device float light_tree_node_importance(const float3 P, /* to-do: compare this with directly using fmaxf and cosf. */ /* Avoid using cosine until needed. */ - const float theta_prime = fmaxf(theta_i - theta_u, 0); - /* to-do: this is also a rough heuristic to see if any contribution is possible. - * In the paper, this is only theta_e, but this seems to be off for point lights. */ - if (theta_prime >= theta_o + theta_e) { + const float theta_prime = fmaxf(theta - theta_o - theta_u, 0); + if (theta_prime >= theta_e) { return 0; } - const float cos_theta_prime = cosf(theta_prime); + const float cos_theta_prime = fast_cosf(theta_prime); float cos_theta_i_prime = 1; - if (theta - theta_o - theta_u > 0) { -cos_theta_i_prime = fabsf(cosf(theta - theta_o - theta_u)); + if (theta_i - theta_u > 0) { +cos_theta_i_prime = fabsf(fast_cosf(theta_i - theta_u)); } /* to-do: find a good approximation for this value. */ @@ -160,11 +161,16 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const float left_probability = left_importance / (left_importance + right_importance); if (tree_u < left_probability) { + index = index + 1; knode = left; + tree_u = tree_u * (left_importance + right_importance) / left_importance; *pdf_factor *= left_probability; } else { + index = knode->child_index; knode = right; + tree_u = (tree_u * (left_importance + right_importance) - left_importance) / + right_importance; *pdf_factor *= (1 - left_probability); } } diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 86a235815c7..aa04bf4986c 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -352,6 +352,7 @@ void LightManager::device_update_distribution(Device *, for (int index = 0; index < linearized_bvh.size(); index++) { const PackedLightTreeNode = linearized_bvh[index]; + light_tree_nodes[index].energy = node.energy; for (int i = 0; i < 3; i++) { light_tree_nodes[index].bounding_box_min[i] = node.bbox.min[i]; light_tree_nodes[index].bounding_box_max[i] = node.bbox.max[i]; @@ -536,6 +537,7 @@ void LightManager::device_update_distribution(Device *, * the light has been sampled through the light distribution. * Therefore, we override it for now and adjust the pdf manually in the light tree.*/ if (scene->integrator->get_use_light_tree()) { + kintegrator->pdf_triangles = 1.0f; kintegrator->pdf_lights = 1.0f; } else { diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 35c3d11104e..d50f257e6c7 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -37,9 +37,9 @@ OrientationBounds merge(const
[Bf-blender-cvs] [1d22a45de0f] soc-2022-many-lights-sampling: Cycles: set pdf_lights based on light sampling
Commit: 1d22a45de0fc7d499b73d7e0fb02e851cf048316 Author: Jeffrey Liu Date: Fri Jun 17 03:14:45 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB1d22a45de0fc7d499b73d7e0fb02e851cf048316 Cycles: set pdf_lights based on light sampling === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 4d62365d23e..7cff13b7c97 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -169,15 +169,6 @@ ccl_device bool light_tree_sample(KernelGlobals kg, } } - /* Special case where there's only a single light. */ - if (knode->num_prims == 1) { -if (UNLIKELY(light_select_reached_max_bounces(kg, -knode->child_index, bounce))) { - return false; -} -return light_sample( -kg, -knode->child_index, randu, randv, P, path_flag, ls); - } - /* Right now, sampling is done by incrementing the CDF by the PDF. * However, we first need to calculate the total importance so that we can normalize the CDF. */ float total_emitter_importance = 0.0f; @@ -196,15 +187,12 @@ ccl_device bool light_tree_sample(KernelGlobals kg, float emitter_cdf = 0.0f; for (int i = 0; i < knode->num_prims; i++) { const int prim_index = -knode->child_index + i; -/* to-do: is there any way to cache these values, so that recalculation isn't needed? - * At the very least, we can maybe store the total importance during light tree construction - * so that the first for loop isn't necessary. */ +/* to-do: is there any way to cache these values, so that recalculation isn't needed? */ const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) * inv_total_importance; emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; - assert(*pdf_factor != 0.0f); if (UNLIKELY(light_select_reached_max_bounces(kg, prim_index, bounce))) { return false; } diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 3a6d43aa8e9..86a235815c7 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -532,16 +532,24 @@ void LightManager::device_update_distribution(Device *, /* to-do: this pdf is probably going to need adjustment if a light tree is used. */ kintegrator->num_all_lights = num_lights; -if (trianglearea > 0.0f) { - kintegrator->pdf_triangles = 1.0f / trianglearea; - if (num_lights) -kintegrator->pdf_triangles *= 0.5f; +/* pdf_lights is used when sampling lights, and assumes that + * the light has been sampled through the light distribution. + * Therefore, we override it for now and adjust the pdf manually in the light tree.*/ +if (scene->integrator->get_use_light_tree()) { + kintegrator->pdf_lights = 1.0f; } +else { + if (trianglearea > 0.0f) { +kintegrator->pdf_triangles = 1.0f / trianglearea; +if (num_lights) + kintegrator->pdf_triangles *= 0.5f; + } -if (num_lights) { - kintegrator->pdf_lights = 1.0f / num_lights; - if (trianglearea > 0.0f) -kintegrator->pdf_lights *= 0.5f; + if (num_lights) { +kintegrator->pdf_lights = 1.0f / num_lights; +if (trianglearea > 0.0f) + kintegrator->pdf_lights *= 0.5f; + } } kintegrator->use_lamp_mis = use_lamp_mis; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5f9cebe6189] soc-2022-many-lights-sampling: Cycles: update light tree importance and correct normals/position args
Commit: 5f9cebe618922608c6f310cb7012bb9c0089c49d Author: Jeffrey Liu Date: Thu Jun 16 14:14:58 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5f9cebe618922608c6f310cb7012bb9c0089c49d Cycles: update light tree importance and correct normals/position args === M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index d08ddca2291..c77ca9431df 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -117,7 +117,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, if (kg->__data.integrator.use_light_tree) { if (!light_tree_sample_from_position( - kg, rng_state, light_u, light_v, sd->time, sd->N, sd->P, bounce, path_flag, )) { + kg, rng_state, light_u, light_v, sd->time, sd->P, sd->N, bounce, path_flag, )) { return; } } diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 839653faa44..4d62365d23e 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -4,12 +4,28 @@ CCL_NAMESPACE_BEGIN -ccl_device float light_tree_bounding_box_angle(KernelGlobals kg, - const float3 bbox_min, +ccl_device float light_tree_bounding_box_angle(const float3 bbox_min, const float3 bbox_max, - const float3 P) + const float3 P, + const float3 point_to_centroid) { - return 0; + /* Want to iterate through all 8 possible points of the bounding box. */ + float theta_u = 0; + float3 corners[8]; + corners[0] = bbox_min; + corners[1] = make_float3(bbox_min.x, bbox_min.y, bbox_max.z); + corners[2] = make_float3(bbox_min.x, bbox_max.y, bbox_min.z); + corners[3] = make_float3(bbox_min.x, bbox_max.y, bbox_max.z); + corners[4] = make_float3(bbox_max.x, bbox_min.y, bbox_min.z); + corners[5] = make_float3(bbox_max.x, bbox_min.y, bbox_max.z); + corners[6] = make_float3(bbox_max.x, bbox_max.y, bbox_min.z); + corners[7] = bbox_max; + for (int i = 0; i < 8; ++i) { +float3 point_to_corner = normalize(P - corners[i]); +const float cos_theta_u = dot(point_to_centroid, point_to_corner); +theta_u = fmaxf(fast_acosf(cos_theta_u), theta_u); + } + return theta_u; } /* This is the general function for calculating the importance of either a cluster or an emitter. @@ -25,14 +41,13 @@ ccl_device float light_tree_node_importance(const float3 P, const float energy) { const float3 centroid = 0.5f * bbox_min + 0.5f * bbox_max; - const float3 point_to_centroid = P - centroid; - const float3 point_to_bbox_max = P - bbox_max; + const float3 point_to_centroid = normalize(P - centroid); - const float distance_squared = len_squared(point_to_centroid); + const float distance_squared = len_squared(P - centroid); const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); const float theta_i = fast_acosf(dot(point_to_centroid, N)); - const float theta_u = fast_acosf(dot(point_to_centroid, point_to_bbox_max)); + const float theta_u = light_tree_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid); /* to-do: compare this with directly using fmaxf and cosf. */ /* Avoid using cosine until needed. */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [9ca7fb885e7] soc-2022-many-lights-sampling: Cycles: fix logic to support multiple point lights in tree
Commit: 9ca7fb885e7f090fd29fa1c166ba089a9150ba6b Author: Jeffrey Liu Date: Thu Jun 16 05:53:22 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB9ca7fb885e7f090fd29fa1c166ba089a9150ba6b Cycles: fix logic to support multiple point lights in tree === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light_tree.cpp M release/scripts/addons === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index cf3ffa18497..839653faa44 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -156,6 +156,9 @@ ccl_device bool light_tree_sample(KernelGlobals kg, /* Special case where there's only a single light. */ if (knode->num_prims == 1) { +if (UNLIKELY(light_select_reached_max_bounces(kg, -knode->child_index, bounce))) { + return false; +} return light_sample( kg, -knode->child_index, randu, randv, P, path_flag, ls); } @@ -187,6 +190,9 @@ ccl_device bool light_tree_sample(KernelGlobals kg, if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; assert(*pdf_factor != 0.0f); + if (UNLIKELY(light_select_reached_max_bounces(kg, prim_index, bounce))) { +return false; + } return light_sample(kg, prim_index, randu, randv, P, path_flag, ls); } } diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index ef5317f2bd1..35c3d11104e 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -177,14 +177,15 @@ LightTreeBuildNode *LightTree::recursive_build(vector /* Var(X) = E[X^2] - E[X]^2 */ float energy_variance = (energy_squared_total / num_prims) - (energy_total / num_prims) * (energy_total / num_prims); - if (num_prims == 1) { + /* to-do: find a better way to handle when all centroids overlap. */ + if (num_prims == 1 || centroid_bounds.area() == 0.0f) { int first_prim_offset = ordered_prims.size(); /* to-do: reduce this? */ for (int i = start; i < end; i++) { int prim_num = primitive_info[i].prim_num; ordered_prims.push_back(prims_[prim_num]); } -node->init_leaf(start, num_prims, node_bbox, node_bcone, energy_total, energy_variance); +node->init_leaf(first_prim_offset, num_prims, node_bbox, node_bcone, energy_total, energy_variance); } else { /* Find the best place to split the primitives into 2 nodes. @@ -239,7 +240,7 @@ LightTreeBuildNode *LightTree::recursive_build(vector int prim_num = primitive_info[i].prim_num; ordered_prims.push_back(prims_[prim_num]); } - node->init_leaf(start, num_prims, node_bbox, node_bcone, energy_total, energy_variance); + node->init_leaf(first_prim_offset, num_prims, node_bbox, node_bcone, energy_total, energy_variance); } } @@ -263,6 +264,11 @@ void LightTree::split_saoh(const BoundBox _bbox, /* Check each dimension to find the minimum splitting cost. */ min_cost = FLT_MAX; for (int dim = 0; dim < 3; dim++) { +/* If the centroid bounding box is 0 along a given dimension, skip it. */ +if (centroid_bbox.size()[dim] == 0.0f) { + continue; +} + const float inv_extent = 1 / (centroid_bbox.size()[dim]); /* Fill in buckets with primitives. */ diff --git a/release/scripts/addons b/release/scripts/addons index c51e0bb1793..ebe0bd5677a 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit c51e0bb1793c44c7a1b7435593dd5022cf7c8eec +Subproject commit ebe0bd5677af5810972feb212a027b2a30f1ee6a ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [3f1e3d2dfa6] soc-2022-many-lights-sampling: Cycles: handle case where light tree importance is 0
Commit: 3f1e3d2dfa61e784c978a1d7931c1bec8be1e9ff Author: Jeffrey Liu Date: Wed Jun 15 10:24:20 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB3f1e3d2dfa61e784c978a1d7931c1bec8be1e9ff Cycles: handle case where light tree importance is 0 === M intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index c5f1f52f05e..cf3ffa18497 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -154,8 +154,13 @@ ccl_device bool light_tree_sample(KernelGlobals kg, } } - /* Once we're at a leaf node, we can sample from the cluster of primitives inside. - * Right now, this is done by incrementing the CDF by the PDF. + /* Special case where there's only a single light. */ + if (knode->num_prims == 1) { +return light_sample( +kg, -knode->child_index, randu, randv, P, path_flag, ls); + } + + /* Right now, sampling is done by incrementing the CDF by the PDF. * However, we first need to calculate the total importance so that we can normalize the CDF. */ float total_emitter_importance = 0.0f; for (int i = 0; i < knode->num_prims; i++) { @@ -163,12 +168,11 @@ ccl_device bool light_tree_sample(KernelGlobals kg, total_emitter_importance += light_tree_emitter_importance(kg, P, N, prim_index); } - /* to-do: need to handle a case when total importance is 0.*/ + /* to-do: need to handle a case when total importance is 0. */ if (total_emitter_importance == 0.0f) { - +return false; } - /* Once we have the total importance, we can normalize the CDF and sample it. */ const float inv_total_importance = 1 / total_emitter_importance; float emitter_cdf = 0.0f; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [2c101527c1b] soc-2022-many-lights-sampling: Cycles: support single point light rendering in light tree
Commit: 2c101527c1bf5583dca0b2a3358a9010e7e259bb Author: Jeffrey Liu Date: Wed Jun 15 03:26:33 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB2c101527c1bf5583dca0b2a3358a9010e7e259bb Cycles: support single point light rendering in light tree === M intern/cycles/kernel/light/light_tree.h M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h index 19e57c88152..c5f1f52f05e 100644 --- a/intern/cycles/kernel/light/light_tree.h +++ b/intern/cycles/kernel/light/light_tree.h @@ -37,7 +37,9 @@ ccl_device float light_tree_node_importance(const float3 P, /* to-do: compare this with directly using fmaxf and cosf. */ /* Avoid using cosine until needed. */ const float theta_prime = fmaxf(theta_i - theta_u, 0); - if (theta_prime >= theta_e) { + /* to-do: this is also a rough heuristic to see if any contribution is possible. + * In the paper, this is only theta_e, but this seems to be off for point lights. */ + if (theta_prime >= theta_o + theta_e) { return 0; } const float cos_theta_prime = cosf(theta_prime); @@ -127,6 +129,7 @@ ccl_device bool light_tree_sample(KernelGlobals kg, /* Also keep track of the probability of traversing to a given node, */ /* so that we can scale our PDF accordingly later. */ int index = 0; + *pdf_factor = 1.0f; /* to-do: is it better to generate a new random sample for each step of the traversal? */ float tree_u = path_state_rng_1D(kg, rng_state, 1); @@ -137,8 +140,8 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const ccl_global KernelLightTreeNode *left = _tex_fetch(__light_tree_nodes, index + 1); const ccl_global KernelLightTreeNode *right = _tex_fetch(__light_tree_nodes, knode->child_index); -const float left_importance{light_tree_cluster_importance(kg, P, N, left)}; -const float right_importance{light_tree_cluster_importance(kg, P, N, right)}; +const float left_importance = light_tree_cluster_importance(kg, P, N, left); +const float right_importance = light_tree_cluster_importance(kg, P, N, right); const float left_probability = left_importance / (left_importance + right_importance); if (tree_u < left_probability) { @@ -159,20 +162,27 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const int prim_index = -knode->child_index + i; total_emitter_importance += light_tree_emitter_importance(kg, P, N, prim_index); } - const float inv_total_importance = 1 / total_emitter_importance; + + /* to-do: need to handle a case when total importance is 0.*/ + if (total_emitter_importance == 0.0f) { + + } /* Once we have the total importance, we can normalize the CDF and sample it. */ + const float inv_total_importance = 1 / total_emitter_importance; float emitter_cdf = 0.0f; for (int i = 0; i < knode->num_prims; i++) { const int prim_index = -knode->child_index + i; /* to-do: is there any way to cache these values, so that recalculation isn't needed? * At the very least, we can maybe store the total importance during light tree construction * so that the first for loop isn't necessary. */ -const float emitter_pdf{light_tree_emitter_importance(kg, P, N, prim_index)}; -emitter_cdf += emitter_pdf * inv_total_importance; +const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) * + inv_total_importance; +emitter_cdf += emitter_pdf; if (tree_u < emitter_cdf) { *pdf_factor *= emitter_pdf; + assert(*pdf_factor != 0.0f); return light_sample(kg, prim_index, randu, randv, P, path_flag, ls); } } @@ -195,6 +205,7 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg, float pdf_factor; bool ret = light_tree_sample( kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, _factor); + assert(pdf_factor != 0.0f); ls->pdf *= pdf_factor; return ret; } diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 8ae86443150..ef5317f2bd1 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -118,7 +118,7 @@ LightTree::LightTree(const vector , Scene *scene, uint scene_ = scene; max_lights_in_leaf_ = max_lights_in_leaf; - vector build_data(prims.size()); + vector build_data; for (int i = 0; i < prims.size(); i++) { LightTreePrimitiveInfo prim_info; prim_info.bbox = prims[i].calculate_bbox(scene); @@ -235,7 +235,6 @@ LightTreeBuildNode *LightTree::recursive_build(vector } else { int first_prim_offset = ordered_prims.size(); - /* to-do: reduce this? */ for (int i = start; i < end; i++) { int p
[Bf-blender-cvs] [3a911692769] soc-2022-many-lights-sampling: Cleanup: remove CRLF from textures.h
Commit: 3a911692769ec1130e976be40c63cf2e93efdf6b Author: Jeffrey Liu Date: Tue Jun 14 02:07:51 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB3a911692769ec1130e976be40c63cf2e93efdf6b Cleanup: remove CRLF from textures.h === M intern/cycles/kernel/textures.h === diff --git a/intern/cycles/kernel/textures.h b/intern/cycles/kernel/textures.h index e15e7cbf01e..a3aeb325f88 100644 --- a/intern/cycles/kernel/textures.h +++ b/intern/cycles/kernel/textures.h @@ -1,85 +1,85 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#ifndef KERNEL_TEX -# define KERNEL_TEX(type, name) -#endif - -/* BVH2, not used for OptiX or Embree. */ -KERNEL_TEX(float4, __bvh_nodes) -KERNEL_TEX(float4, __bvh_leaf_nodes) -KERNEL_TEX(uint, __prim_type) -KERNEL_TEX(uint, __prim_visibility) -KERNEL_TEX(uint, __prim_index) -KERNEL_TEX(uint, __prim_object) -KERNEL_TEX(uint, __object_node) -KERNEL_TEX(float2, __prim_time) - -/* objects */ -KERNEL_TEX(KernelObject, __objects) -KERNEL_TEX(Transform, __object_motion_pass) -KERNEL_TEX(DecomposedTransform, __object_motion) -KERNEL_TEX(uint, __object_flag) -KERNEL_TEX(float, __object_volume_step) -KERNEL_TEX(uint, __object_prim_offset) - -/* cameras */ -KERNEL_TEX(DecomposedTransform, __camera_motion) - -/* triangles */ -KERNEL_TEX(uint, __tri_shader) -KERNEL_TEX(packed_float3, __tri_vnormal) -KERNEL_TEX(uint4, __tri_vindex) -KERNEL_TEX(uint, __tri_patch) -KERNEL_TEX(float2, __tri_patch_uv) -KERNEL_TEX(packed_float3, __tri_verts) - -/* curves */ -KERNEL_TEX(KernelCurve, __curves) -KERNEL_TEX(float4, __curve_keys) -KERNEL_TEX(KernelCurveSegment, __curve_segments) - -/* patches */ -KERNEL_TEX(uint, __patches) - -/* pointclouds */ -KERNEL_TEX(float4, __points) -KERNEL_TEX(uint, __points_shader) - -/* attributes */ -KERNEL_TEX(uint4, __attributes_map) -KERNEL_TEX(float, __attributes_float) -KERNEL_TEX(float2, __attributes_float2) -KERNEL_TEX(packed_float3, __attributes_float3) -KERNEL_TEX(float4, __attributes_float4) -KERNEL_TEX(uchar4, __attributes_uchar4) - -/* lights */ -KERNEL_TEX(KernelLightDistribution, __light_distribution) -KERNEL_TEX(KernelLight, __lights) -KERNEL_TEX(float2, __light_background_marginal_cdf) -KERNEL_TEX(float2, __light_background_conditional_cdf) - -/* light tree */ -KERNEL_TEX(KernelLightTreeNode, __light_tree_nodes) - -/* particles */ -KERNEL_TEX(KernelParticle, __particles) - -/* shaders */ -KERNEL_TEX(uint4, __svm_nodes) -KERNEL_TEX(KernelShader, __shaders) - -/* lookup tables */ -KERNEL_TEX(float, __lookup_table) - -/* sobol */ -KERNEL_TEX(float, __sample_pattern_lut) - -/* image textures */ -KERNEL_TEX(TextureInfo, __texture_info) - -/* ies lights */ -KERNEL_TEX(float, __ies) - -#undef KERNEL_TEX +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#ifndef KERNEL_TEX +# define KERNEL_TEX(type, name) +#endif + +/* BVH2, not used for OptiX or Embree. */ +KERNEL_TEX(float4, __bvh_nodes) +KERNEL_TEX(float4, __bvh_leaf_nodes) +KERNEL_TEX(uint, __prim_type) +KERNEL_TEX(uint, __prim_visibility) +KERNEL_TEX(uint, __prim_index) +KERNEL_TEX(uint, __prim_object) +KERNEL_TEX(uint, __object_node) +KERNEL_TEX(float2, __prim_time) + +/* objects */ +KERNEL_TEX(KernelObject, __objects) +KERNEL_TEX(Transform, __object_motion_pass) +KERNEL_TEX(DecomposedTransform, __object_motion) +KERNEL_TEX(uint, __object_flag) +KERNEL_TEX(float, __object_volume_step) +KERNEL_TEX(uint, __object_prim_offset) + +/* cameras */ +KERNEL_TEX(DecomposedTransform, __camera_motion) + +/* triangles */ +KERNEL_TEX(uint, __tri_shader) +KERNEL_TEX(packed_float3, __tri_vnormal) +KERNEL_TEX(uint4, __tri_vindex) +KERNEL_TEX(uint, __tri_patch) +KERNEL_TEX(float2, __tri_patch_uv) +KERNEL_TEX(packed_float3, __tri_verts) + +/* curves */ +KERNEL_TEX(KernelCurve, __curves) +KERNEL_TEX(float4, __curve_keys) +KERNEL_TEX(KernelCurveSegment, __curve_segments) + +/* patches */ +KERNEL_TEX(uint, __patches) + +/* pointclouds */ +KERNEL_TEX(float4, __points) +KERNEL_TEX(uint, __points_shader) + +/* attributes */ +KERNEL_TEX(uint4, __attributes_map) +KERNEL_TEX(float, __attributes_float) +KERNEL_TEX(float2, __attributes_float2) +KERNEL_TEX(packed_float3, __attributes_float3) +KERNEL_TEX(float4, __attributes_float4) +KERNEL_TEX(uchar4, __attributes_uchar4) + +/* lights */ +KERNEL_TEX(KernelLightDistribution, __light_distribution) +KERNEL_TEX(KernelLight, __lights) +KERNEL_TEX(float2, __light_background_marginal_cdf) +KERNEL_TEX(float2, __light_background_conditional_cdf) + +/* light tree */ +KERNEL_TEX(KernelLightTreeNode, __light_tree_nodes) + +/* particles */ +KERNEL_TEX(KernelParticle, __particles) + +/* shaders */ +KERNEL_TEX(uint4, __svm_nodes) +KERNEL_TEX(KernelShader, __shaders) + +/* lookup tables */ +KERNEL_TEX(float, __lookup_table) + +/* sobol */ +KERNEL_TEX(float
[Bf-blender-cvs] [b2172a53c0d] soc-2022-many-lights-sampling: Cycles: add light bvh for access through device kernel
Commit: b2172a53c0d12a454b51f62811c59bf4d474d8da Author: Jeffrey Liu Date: Fri Jun 10 19:41:59 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBb2172a53c0d12a454b51f62811c59bf4d474d8da Cycles: add light bvh for access through device kernel === M intern/cycles/kernel/textures.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light.h M intern/cycles/scene/light_tree.cpp M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/kernel/textures.h b/intern/cycles/kernel/textures.h index 7deb589a0a9..e15e7cbf01e 100644 --- a/intern/cycles/kernel/textures.h +++ b/intern/cycles/kernel/textures.h @@ -1,82 +1,85 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#ifndef KERNEL_TEX -# define KERNEL_TEX(type, name) -#endif - -/* BVH2, not used for OptiX or Embree. */ -KERNEL_TEX(float4, __bvh_nodes) -KERNEL_TEX(float4, __bvh_leaf_nodes) -KERNEL_TEX(uint, __prim_type) -KERNEL_TEX(uint, __prim_visibility) -KERNEL_TEX(uint, __prim_index) -KERNEL_TEX(uint, __prim_object) -KERNEL_TEX(uint, __object_node) -KERNEL_TEX(float2, __prim_time) - -/* objects */ -KERNEL_TEX(KernelObject, __objects) -KERNEL_TEX(Transform, __object_motion_pass) -KERNEL_TEX(DecomposedTransform, __object_motion) -KERNEL_TEX(uint, __object_flag) -KERNEL_TEX(float, __object_volume_step) -KERNEL_TEX(uint, __object_prim_offset) - -/* cameras */ -KERNEL_TEX(DecomposedTransform, __camera_motion) - -/* triangles */ -KERNEL_TEX(uint, __tri_shader) -KERNEL_TEX(packed_float3, __tri_vnormal) -KERNEL_TEX(uint4, __tri_vindex) -KERNEL_TEX(uint, __tri_patch) -KERNEL_TEX(float2, __tri_patch_uv) -KERNEL_TEX(packed_float3, __tri_verts) - -/* curves */ -KERNEL_TEX(KernelCurve, __curves) -KERNEL_TEX(float4, __curve_keys) -KERNEL_TEX(KernelCurveSegment, __curve_segments) - -/* patches */ -KERNEL_TEX(uint, __patches) - -/* pointclouds */ -KERNEL_TEX(float4, __points) -KERNEL_TEX(uint, __points_shader) - -/* attributes */ -KERNEL_TEX(uint4, __attributes_map) -KERNEL_TEX(float, __attributes_float) -KERNEL_TEX(float2, __attributes_float2) -KERNEL_TEX(packed_float3, __attributes_float3) -KERNEL_TEX(float4, __attributes_float4) -KERNEL_TEX(uchar4, __attributes_uchar4) - -/* lights */ -KERNEL_TEX(KernelLightDistribution, __light_distribution) -KERNEL_TEX(KernelLight, __lights) -KERNEL_TEX(float2, __light_background_marginal_cdf) -KERNEL_TEX(float2, __light_background_conditional_cdf) - -/* particles */ -KERNEL_TEX(KernelParticle, __particles) - -/* shaders */ -KERNEL_TEX(uint4, __svm_nodes) -KERNEL_TEX(KernelShader, __shaders) - -/* lookup tables */ -KERNEL_TEX(float, __lookup_table) - -/* sobol */ -KERNEL_TEX(float, __sample_pattern_lut) - -/* image textures */ -KERNEL_TEX(TextureInfo, __texture_info) - -/* ies lights */ -KERNEL_TEX(float, __ies) - -#undef KERNEL_TEX +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#ifndef KERNEL_TEX +# define KERNEL_TEX(type, name) +#endif + +/* BVH2, not used for OptiX or Embree. */ +KERNEL_TEX(float4, __bvh_nodes) +KERNEL_TEX(float4, __bvh_leaf_nodes) +KERNEL_TEX(uint, __prim_type) +KERNEL_TEX(uint, __prim_visibility) +KERNEL_TEX(uint, __prim_index) +KERNEL_TEX(uint, __prim_object) +KERNEL_TEX(uint, __object_node) +KERNEL_TEX(float2, __prim_time) + +/* objects */ +KERNEL_TEX(KernelObject, __objects) +KERNEL_TEX(Transform, __object_motion_pass) +KERNEL_TEX(DecomposedTransform, __object_motion) +KERNEL_TEX(uint, __object_flag) +KERNEL_TEX(float, __object_volume_step) +KERNEL_TEX(uint, __object_prim_offset) + +/* cameras */ +KERNEL_TEX(DecomposedTransform, __camera_motion) + +/* triangles */ +KERNEL_TEX(uint, __tri_shader) +KERNEL_TEX(packed_float3, __tri_vnormal) +KERNEL_TEX(uint4, __tri_vindex) +KERNEL_TEX(uint, __tri_patch) +KERNEL_TEX(float2, __tri_patch_uv) +KERNEL_TEX(packed_float3, __tri_verts) + +/* curves */ +KERNEL_TEX(KernelCurve, __curves) +KERNEL_TEX(float4, __curve_keys) +KERNEL_TEX(KernelCurveSegment, __curve_segments) + +/* patches */ +KERNEL_TEX(uint, __patches) + +/* pointclouds */ +KERNEL_TEX(float4, __points) +KERNEL_TEX(uint, __points_shader) + +/* attributes */ +KERNEL_TEX(uint4, __attributes_map) +KERNEL_TEX(float, __attributes_float) +KERNEL_TEX(float2, __attributes_float2) +KERNEL_TEX(packed_float3, __attributes_float3) +KERNEL_TEX(float4, __attributes_float4) +KERNEL_TEX(uchar4, __attributes_uchar4) + +/* lights */ +KERNEL_TEX(KernelLightDistribution, __light_distribution) +KERNEL_TEX(KernelLight, __lights) +KERNEL_TEX(float2, __light_background_marginal_cdf) +KERNEL_TEX(float2, __light_background_conditional_cdf) + +/* light tree */ +KERNEL_TEX(KernelLightTreeNode, __light_tree_nodes) + +/* particles */ +KERNEL_TEX(KernelParticle, __particles) + +/* shaders */ +KERNEL_TEX(uint4, __svm_nodes) +KERNEL_TEX(KernelShader, __shaders
[Bf-blender-cvs] [ef7d2d931a5] soc-2022-many-lights-sampling: Cycles: integrate light tree sampling into device kernel (WIP)
Commit: ef7d2d931a5ead8ea983f8ad4cfb48734a6c6e21 Author: Jeffrey Liu Date: Tue Jun 14 01:58:42 2022 -0400 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBef7d2d931a5ead8ea983f8ad4cfb48734a6c6e21 Cycles: integrate light tree sampling into device kernel (WIP) === M intern/cycles/kernel/CMakeLists.txt M intern/cycles/kernel/integrator/shade_surface.h A intern/cycles/kernel/light/light_tree.h === diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 473bdb67920..c1279bfba51 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -246,6 +246,7 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS set(SRC_KERNEL_LIGHT_HEADERS light/light.h + light/light_tree.h light/background.h light/common.h light/sample.h diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index ce1398859b7..d08ddca2291 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -14,6 +14,7 @@ #include "kernel/integrator/volume_stack.h" #include "kernel/light/light.h" +#include "kernel/light/light_tree.h" #include "kernel/light/sample.h" CCL_NAMESPACE_BEGIN @@ -114,9 +115,17 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, float light_u, light_v; path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, _u, _v); -if (!light_distribution_sample_from_position( -kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, )) { - return; +if (kg->__data.integrator.use_light_tree) { + if (!light_tree_sample_from_position( + kg, rng_state, light_u, light_v, sd->time, sd->N, sd->P, bounce, path_flag, )) { +return; + } +} +else { + if (!light_distribution_sample_from_position( + kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, )) { +return; + } } } diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h new file mode 100644 index 000..19e57c88152 --- /dev/null +++ b/intern/cycles/kernel/light/light_tree.h @@ -0,0 +1,202 @@ +#pragma once + +#include "kernel/light/light.h" + +CCL_NAMESPACE_BEGIN + +ccl_device float light_tree_bounding_box_angle(KernelGlobals kg, + const float3 bbox_min, + const float3 bbox_max, + const float3 P) +{ + return 0; +} + +/* This is the general function for calculating the importance of either a cluster or an emitter. + * Both of the specialized functions obtain the necessary data before calling this function. + * to-do: find a better way to handle this? */ +ccl_device float light_tree_node_importance(const float3 P, +const float3 N, +const float3 bbox_min, +const float3 bbox_max, +const float3 bcone_axis, +const float theta_o, +const float theta_e, +const float energy) +{ + const float3 centroid = 0.5f * bbox_min + 0.5f * bbox_max; + const float3 point_to_centroid = P - centroid; + const float3 point_to_bbox_max = P - bbox_max; + + const float distance_squared = len_squared(point_to_centroid); + + const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid)); + const float theta_i = fast_acosf(dot(point_to_centroid, N)); + const float theta_u = fast_acosf(dot(point_to_centroid, point_to_bbox_max)); + + /* to-do: compare this with directly using fmaxf and cosf. */ + /* Avoid using cosine until needed. */ + const float theta_prime = fmaxf(theta_i - theta_u, 0); + if (theta_prime >= theta_e) { +return 0; + } + const float cos_theta_prime = cosf(theta_prime); + + float cos_theta_i_prime = 1; + if (theta - theta_o - theta_u > 0) { +cos_theta_i_prime = fabsf(cosf(theta - theta_o - theta_u)); + } + + /* to-do: find a good approximation for this value. */ + const float f_a = 1; + + float importance = f_a * cos_theta_i_prime * energy / distance_squared * cos_theta_prime; + return importance; +} + +ccl_device float light_tree_emitter_importance(KernelGlobals kg, + const float3 P, + const float3 N, + int emitter_index) +{ + ccl_global