I’m struggling to understand what needs to be done in shader_bsdf_sample
to convert the relevant closures to wavelength intensities.
I’m looking at the call to bsdf_sample, one of the functions I’m meant to be looking out for. It is passing in a pointer to a local variable called eval, which seems to be modified within bsdf_sample
as to be expected, but then upon return it is only multiplied with sc->weight
when passed in to bsdf_eval_init
which seems odd. Maybe I’m misunderstanding the purpose of that init function… Should I be converting eval * sc->weight
to wavelength intensities before passing it into bsdf_eval_init
? If so, could someone describe what the init function is actually for?
@brecht and @lukasstockner97 (as the most recent modifiers of this code)
Code for reference
// intern\cycles\kernel\kernel_shader.h:778
ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
ShaderData *sd,
float randu,
float randv,
BsdfEval *bsdf_eval,
float3 *omega_in,
differential3 *domega_in,
float *pdf,
float3 wavelengths)
{
PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
if (sc == NULL) {
*pdf = 0.0f;
return LABEL_NONE;
}
/* BSSRDF should already have been handled elsewhere. */
kernel_assert(CLOSURE_IS_BSDF(sc->type));
int label;
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
*pdf = 0.0f;
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if (*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight, kernel_data.film.use_light_pass);
if (sd->num_closure > 1) {
float sweight = sc->sample_weight;
_shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf * sweight, sweight, wavelengths);
}
}
return label;
}