[Bf-blender-cvs] [bbf4c9d6475] soc-2022-many-lights-sampling: Cycles: update MIS calculations when light tree is enabled
Jeffrey Liu
noreply at git.blender.org
Sat Jul 9 06:57:06 CEST 2022
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/cycles/kernel/integrator/state_template.h
index e7e6db037b0..236855af5ec 100644
--- a/intern/cycles/kernel/integrator/state_template.h
+++ b/intern/cycles/kernel/integrator/state_template.h
@@ -42,6 +42,7 @@ KERNEL_STRUCT_MEMBER(path, uint8_t, mnee, KERNEL_FEATURE_PATH_TRACING)
* compute the complete distance through transparent surfaces and volumes. */
KERNEL_STRUCT_MEMBER(path, float, mis_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
KERNEL_STRUCT_MEMBER(path, float, mis_ray_t, KERNEL_FEATURE_PATH_TRACING)
+KERNEL_STRUCT_MEMBER(path, packed_float3, mis_origin_n, KERNEL_FEATURE_PATH_TRACING)
/* Filter glossy. */
KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
/* Continuation probability for path termination. */
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index 1e7a333d013..e9140298257 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -642,15 +642,17 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
}
else {
float area = 1.0f;
- if (has_motion) {
- /* get the center frame vertices, this is what the PDF was calculated from */
- triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
- area = triangle_area(V[0], V[1], V[2]);
- }
- else {
- area = 0.5f * len(N);
+ if (!kernel_data.integrator.use_light_tree) {
+ if (has_motion) {
+ /* get the center frame vertices, this is what the PDF was calculated from */
+ triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
+ area = triangle_area(V[0], V[1], V[2]);
+ }
+ else {
+ area = 0.5f * len(N);
+ }
}
- const float pdf = area * kernel_data.integrator.pdf_triangles;
+ float pdf = area * kernel_data.integrator.pdf_triangles;
return pdf / solid_angle;
}
}
@@ -665,9 +667,10 @@ ccl_device_forceinline float triangle_light_pdf(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, sd->object, sd->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]);
pdf = pdf * area_pre / area;
}
+
return pdf;
}
}
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index cf7e9c2ee18..4df1dd7adc7 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -206,28 +206,6 @@ ccl_device int light_tree_sample(KernelGlobals kg,
triangle_light_sample<in_volume_segment>(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);
}
@@ -350,7 +328,7 @@ ccl_device float light_tree_pdf(KernelGlobals kg, const float3 P, const float3 N
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) {
+ if (prim == emitter) {
emitter_importance = importance;
}
total_importance += importance;
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index fc43a1b735a..9def2e5690b 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -1229,8 +1229,11 @@ typedef struct KernelBackground {
int lightgroup;
+ /* index into lights array */
+ int light_index;
+
/* Padding */
- int pad1, pad2;
+ int pad1;
} KernelBackground;
static_assert_align(KernelBackground, 16);
diff --git a/intern/cycles/scene/background.cpp b/intern/cycles/scene/background.cpp
index bffc8895bfd..0779313e5ba 100644
--- a/intern/cycles/scene/background.cpp
+++ b/intern/cycles/scene/background.cpp
@@ -4,6 +4,7 @@
#include "scene/background.h"
#include "device/device.h"
#include "scene/integrator.h"
+#include "scene/light.h"
#include "scene/scene.h"
#include "scene/shader.h"
#include "scene/shader_graph.h"
@@ -103,6 +104,19 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
}
+ /* Find background index in lights. */
+ int device_light_index = 0;
+ int background_light_index = -1;
+ foreach (Light *light, scene->lights) {
+ if (light->get_is_enabled()) {
+ if (light->get_light_type() == LIGHT_BACKGROUND) {
+ background_light_index = device_light_index;
+ }
+ device_light_index++;
+ }
+ }
+ kbackground->light_index = background_light_index;
+
/* Light group. */
auto it = scene->lightgroups.find(lightgroup);
if (it != scene->lightgroups.end()) {
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index aeb8cd7a341..6278e3efd93 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -353,15 +353,16 @@ void LightManager::device_update_distribution(Device *device,
if (progress.get_cancel())
return;
+ /* Count emissive triangles. */
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list