Cycles: Refactor microfacet BSDFs to remove separate anisotropy code

Since the sampling and evaluation functions handle both cases anyways,
there's not really a point for keeping the distinction in the kernel,
so we might as well cut down the number of CLOSURE_BSDF_MICROFACETs a bit.

Differential Revision: https://developer.blender.org/D7736
This commit is contained in:
Lukas Stockner
2020-05-14 22:12:29 +02:00
parent 8d918fe0f2
commit c880e54a95
9 changed files with 98 additions and 215 deletions

View File

@@ -320,9 +320,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
/* setup bsdf */
if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
roughness <= 0.075f) /* use single-scatter GGX */
sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
else /* use multi-scatter GGX */
sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
}
}
# ifdef __CAUSTICS_TRICKS__
@@ -515,12 +515,34 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
float roughness = sqr(param1);
bsdf->N = N;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
bsdf->ior = 0.0f;
bsdf->extra = NULL;
if (data_node.y == SVM_STACK_INVALID) {
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
}
else {
bsdf->T = stack_load_float3(stack, data_node.y);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.z);
if (rotation != 0.0f)
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (anisotropy < 0.0f) {
bsdf->alpha_x = roughness / (1.0f + anisotropy);
bsdf->alpha_y = roughness * (1.0f + anisotropy);
}
else {
bsdf->alpha_x = roughness * (1.0f - anisotropy);
bsdf->alpha_y = roughness / (1.0f - anisotropy);
}
}
/* setup bsdf */
if (type == CLOSURE_BSDF_REFLECTION_ID)
sd->flag |= bsdf_reflection_setup(bsdf);
@@ -529,10 +551,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID)
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
kernel_assert(stack_valid(data_node.z));
kernel_assert(stack_valid(data_node.w));
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf->extra) {
bsdf->extra->color = stack_load_float3(stack, data_node.z);
bsdf->extra->color = stack_load_float3(stack, data_node.w);
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
bsdf->extra->clearcoat = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
@@ -675,64 +697,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
break;
}
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
#ifdef __CAUSTICS_TRICKS__
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
float3 weight = sd->svm_closure_weight * mix_weight;
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
if (bsdf) {
bsdf->N = N;
bsdf->extra = NULL;
bsdf->T = stack_load_float3(stack, data_node.y);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.z);
if (rotation != 0.0f)
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float roughness = sqr(param1);
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (anisotropy < 0.0f) {
bsdf->alpha_x = roughness / (1.0f + anisotropy);
bsdf->alpha_y = roughness * (1.0f + anisotropy);
}
else {
bsdf->alpha_x = roughness * (1.0f - anisotropy);
bsdf->alpha_y = roughness / (1.0f - anisotropy);
}
bsdf->ior = 0.0f;
if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
}
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
}
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
kernel_assert(stack_valid(data_node.w));
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf->extra) {
bsdf->extra->color = stack_load_float3(stack, data_node.w);
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
bsdf->extra->clearcoat = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
}
}
else
sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
}
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
float3 weight = sd->svm_closure_weight * mix_weight;
VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);