[Bf-blender-cvs] [46bc834a3dd] microfacet_hair: Merge branch 'master' into microfacet_hair
Weizhen Huang
noreply at git.blender.org
Fri Jan 20 15:18:44 CET 2023
Commit: 46bc834a3ddf39ef53ebfd221697ac26ad5c15d5
Author: Weizhen Huang
Date: Fri Jan 20 15:18:29 2023 +0100
Branches: microfacet_hair
https://developer.blender.org/rB46bc834a3ddf39ef53ebfd221697ac26ad5c15d5
Merge branch 'master' into microfacet_hair
===================================================================
===================================================================
diff --cc intern/cycles/blender/curves.cpp
index ce8a35fb61b,6158ed78598..0b06ab22bbc
--- a/intern/cycles/blender/curves.cpp
+++ b/intern/cycles/blender/curves.cpp
@@@ -895,9 -885,6 +894,14 @@@ static void export_hair_curves(Scene *s
float *attr_length = NULL;
float *attr_random = NULL;
+ if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) {
- attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3();
++ /* Compute geometry normals. */
++ float3 *attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3();
++ int i = 0;
++ for (BL::FloatVectorValueReadOnly &normal : b_curves.normals) {
++ attr_normal[i++] = get_float3(normal.vector());
++ }
+ }
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
}
diff --cc intern/cycles/kernel/closure/bsdf.h
index cb797e284a4,2f53454d7dd..8ca750945ff
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@@ -242,14 -220,10 +221,14 @@@ ccl_device_inline int bsdf_sample(Kerne
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(
- kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
+ kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta);
break;
+ case CLOSURE_BSDF_HAIR_MICROFACET_ID:
+ label = bsdf_microfacet_hair_sample(
- kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
++ kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta);
+ break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
@@@ -514,8 -483,7 +493,8 @@@ ccl_device_inline int bsdf_label(const
label = LABEL_TRANSMIT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ case CLOSURE_BSDF_HAIR_MICROFACET_ID:
- if (bsdf_is_transmission(sc, omega_in))
+ if (bsdf_is_transmission(sc, wo))
label = LABEL_TRANSMIT | LABEL_GLOSSY;
else
label = LABEL_REFLECT | LABEL_GLOSSY;
@@@ -603,37 -571,34 +582,37 @@@ ccl_device_inlin
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_diffuse_toon_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_glossy_toon_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
+ eval = bsdf_principled_hair_eval(kg, sd, sc, wo, pdf);
break;
+ case CLOSURE_BSDF_HAIR_MICROFACET_ID:
- eval = bsdf_microfacet_hair_eval(kg, sd, sc, omega_in, pdf);
++ eval = bsdf_microfacet_hair_eval(kg, sd, sc, wo, pdf);
+ break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_hair_reflection_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- eval = bsdf_principled_sheen_eval(sc, sd->I, omega_in, pdf);
+ eval = bsdf_principled_sheen_eval(sc, sd->wi, wo, pdf);
break;
#endif
default:
diff --cc intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index b00da5b872d,00000000000..d9d9df942e6
mode 100644,000000..100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@@ -1,1405 -1,0 +1,1435 @@@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2018-2022 Blender Foundation */
+
+#pragma once
+
+#ifndef __KERNEL_GPU__
+# include <fenv.h>
+#endif
+
+#include "kernel/util/color.h"
+
+CCL_NAMESPACE_BEGIN
+
+typedef struct MicrofacetHairExtra {
+ /* TODO: is this necessary? */
+ float R;
+ float TT;
+ float TRT;
+
+ /* Geometry data. */
+ float4 geom;
+} MicrofacetHairExtra;
+
+typedef struct MicrofacetHairBSDF {
+ SHADER_CLOSURE_BASE;
+
+ /* Absorption coefficient. */
+ Spectrum sigma;
+ /* Microfacet distribution roughness. */
+ float roughness;
+ /* Cuticle tilt angle. */
+ float tilt;
+ /* IOR. */
+ float eta;
+
+ /* GGX/Beckmann. */
+ int distribution_type;
+
+ /* Circular/Elliptical */
+ int cross_section;
+
+ /* The ratio of the minor axis to the major axis. */
+ float aspect_ratio;
+
+ /* Extra closure. */
+ ccl_private MicrofacetHairExtra *extra;
+} MicrofacetHairBSDF;
+
+static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetHairBSDF),
+ "MicrofacetHairBSDF is too large!");
+static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetHairExtra),
+ "MicrofacetHairExtra is too large!");
+
+#ifdef __HAIR__
+/* Set up the hair closure. */
+ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
+ ccl_private MicrofacetHairBSDF *bsdf)
+{
+ bsdf->type = CLOSURE_BSDF_HAIR_MICROFACET_ID;
+
+ bsdf->roughness = clamp(bsdf->roughness, 0.001f, 1.0f);
+
+ /* Compute local frame. The Y axis is aligned with the curve tangent; the X axis is perpendicular
+ to the ray direction for circular cross-sections, or aligned with the major axis for elliptical
+ cross-sections. */
+ const float3 Y = safe_normalize(sd->dPdu);
- const float3 X = safe_normalize(cross(Y, sd->I));
++ const float3 X = safe_normalize(cross(Y, sd->wi));
+
+ /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at the center, to grazing
+ * the other edge. This is the cosine of the angle between sd->N and X. */
+ const 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));
+ kernel_assert(isfinite_safe(h));
+
+ if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
+ if (bsdf->aspect_ratio > 1.0f) {
+ bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio;
+
+ /* Switch major and minor axis. */
+ const float3 minor_axis = safe_normalize(cross(
+ sd->dPdu, make_float3(bsdf->extra->geom.x, bsdf->extra->geom.y, bsdf->extra->geom.z)));
+ const float3 major_axis = safe_normalize(cross(minor_axis, sd->dPdu));
+
+ /* Local frame is independent of the ray direction for elliptical hairs. */
+ bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, h);
+ }
+ else {
+ bsdf->extra->geom.w = h;
+ }
+ }
+ else {
+ bsdf->extra->geom = make_float4(X.x, X.y, X.z, h);
+ }
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
+}
+
+#endif /* __HAIR__ */
+
+/* -------------------------------------------------------------------- */
+/** \name Hair coordinate system utils.
+ * \{ */
+
+/* Returns sin(theta) of the given direction. */
+ccl_device_inline float sin_theta(const float3 w)
+{
+ return w.y;
+}
+
+/* Returns cos(theta) of the given direction. */
+ccl_device_inline float cos_theta(const float3 w)
+{
+ return safe_sqrtf(sqr(w.x) + sqr(w.z));
+}
+
+/* Returns tan(theta) of the given direction. */
+ccl_device_inline float tan_theta(const float3 w)
+{
+ return sin_theta(w) / cos_theta(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);
+ return make_float2(w.x / c, w.z / c);
+}
+
+/* Extract the theta coordinate from the given direction.
+ * -pi < theta < pi */
+ccl_device_inline float dir_theta(const float3 w)
+{
+ return atan2f(sin_theta(w), cos_theta(w));
+}
+
+/* Extract the phi coordinate from the given direction, assuming phi(wi) = 0.
+ * -pi < phi < pi */
+ccl_device_inline float dir_phi(const float3 w)
+{
+ return atan2f(w.x, w.z);
+}
+
+/* Extract theta and phi coordinates from the given direction, assuming phi(wi) = 0.
+ * -pi/2 < theta < pi/2, -pi < phi < pi */
+ccl_device_inline float2 dir_sph(const float3 w)
+{
+ return make_float2(dir_theta(w), dir_phi(w));
+}
+
+/* Compute the vector direction given spherical coordinates. */
+ccl_device_inline float3 sph_dir(float theta, float phi)
+{
+ float sin_theta, cos_theta, sin_phi, cos_phi;
+ fast_sincosf(theta, &sin_theta, &cos_theta);
+ fast_sincosf(phi, &sin_phi, &cos_phi);
+ return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta);
+}
+
+/* Utility functions for elliptical cross-sections. */
+
+/* Conversion between gamma and phi. Notations see Figure 5 in the paper. */
+ccl_device float to_phi(float gamma, float a, float b)
+{
+ float sin_gamma, cos_gamma;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list