[Bf-blender-cvs] [f0529cfabc7] microfacet_hair: Add support for OSL shader to microfacet hair model
Weizhen Huang
noreply at git.blender.org
Mon Jan 16 16:17:28 CET 2023
Commit: f0529cfabc759712dfe19a575f914aa1aca9c277
Author: Weizhen Huang
Date: Mon Jan 16 16:16:58 2023 +0100
Branches: microfacet_hair
https://developer.blender.org/rBf0529cfabc759712dfe19a575f914aa1aca9c277
Add support for OSL shader to microfacet hair model
===================================================================
M intern/cycles/kernel/closure/bsdf_hair_microfacet.h
M intern/cycles/kernel/osl/closures_setup.h
M intern/cycles/kernel/osl/closures_template.h
M intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
M intern/cycles/kernel/osl/shaders/stdcycles.h
M intern/cycles/kernel/svm/closure.h
M intern/cycles/scene/shader_nodes.cpp
===================================================================
diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index ff372ab947b..be3d7d7e105 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -17,8 +17,6 @@ typedef struct MicrofacetHairExtra {
float TT;
float TRT;
- float aspect_ratio;
-
/* Geometry data. */
float4 geom;
} MicrofacetHairExtra;
@@ -41,6 +39,9 @@ typedef struct MicrofacetHairBSDF {
/* 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;
@@ -74,8 +75,20 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
kernel_assert(isfinite_safe(h));
if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
- /* Local frame is independent of the ray direction for elliptical hairs. */
- bsdf->extra->geom.w = h;
+ 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);
@@ -802,7 +815,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC
/* get elliptical cross section characteristic */
const float a = 1.0f;
/* TODO: rename this as aspect ratio? e is in [0, 0.85], b is in [0.52, 1]. */
- const float b = bsdf->extra->aspect_ratio;
+ const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b / a);
/* this follows blender's convention (unlike the circular case?) */
@@ -898,7 +911,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
return zero_float3();
}
- /* this follows blender's convention (unlike the circular case?) */
+ /* TODO: switch wi and wo? */
const float3 wo = wi_;
const float3 wi = wo_;
@@ -923,7 +936,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
/* get elliptical cross section characteristic */
const float a = 1.0f;
- const float b = bsdf->extra->aspect_ratio;
+ const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b / a); /* Squared Eccentricity. */
const float gamma_m_min = to_gamma(phi_m_min, a, b) + 1e-3f;
@@ -1094,7 +1107,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg,
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->aspect_ratio);
+ const float e2 = 1.0f - sqr(bsdf->aspect_ratio);
const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi)));
if (fabsf(bsdf->extra->geom.w) > radius) {
*pdf = 0.0f;
@@ -1136,7 +1149,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
/* get elliptical cross section characteristic */
const float a = 1.0f;
- const float b = bsdf->extra->aspect_ratio;
+ const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b / a);
/* macronormal */
@@ -1345,7 +1358,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg,
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
- if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->extra->aspect_ratio == 1.0f) {
+ if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->aspect_ratio == 1.0f) {
return bsdf_microfacet_hair_eval_circular(kg, sd, sc, omega_in, pdf);
}
@@ -1365,7 +1378,7 @@ ccl_device int bsdf_microfacet_hair_sample(KernelGlobals kg,
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
- if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->extra->aspect_ratio == 1.0f) {
+ if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->aspect_ratio == 1.0f) {
return bsdf_microfacet_hair_sample_circular(
kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
}
diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h
index ceaf56ccba6..a419589880e 100644
--- a/intern/cycles/kernel/osl/closures_setup.h
+++ b/intern/cycles/kernel/osl/closures_setup.h
@@ -23,6 +23,7 @@
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
+#include "kernel/closure/bsdf_hair_microfacet.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bsdf_principled_sheen.h"
#include "kernel/closure/volume.h"
@@ -1121,6 +1122,49 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
#endif
}
+ccl_device void osl_closure_microfacet_hair_setup(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ uint32_t path_flag,
+ float3 weight,
+ ccl_private const MicrofacetHairClosure *closure)
+{
+#ifdef __HAIR__
+ if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
+ return;
+ }
+
+ ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)bsdf_alloc(
+ sd, sizeof(MicrofacetHairBSDF), rgb_to_spectrum(weight));
+ if (!bsdf) {
+ return;
+ }
+
+ ccl_private MicrofacetHairExtra *extra = (ccl_private MicrofacetHairExtra *)closure_alloc_extra(
+ sd, sizeof(MicrofacetHairExtra));
+ if (!extra) {
+ return;
+ }
+
+ bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
+ bsdf->sigma = closure->sigma;
+ bsdf->roughness = closure->roughness;
+ bsdf->tilt = closure->tilt;
+ bsdf->eta = closure->eta;
+ bsdf->cross_section = closure->cross_section;
+ bsdf->distribution_type = closure->distribution_type;
+ bsdf->aspect_ratio = closure->aspect_ratio;
+
+ bsdf->extra = extra;
+ bsdf->extra->R = closure->reflection;
+ bsdf->extra->TT = closure->transmission;
+ bsdf->extra->TRT = closure->secondary_reflection;
+ bsdf->extra->geom = make_float4(
+ closure->major_axis.x, closure->major_axis.y, closure->major_axis.z, 0.0f);
+
+ sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
+#endif
+}
+
/* Volume */
ccl_device void osl_closure_absorption_setup(KernelGlobals kg,
diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h
index b9e9b52dcf8..f799010534d 100644
--- a/intern/cycles/kernel/osl/closures_template.h
+++ b/intern/cycles/kernel/osl/closures_template.h
@@ -245,6 +245,21 @@ OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair)
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL)
OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair)
+OSL_CLOSURE_STRUCT_BEGIN(MicrofacetHair, microfacet_hair)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, N, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, sigma, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, roughness, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, tilt, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, eta, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, distribution_type, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, cross_section, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, aspect_ratio, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, reflection, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, transmission, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, secondary_reflection, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, major_axis, NULL)
+OSL_CLOSURE_STRUCT_END(MicrofacetHair, microfacet_hair)
+
OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption)
OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption)
diff --git a/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
index 162b3b682f1..4f0a7f129ed 100644
--- a/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
+++ b/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
@@ -51,6 +51,10 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
float IOR = 1.55,
string AttrRandom = "geom:curve_random",
float Random = 0.0,
+ float AspectRatio = 0.85,
+ float Reflection = 1.0,
+ float Transmission = 1.0,
+ float SecondaryReflection = 1.0,
output closure color BSDF = 0)
{
@@ -99,5 +103,26 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
sigma = m_sigma_from_concentration(0.0, 0.8054375);
}
- BSDF = microfacet_hair(Normal, sigma, roughness, Offset, IOR);
+ int distribution_type_enum = (distribution_type == "GGX") ? 0 : 1;
+ int cross_section_enum = 0;
+ normal major_axis = 0.0;
+
+ if (cross_section == "Elliptical") {
+ cross_section_enum = 1;
+ major_axis = 1.0;
+ getattribute("geom:N", major_axis);
+ }
+
+ BSDF = microfacet_hair(Normal,
+ sigma,
+ roughness,
+ Offset,
+ IOR,
+ distribution_type_enum,
+ cross_section_enum,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list