diff --git a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx index 86b19eaa71..754594620b 100644 --- a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx +++ b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx @@ -25,6 +25,9 @@ + + + @@ -90,4 +93,13 @@ + + + + + + + + + diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl index ef2e090a49..b69d59e8b0 100644 --- a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl @@ -428,6 +428,35 @@ export material mx_thin_film_bsdf( volume: mxp_base.volume ); +export material mx_chiang_hair_bsdf( + // TODO: MDL's chiang_hair BSDF has no support tinting each lobes + color mxp_tint_R = color(1.0), + color mxp_tint_TT = color(1.0), + color mxp_tint_TRT = color(1.0), + float mxp_ior = 1.55, + float2 mxp_roughness_R = float2(0.1, 0.1), + float2 mxp_roughness_TT = float2(0.05, 0.05), + float2 mxp_roughness_TRT = float2(0.2, 0.2), + float mxp_cuticle_angle = 0.5, + float3 mxp_absorption_coefficient = float3(0.0), + // TODO: MDL's chiang_hair BSDF has no support user tangent vector + float3 mxp_curve_direction = state::texture_tangent_u(0) +) [[ + anno::usage( "materialx:bsdf") +]] += material( + hair: df::chiang_hair_bsdf( + diffuse_reflection_weight: 0.0, + diffuse_reflection_tint: color(0.0), + roughness_R: mxp_roughness_R, + roughness_TT: mxp_roughness_TT, + roughness_TRT: mxp_roughness_TRT, + cuticle_angle: mxp_cuticle_angle, + absorption_coefficient: mxp_absorption_coefficient, + ior: mxp_ior + ) +); + // EDF Nodes export material mx_uniform_edf( @@ -980,3 +1009,64 @@ export mx_artistic_ior__result mx_artistic_ior( color k = math::sqrt(k2); return mx_artistic_ior__result(n,k); } + +export float3 mx_dion_hair_absorption_from_melanin( + float mxp_melanin_concentration = 0.25, + float mxp_melanin_redness = 0.5, + color mxp_eumelanin_color = color(0.657704, 0.498077, 0.254107), + color mxp_pheomelanin_color = color(0.829444, 0.67032, 0.349938) +) { + float melanin = -math::log(math::max(1.0 - mxp_melanin_concentration, 0.0001)); + float eumelanin = melanin * (1.0 = mxp_melanin_redness); + float pheomelanin = melanin * mxp_melanin_redness; + return math::max( + eumelanin * -math::log(mxp_eumelanin_color) + pheomelanin * -math::log(mxp_pheomelanin_color), + float3(0.0) + ); +} + +export float3 mx_chiang_hair_absorption_from_color( + color mxp_color = color(1.0, 1.0, 1.0), + float mxp_azimuthal_roughness = 0.2 +) { + float r2 = mxp_azimuthal_roughness * mxp_azimuthal_roughness; + float r4 = r2 * r2; + float r_fac = + 5.969 - + (0.215 * mxp_azimuthal_roughness) + + (2.532 * r2) - + (10.73 * r2 * mxp_azimuthal_roughness) + + (5.574 * r4) + + (0.245 * r4 * mxp_azimuthal_roughness); + float3 sigma = math::log(math::min(math::max(mxp_color, 0.001), float3(1.0))) / r_fac; + return (sigma * sigma); +} + +// Supportive struct type for the three outputs of mx_chiang_hair_roughness +export struct mx_chiang_hair_roughness__result { + float2 mxp_roughness_R; + float2 mxp_roughness_TT; + float2 mxp_roughness_TRT; +}; + +export mx_chiang_hair_roughness__result mx_chiang_hair_roughness( + float mxp_longitudinal = 0.1, + float mxp_azimuthal = 0.2, + float mxp_scale_TT = 0.5, + float mxp_scale_TRT = 2.0 +) { + float lr = math::clamp(mxp_longitudinal, 0.001, 1.0); + float ar = math::clamp(mxp_azimuthal, 0.001, 1.0); + + // longitudinal variance + float v = 0.726 * lr + 0.812 * lr * lr + 3.7 * math::pow(lr, 20); + v = v * v; + + float s = 0.265 * ar + 1.194 * ar * ar + 5.372 * math::pow(ar, 22); + + float2 roughness_R = float2(v, s); + float2 roughness_TT = float2(v * mxp_scale_TT * mxp_scale_TT, s); + float2 roughness_TRT = float2(v * mxp_scale_TRT * mxp_scale_TRT, s); + + return mx_chiang_hair_roughness__result(roughness_R, roughness_TT, roughness_TRT); +} diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 12a1f33868..e1a23cf7d4 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -93,12 +93,8 @@ TEST_CASE("GenShader: MDL Implementation Check", "[genmdl]") generatorSkipNodeTypes.insert("light"); mx::StringSet generatorSkipNodeDefs; - generatorSkipNodeDefs.insert("ND_chiang_hair_roughness"); - generatorSkipNodeDefs.insert("ND_chiang_hair_absorption_from_color"); - generatorSkipNodeDefs.insert("ND_deon_hair_absorption_from_melanin"); - generatorSkipNodeDefs.insert("ND_chiang_hair_bsdf"); - GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 35); + GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 31); } diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.h b/source/MaterialXTest/MaterialXGenMdl/GenMdl.h index 1e617f73fb..ab92a5dacf 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.h +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.h @@ -50,9 +50,6 @@ class MdlShaderGeneratorTester : public GenShaderUtil::ShaderGeneratorTester _skipFiles.insert("heighttonormal_in_nodegraph.mtlx"); } - _skipFiles.insert("hair_bsdf.mtlx"); - _skipFiles.insert("hair_surfaceshader.mtlx"); - ShaderGeneratorTester::addSkipFiles(); }