Cycles: Pack Chiang Hair local coordinates into BSDF normal field
This has two main advantages: First, it allows to get rid of the extra closure since the remaining float can just be moved to the main closure allocation. Second, previously sd->N was completely unused and therefore unintialized, which ended up causing issues for the Normal render pass.
This commit is contained in:
@@ -15,11 +15,6 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
typedef struct ChiangHairExtra {
|
||||
/* Geometry data. */
|
||||
float4 geom;
|
||||
} ChiangHairExtra;
|
||||
|
||||
typedef struct ChiangHairBSDF {
|
||||
SHADER_CLOSURE_BASE;
|
||||
|
||||
@@ -36,12 +31,11 @@ typedef struct ChiangHairBSDF {
|
||||
/* Effective variance for the diffuse bounce only. */
|
||||
float m0_roughness;
|
||||
|
||||
/* Extra closure. */
|
||||
ccl_private ChiangHairExtra *extra;
|
||||
/* Azimuthal offset. */
|
||||
float h;
|
||||
} ChiangHairBSDF;
|
||||
|
||||
static_assert(sizeof(ShaderClosure) >= sizeof(ChiangHairBSDF), "ChiangHairBSDF is too large!");
|
||||
static_assert(sizeof(ShaderClosure) >= sizeof(ChiangHairExtra), "ChiangHairExtra is too large!");
|
||||
|
||||
/* Gives the change in direction in the normal plane for the given angles and p-th-order
|
||||
* scattering. */
|
||||
@@ -184,13 +178,13 @@ ccl_device int bsdf_hair_chiang_setup(ccl_private ShaderData *sd, ccl_private Ch
|
||||
|
||||
/* TODO: we convert this value to a cosine later and discard the sign, so
|
||||
* we could probably save some operations. */
|
||||
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), Z);
|
||||
bsdf->h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), Z);
|
||||
|
||||
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
|
||||
kernel_assert(fabsf(bsdf->h) < 1.0f + 1e-4f);
|
||||
kernel_assert(isfinite_safe(Y));
|
||||
kernel_assert(isfinite_safe(h));
|
||||
|
||||
bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
|
||||
bsdf->N = Y;
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
|
||||
}
|
||||
@@ -261,7 +255,7 @@ ccl_device Spectrum bsdf_hair_chiang_eval(KernelGlobals kg,
|
||||
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
|
||||
|
||||
ccl_private const ChiangHairBSDF *bsdf = (ccl_private const ChiangHairBSDF *)sc;
|
||||
const float3 Y = float4_to_float3(bsdf->extra->geom);
|
||||
const float3 Y = bsdf->N;
|
||||
|
||||
const float3 X = safe_normalize(sd->dPdu);
|
||||
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
|
||||
@@ -278,7 +272,7 @@ ccl_device Spectrum bsdf_hair_chiang_eval(KernelGlobals kg,
|
||||
const float sin_theta_t = sin_theta_o / bsdf->eta;
|
||||
const float cos_theta_t = cos_from_sin(sin_theta_t);
|
||||
|
||||
const float sin_gamma_o = bsdf->extra->geom.w;
|
||||
const float sin_gamma_o = bsdf->h;
|
||||
const float cos_gamma_o = cos_from_sin(sin_gamma_o);
|
||||
const float gamma_o = safe_asinf(sin_gamma_o);
|
||||
|
||||
@@ -349,7 +343,7 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg,
|
||||
*sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
|
||||
*eta = bsdf->eta;
|
||||
|
||||
const float3 Y = float4_to_float3(bsdf->extra->geom);
|
||||
const float3 Y = bsdf->N;
|
||||
|
||||
const float3 X = safe_normalize(sd->dPdu);
|
||||
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
|
||||
@@ -364,7 +358,7 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg,
|
||||
const float sin_theta_t = sin_theta_o / bsdf->eta;
|
||||
const float cos_theta_t = cos_from_sin(sin_theta_t);
|
||||
|
||||
const float sin_gamma_o = bsdf->extra->geom.w;
|
||||
const float sin_gamma_o = bsdf->h;
|
||||
const float cos_gamma_o = cos_from_sin(sin_gamma_o);
|
||||
const float gamma_o = safe_asinf(sin_gamma_o);
|
||||
|
||||
@@ -472,7 +466,7 @@ ccl_device Spectrum bsdf_hair_chiang_albedo(ccl_private const ShaderData *sd,
|
||||
ccl_private ChiangHairBSDF *bsdf = (ccl_private ChiangHairBSDF *)sc;
|
||||
|
||||
const float cos_theta_o = cos_from_sin(dot(sd->wi, safe_normalize(sd->dPdu)));
|
||||
const float cos_gamma_o = cos_from_sin(bsdf->extra->geom.w);
|
||||
const float cos_gamma_o = cos_from_sin(bsdf->h);
|
||||
const float f = fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta);
|
||||
|
||||
const float roughness_scale = bsdf_principled_hair_albedo_roughness_scale(bsdf->v);
|
||||
|
||||
@@ -858,12 +858,6 @@ ccl_device void osl_closure_hair_chiang_setup(KernelGlobals kg,
|
||||
return;
|
||||
}
|
||||
|
||||
ccl_private ChiangHairExtra *extra = (ccl_private ChiangHairExtra *)closure_alloc_extra(
|
||||
sd, sizeof(ChiangHairExtra));
|
||||
if (!extra) {
|
||||
return;
|
||||
}
|
||||
|
||||
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
|
||||
bsdf->sigma = closure->sigma;
|
||||
bsdf->v = closure->v;
|
||||
@@ -872,8 +866,6 @@ ccl_device void osl_closure_hair_chiang_setup(KernelGlobals kg,
|
||||
bsdf->eta = closure->eta;
|
||||
bsdf->m0_roughness = closure->m0_roughness;
|
||||
|
||||
bsdf->extra = extra;
|
||||
|
||||
sd->flag |= bsdf_hair_chiang_setup(sd, bsdf);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -706,13 +706,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
ccl_private ChiangHairBSDF *bsdf = (ccl_private ChiangHairBSDF *)bsdf_alloc(
|
||||
sd, sizeof(ChiangHairBSDF), weight);
|
||||
if (bsdf) {
|
||||
ccl_private ChiangHairExtra *extra = (ccl_private ChiangHairExtra *)closure_alloc_extra(
|
||||
sd, sizeof(ChiangHairExtra));
|
||||
|
||||
if (!extra) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Remap Coat value to [0, 100]% of Roughness. */
|
||||
float coat = stack_load_float_default(stack, shared_ofs1, data_node3.w);
|
||||
float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
|
||||
@@ -722,7 +715,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
bsdf->m0_roughness = m0_roughness;
|
||||
bsdf->alpha = alpha;
|
||||
bsdf->eta = ior;
|
||||
bsdf->extra = extra;
|
||||
bsdf->sigma = sigma;
|
||||
|
||||
sd->flag |= bsdf_hair_chiang_setup(sd, bsdf);
|
||||
|
||||
Reference in New Issue
Block a user