Cycles: new Microfacet-based Hair BSDF with elliptical cross-section support #105600

Merged
Weizhen Huang merged 114 commits from weizhen/blender:microfacet_hair into main 2023-08-18 12:46:20 +02:00
3 changed files with 24 additions and 31 deletions
Showing only changes of commit 68501a20e2 - Show all commits

View File

@ -177,7 +177,8 @@ ccl_device_inline float arc_length(float e2, float gamma)
#ifdef __HAIR__
/* Set up the hair closure. */
ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
ccl_private MicrofacetHairBSDF *bsdf)
ccl_private MicrofacetHairBSDF *bsdf,
uint32_t path_flag)
{
bsdf->type = CLOSURE_BSDF_HAIR_MICROFACET_ID;
@ -226,6 +227,14 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
1.0f :
sqrtf(1.0f - bsdf->extra->e2 * sqr(I.x) / (sqr(I.x) + sqr(I.z)));
/* Treat as transparent material if intersection lies outside of the projected radius. */
if (fabsf(bsdf->h) >= bsdf->extra->radius) {
bsdf_transparent_setup(sd, bsdf->weight, path_flag);
bsdf->type = CLOSURE_NONE_ID;
bsdf->sample_weight = 0.0f;
return 0;
}
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
}
@ -607,19 +616,7 @@ ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg,
*sampled_roughness = make_float2(roughness, roughness);
*eta = bsdf->eta;
/* Treat as transparent material if intersection lies outside of the projected radius. */
if (fabsf(bsdf->h) > bsdf->extra->radius) {
*wo = -sd->wi;
*pdf = 1.0f;
*eval = one_spectrum();
*eta = 1.0f;
return LABEL_TRANSMIT | LABEL_TRANSPARENT;
}
if (bsdf->extra->R <= 0.0f && bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) {
/* Early out for inactive lobe. */
return LABEL_NONE;
}
kernel_assert(fabsf(bsdf->h) < bsdf->extra->radius);
weizhen marked this conversation as resolved Outdated

Same here.

Same here.
/* Generate samples. */
float sample_lobe = rand.x;
@ -790,11 +787,7 @@ ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg,
const float trt = average(TRT);
const float trrt = average(TRRT);
const float total_energy = r + tt + trt + trrt;
if (total_energy == 0.0f) {
*pdf = 0.0f;
return LABEL_NONE;
}
kernel_assert(total_energy > 0.0f);
float3 local_O;
@ -839,10 +832,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg,
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
/* Treat as transparent material if intersection lies outside of the projected radius. */
if (fabsf(bsdf->h) > bsdf->extra->radius) {
return zero_spectrum();
}
kernel_assert(fabsf(bsdf->h) < bsdf->extra->radius);
/* Get local coordinate system. */
const float3 X = bsdf->N;

View File

@ -916,7 +916,7 @@ ccl_device void osl_closure_microfacet_hair_setup(KernelGlobals kg,
bsdf->extra->TT = closure->tt_lobe;
bsdf->extra->TRT = closure->trt_lobe;
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf, path_flag);
#endif
}

View File

@ -692,6 +692,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
else {
kernel_assert(type == CLOSURE_BSDF_HAIR_MICROFACET_ID);
uint R_ofs, TT_ofs, TRT_ofs, unused;
svm_unpack_node_uchar4(data_node4.x, &R_ofs, &TT_ofs, &TRT_ofs, &unused);
float R = stack_load_float_default(stack, R_ofs, data_node4.y);
float TT = stack_load_float_default(stack, TT_ofs, data_node4.z);
float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w);
if (R <= 0.0f && TT <= 0.0f && TRT <= 0.0f) {
break;
}
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)bsdf_alloc(
sd, sizeof(MicrofacetHairBSDF), weight);
if (bsdf) {
@ -702,12 +711,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
break;
}
uint R_ofs, TT_ofs, TRT_ofs, unused;
svm_unpack_node_uchar4(data_node4.x, &R_ofs, &TT_ofs, &TRT_ofs, &unused);
float R = stack_load_float_default(stack, R_ofs, data_node4.y);
float TT = stack_load_float_default(stack, TT_ofs, data_node4.z);
float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w);
bsdf->extra = extra;
bsdf->extra->R = fmaxf(0.0f, R);
bsdf->extra->TT = fmaxf(0.0f, TT);
@ -725,7 +728,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->eta = ior;
bsdf->sigma = sigma;
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf, path_flag);
}
}
break;