Cycles: MIS for lamps now loops over all lamps instead of picking one.
Probably will not be noticed in most scenes. This helps reduce noise when you have multiple lamps with MIS enabled, at the cost of some performance, but from testing some scenes this seems better.
This commit is contained in:
@@ -183,16 +183,17 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
|
|||||||
|
|
||||||
/* Indirect Lamp Emission */
|
/* Indirect Lamp Emission */
|
||||||
|
|
||||||
ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float randt, float3 *emission)
|
ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission)
|
||||||
{
|
{
|
||||||
LightSample ls;
|
bool hit_lamp = false;
|
||||||
int lamp = lamp_light_eval_sample(kg, randt);
|
|
||||||
|
|
||||||
if(lamp == LAMP_NONE)
|
*emission = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
return false;
|
|
||||||
|
for(int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
|
||||||
|
LightSample ls;
|
||||||
|
|
||||||
if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
|
if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
|
||||||
return false;
|
continue;
|
||||||
|
|
||||||
#ifdef __PASSES__
|
#ifdef __PASSES__
|
||||||
/* use visibility flag to skip lights */
|
/* use visibility flag to skip lights */
|
||||||
@@ -200,7 +201,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st
|
|||||||
if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
|
if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
|
||||||
((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
|
((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
|
||||||
((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)))
|
((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)))
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -213,8 +214,11 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st
|
|||||||
L *= mis_weight;
|
L *= mis_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
*emission = L;
|
*emission += L;
|
||||||
return true;
|
hit_lamp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hit_lamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indirect Background */
|
/* Indirect Background */
|
||||||
|
@@ -421,7 +421,6 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
|
|||||||
/* compute pdf */
|
/* compute pdf */
|
||||||
if(ls->t != FLT_MAX)
|
if(ls->t != FLT_MAX)
|
||||||
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
|
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
|
||||||
ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -240,10 +240,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
|
|||||||
light_ray.dP = ray.dP;
|
light_ray.dP = ray.dP;
|
||||||
|
|
||||||
/* intersect with lamp */
|
/* intersect with lamp */
|
||||||
float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
|
|
||||||
float3 emission;
|
float3 emission;
|
||||||
|
|
||||||
if(indirect_lamp_emission(kg, &state, &light_ray, light_t, &emission))
|
if(indirect_lamp_emission(kg, &state, &light_ray, &emission))
|
||||||
path_radiance_accum_emission(L, throughput, emission, state.bounce);
|
path_radiance_accum_emission(L, throughput, emission, state.bounce);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -624,10 +623,9 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
|
|||||||
light_ray.dP = ray.dP;
|
light_ray.dP = ray.dP;
|
||||||
|
|
||||||
/* intersect with lamp */
|
/* intersect with lamp */
|
||||||
float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
|
|
||||||
float3 emission;
|
float3 emission;
|
||||||
|
|
||||||
if(indirect_lamp_emission(kg, &state, &light_ray, light_t, &emission))
|
if(indirect_lamp_emission(kg, &state, &light_ray, &emission))
|
||||||
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
|
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user