Fix incorrect MIS weights in Cycles with multiple lights.

This causes some difference in the classroom scene, where ray visibility
tricks are used and break the MIS balance. Otherwise there doesn't seem
to be much effect, but better to use the right formulas. Problem originally
identified by Lukas.
This commit is contained in:
Brecht Van Lommel
2017-11-07 03:28:10 +01:00
parent 5f2be40658
commit e74b229342
3 changed files with 9 additions and 12 deletions

View File

@@ -547,7 +547,7 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
float costheta = dot(lightD, D); float costheta = dot(lightD, D);
ls->pdf = invarea/(costheta*costheta*costheta); ls->pdf = invarea/(costheta*costheta*costheta);
ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights; ls->eval_fac = ls->pdf;
} }
#ifdef __BACKGROUND_MIS__ #ifdef __BACKGROUND_MIS__
else if(type == LIGHT_BACKGROUND) { else if(type == LIGHT_BACKGROUND) {
@@ -559,7 +559,6 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
ls->D = -D; ls->D = -D;
ls->t = FLT_MAX; ls->t = FLT_MAX;
ls->eval_fac = 1.0f; ls->eval_fac = 1.0f;
ls->pdf *= kernel_data.integrator.pdf_lights;
} }
#endif #endif
else { else {
@@ -622,10 +621,10 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
float invarea = data2.x; float invarea = data2.x;
ls->eval_fac = 0.25f*invarea; ls->eval_fac = 0.25f*invarea;
} }
ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
} }
ls->pdf *= kernel_data.integrator.pdf_lights;
return (ls->pdf > 0.0f); return (ls->pdf > 0.0f);
} }
@@ -757,8 +756,11 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
ls->pdf = area_light_sample(P, &light_P, axisu, axisv, 0, 0, false); ls->pdf = area_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
ls->eval_fac = 0.25f*invarea; ls->eval_fac = 0.25f*invarea;
} }
else else {
return false; return false;
}
ls->pdf *= kernel_data.integrator.pdf_lights;
return true; return true;
} }

View File

@@ -1239,8 +1239,8 @@ typedef struct KernelIntegrator {
int num_all_lights; int num_all_lights;
float pdf_triangles; float pdf_triangles;
float pdf_lights; float pdf_lights;
float inv_pdf_lights;
int pdf_background_res; int pdf_background_res;
float light_inv_rr_threshold;
/* light portals */ /* light portals */
float portal_pdf; float portal_pdf;
@@ -1298,9 +1298,8 @@ typedef struct KernelIntegrator {
float volume_step_size; float volume_step_size;
int volume_samples; int volume_samples;
float light_inv_rr_threshold;
int start_sample; int start_sample;
int pad;
} KernelIntegrator; } KernelIntegrator;
static_assert_align(KernelIntegrator, 16); static_assert_align(KernelIntegrator, 16);

View File

@@ -414,7 +414,6 @@ void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Sce
/* precompute pdfs */ /* precompute pdfs */
kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f; kintegrator->pdf_lights = 0.0f;
kintegrator->inv_pdf_lights = 0.0f;
/* sample one, with 0.5 probability of light or triangle */ /* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = num_lights; kintegrator->num_all_lights = num_lights;
@@ -429,8 +428,6 @@ void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Sce
kintegrator->pdf_lights = 1.0f/num_lights; kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f) if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f; kintegrator->pdf_lights *= 0.5f;
kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
} }
kintegrator->use_lamp_mis = use_lamp_mis; kintegrator->use_lamp_mis = use_lamp_mis;
@@ -467,7 +464,6 @@ void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Sce
kintegrator->num_all_lights = 0; kintegrator->num_all_lights = 0;
kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f; kintegrator->pdf_lights = 0.0f;
kintegrator->inv_pdf_lights = 0.0f;
kintegrator->use_lamp_mis = false; kintegrator->use_lamp_mis = false;
kintegrator->num_portals = 0; kintegrator->num_portals = 0;
kintegrator->portal_offset = 0; kintegrator->portal_offset = 0;