[Bf-blender-cvs] [00b90ede1b8] gsoc-2018-many-light-sampling: Cycles: Light tree related bug fixes
Erik Englesson
noreply at git.blender.org
Fri Jul 27 18:19:48 CEST 2018
Commit: 00b90ede1b8cba0d47a4cdc7c6d48f49ed15d677
Author: Erik Englesson
Date: Mon Jul 23 16:05:04 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rB00b90ede1b8cba0d47a4cdc7c6d48f49ed15d677
Cycles: Light tree related bug fixes
- Fixed bug in triangle_light_pdf_area() from PDF refactor
- Early exit if picking prob is zero in tree traversal
- The background index is now an index into the lights
array instead of the distribution array.
===================================================================
M intern/cycles/kernel/kernel_light.h
M intern/cycles/render/light.cpp
===================================================================
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 0d576b60540..56f4e9e0c72 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -805,14 +805,14 @@ ccl_device_inline bool triangle_world_space_vertices(KernelGlobals *kg, int obje
return has_motion;
}
-ccl_device_inline float triangle_light_pdf_area(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
+ccl_device_inline float triangle_light_pdf_area(KernelGlobals *kg, const float3 Ng, const float3 I, float t, float triangle_area)
{
float cos_pi = fabsf(dot(Ng, I));
if(cos_pi == 0.0f)
return 0.0f;
- return t*t/cos_pi;
+ return t*t/(cos_pi * triangle_area);
}
ccl_device_forceinline float triangle_light_pdf(KernelGlobals *kg, ShaderData *sd, float t)
@@ -822,7 +822,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals *kg, ShaderData *s
* to the length of the edges of the triangle. */
float3 V[3];
- bool has_motion = triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V);
+ triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V);
const float3 e0 = V[1] - V[0];
const float3 e1 = V[2] - V[0];
@@ -853,35 +853,12 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals *kg, ShaderData *s
return 0.0f;
}
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);
- }
- const float pdf = area * kernel_data.integrator.pdf_triangles;
- return pdf / solid_angle;
+ return 1.0f / solid_angle;
}
}
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;
- }
- /* 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 = triangle_area(V[0], V[1], V[2]);
- pdf = pdf * area_pre / area;
- }
-
- return pdf;
+ const float area = 0.5f * len(N);
+ return triangle_light_pdf_area(kg, sd->Ng, sd->I, t, area);
}
}
@@ -1011,7 +988,8 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg, int prim, i
ls->P = u * V[0] + v * V[1] + t * V[2];
/* compute incoming direction, distance and pdf */
ls->D = normalize_len(ls->P - P, &ls->t);
- ls->pdf = triangle_light_pdf_area(kg, ls->Ng, -ls->D, ls->t);
+ float area = 0.5f * Nl;
+ ls->pdf = triangle_light_pdf_area(kg, ls->Ng, -ls->D, ls->t, area);
ls->u = u;
ls->v = v;
@@ -1556,6 +1534,11 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg,
float pdf_factor = 0.0f;
int index = -1;
light_distribution_sample(kg, P, N, &randu, &index, &pdf_factor);
+
+ if(pdf_factor == 0.0f){
+ return false;
+ }
+
light_point_sample(kg, randu, randv, time, P, bounce, index, ls);
/* combine pdfs */
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index fa3e7d32780..69c0dbcd15e 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -381,10 +381,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
int light_index = 0;
int light_id = 0;
+ int background_index = -1;
foreach(Light *light, scene->lights) {
if(light->is_enabled) {
emissivePrims.push_back(Primitive(~light_index, light_id));
num_lights++;
+ if(light->type == LIGHT_BACKGROUND){
+ background_index = light_index;
+ }
light_index++;
}
if(light->is_portal) {
@@ -646,7 +650,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
offset = 0;
/* create distributions for lights */
- int background_index = -1;
foreach (Primitive prim, emissivePrims){
if(progress.get_cancel()) return;
@@ -669,7 +672,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(light->type == LIGHT_BACKGROUND) {
num_background_lights++;
background_mis = light->use_mis;
- background_index = offset;
} else if(light->type == LIGHT_DISTANT){
num_distant_lights++;
}
More information about the Bf-blender-cvs
mailing list