Commit: f4987bdb0683ca4dc1f85764ae90bc88a5b98cc3
Author: Weizhen Huang
Date: Thu Dec 22 18:24:58 2022 +0100
Branches: microfacet_hair
https://developer.blender.org/rBf4987bdb0683ca4dc1f85764ae90bc88a5b98cc3
Treat hair as transparent if intersection lies outside of the radius
===================================================================
M intern/cycles/kernel/closure/bsdf_hair_microfacet.h
===================================================================
diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index a037839c691..93f42b8f21a 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -66,7 +66,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private
ShaderData *sd,
* the center, to grazing the other edge. This is the sine of the angle
* between sd->Ng and Z, as seen from the tangent X. */
- float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->Ng);
+ float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->N);
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
kernel_assert(isfinite_safe(X));
@@ -109,6 +109,11 @@ ccl_device_inline float tan_theta(const float3 w)
}
/* Returns sin(phi) and cos(phi) of the given direction. */
+ccl_device float sin_phi(const float3 w)
+{
+ return w.x / cos_theta(w);
+}
+
ccl_device float2 sincos_phi(const float3 w)
{
float c = cos_theta(w);
@@ -1132,6 +1137,14 @@ ccl_device Spectrum
bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg,
const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y),
dot(omega_in, Z));
+ /* Treat as transparent material if intersection lies outside of the
projected radius. */
+ const float e2 = 1.0f - sqr(bsdf->extra->eccentricity);
+ const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi)));
+ if (fabsf(bsdf->extra->geom.w) > radius) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
/* evaluate */
const float3 R = bsdf_microfacet_hair_eval_r_elliptic(sc, wi, wo) +
bsdf_microfacet_hair_eval_tt_trt_elliptic(kg, sc, wi, wo,
sd->lcg_state);
@@ -1157,12 +1170,6 @@ ccl_device int
bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
*eta = bsdf->eta;
const float inv_eta = 1.0f / *eta;
- if (bsdf->extra->R <= 0.0f && bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <=
0.0f) {
- /* early out for inactive lobe */
- *pdf = 0.0f;
- return LABEL_NONE;
- }
-
/* get local wi (convention is reversed from other hair bcsdfs) */
const float3 X = float4_to_float3(bsdf->extra->geom);
float3 Y = sd->dPdu;
@@ -1171,6 +1178,31 @@ ccl_device int
bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ /* get elliptical cross section characteristic */
+ const float a = 1.0f;
+ const float b = bsdf->extra->eccentricity;
+ const float e2 = 1.0f - sqr(b / a);
+
+ /* macronormal */
+ const float2 sincos_phi_i = sincos_phi(wi);
+ const float sin_phi_i = sincos_phi_i.x;
+ const float cos_phi_i = sincos_phi_i.y;
+ const float d_i = sqrtf(1.0f - e2 * sqr(sin_phi_i));
+
+ /* Treat as transparent material if intersection lies outside of the
projected radius. */
+ if (fabsf(bsdf->extra->geom.w) > d_i) {
+ *omega_in = -sd->I;
+ *pdf = 1;
+ *eval = one_spectrum();
+ 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 */
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
const float tilt = -bsdf->alpha;
const float roughness = bsdf->roughness;
const bool beckmann = (bsdf->model_type ==
NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN);
@@ -1185,16 +1217,6 @@ ccl_device int
bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
const float2 sample_h3 = make_float2(lcg_step_float(&sd->lcg_state),
lcg_step_float(&sd->lcg_state));
- /* get elliptical cross section characteristic */
- const float a = 1.0f;
- const float b = bsdf->extra->eccentricity;
- const float e2 = 1.0f - sqr(b / a);
-
- /* macronormal */
- const float2 sincos_phi_i = sincos_phi(wi);
- const float sin_phi_i = sincos_phi_i.x;
- const float cos_phi_i = sincos_phi_i.y;
- const float d_i = sqrtf(1.0f - e2 * sqr(sin_phi_i));
const float h = d_i * (sample_h * 2.0f - 1.0f);
const float gamma_mi = atan2f(cos_phi_i, -b / a * sin_phi_i) -
acosf(h / sqrtf(sqr(cos_phi_i) + sqr(b / a *
sin_phi_i)));
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs