From 0f2438e35afda93870232beaa4535a42baece782 Mon Sep 17 00:00:00 2001 From: Lee Kerley <154285602+ld-kerley@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:42:37 -0700 Subject: [PATCH 1/2] Fix Chiang hair model for Metal Shading language (#2057) The current approach for converting GLSL code to MSL doesn't work for the recent Chiang hair PR #1968. --- libraries/pbrlib/genglsl/mx_hair_bsdf.glsl | 13 ++++++++-- source/MaterialXGenMsl/MslShaderGenerator.cpp | 24 ++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libraries/pbrlib/genglsl/mx_hair_bsdf.glsl b/libraries/pbrlib/genglsl/mx_hair_bsdf.glsl index e3a9ac20d5..ec1acf91b3 100644 --- a/libraries/pbrlib/genglsl/mx_hair_bsdf.glsl +++ b/libraries/pbrlib/genglsl/mx_hair_bsdf.glsl @@ -240,12 +240,21 @@ vec3 mx_chiang_hair_bsdf( float alpha = cuticle_angle * M_PI - (M_PI / 2.0); // remap [0, 1] to [-PI/2, PI/2] mx_hair_alpha_angles(alpha, sinThetaI, cosThetaI, angles); - vec3 tint[4] = vec3[](tint_R, tint_TT, tint_TRT, tint_TRT); + vec3 tint[4]; + tint[0] = tint_R; + tint[1] = tint_TT; + tint[2] = tint_TRT; + tint[3] = tint_TRT; roughness_R = clamp(roughness_R, 0.001, 1.0); roughness_TT = clamp(roughness_TT, 0.001, 1.0); roughness_TRT = clamp(roughness_TRT, 0.001, 1.0); - vec2 vs[4] = vec2[](roughness_R, roughness_TT, roughness_TRT, roughness_TRT); + + vec2 vs[4]; + vs[0] = roughness_R; + vs[1] = roughness_TT; + vs[2] = roughness_TRT; + vs[3] = roughness_TRT; // R, TT, TRT, TRRT+ vec3 F = vec3(0.0); diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 8db763d7e1..5476b33c90 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -237,7 +237,29 @@ void MslShaderGenerator::MetalizeGeneratedShader(ShaderStage& shaderStage) const } size_t typename_end = pos; std::string typeName = sourceCode.substr(typename_beg, typename_end - typename_beg); - sourceCode.replace(beg, typename_end - beg, "thread " + typeName + "&"); + + while (std::isspace(sourceCode[pos])) + { + ++pos; + } + size_t varname_beg = pos; + while (!std::isspace(sourceCode[pos]) && sourceCode[pos] != '\n' && sourceCode[pos] != ',' && sourceCode[pos] != ')' ) + { + ++pos; + } + size_t varname_end = pos; + std::string varName = sourceCode.substr(varname_beg, varname_end - varname_beg); + + if (varName.find('[') != std::string::npos) + { + // if the variable is an array then we don't need to declare it as a reference, + // we will effectively just be passing the pointer to the array + sourceCode.replace(beg, typename_end - beg, "thread " + typeName); + } + else + { + sourceCode.replace(beg, typename_end - beg, "thread " + typeName + "&"); + } } pos = sourceCode.find(keyword, pos); } From cb04ef7b2388592125fe61b5dae7782523847a5b Mon Sep 17 00:00:00 2001 From: Lee Kerley <154285602+ld-kerley@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:43:22 -0700 Subject: [PATCH 2/2] Refactor mx_math files to remove GLSL guard (#2014) Refactor mx_math.glsl and mx_math.metal to remove the `__DECL_GL_MATH_FUNCTIONS__` guard, and prefix any necessary functions to ensure isolation from other shader generators, such as HdStorm. --- .../lib/mx_generate_prefilter_env.glsl | 6 +- .../pbrlib/genglsl/lib/mx_microfacet.glsl | 8 +- .../genglsl/lib/mx_microfacet_diffuse.glsl | 8 +- .../genglsl/lib/mx_microfacet_specular.glsl | 20 +-- libraries/stdlib/genglsl/lib/mx_math.glsl | 113 +++++++++++++++- .../stdlib/genglsl/mx_rotate_vector2.glsl | 6 +- .../stdlib/genglsl/mx_rotate_vector3.glsl | 6 +- .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 48 +++---- libraries/stdlib/genmsl/lib/mx_math.metal | 126 +++++++++++++++--- .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 52 ++++---- 10 files changed, 296 insertions(+), 97 deletions(-) diff --git a/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl index 7a80d0d3ec..7bc202bfeb 100644 --- a/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl @@ -13,9 +13,9 @@ vec3 mx_latlong_map_projection_inverse(vec2 uv) float latitude = (uv.y - 0.5) * M_PI; float longitude = (uv.x - 0.5) * M_PI * 2.0; - float x = -cos(latitude) * sin(longitude); - float y = -sin(latitude); - float z = cos(latitude) * cos(longitude); + float x = -mx_cos(latitude) * mx_sin(longitude); + float y = -mx_sin(latitude); + float z = mx_cos(latitude) * mx_cos(longitude); return vec3(x, y, z); } diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet.glsl index f0e6f55c13..05c12e907c 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet.glsl @@ -77,8 +77,8 @@ vec3 mx_uniform_sample_hemisphere(vec2 Xi) float phi = 2.0 * M_PI * Xi.x; float cosTheta = 1.0 - Xi.y; float sinTheta = sqrt(1.0 - mx_square(cosTheta)); - return vec3(cos(phi) * sinTheta, - sin(phi) * sinTheta, + return vec3(mx_cos(phi) * sinTheta, + mx_sin(phi) * sinTheta, cosTheta); } @@ -88,8 +88,8 @@ vec3 mx_cosine_sample_hemisphere(vec2 Xi) float phi = 2.0 * M_PI * Xi.x; float cosTheta = sqrt(Xi.y); float sinTheta = sqrt(1.0 - Xi.y); - return vec3(cos(phi) * sinTheta, - sin(phi) * sinTheta, + return vec3(mx_cos(phi) * sinTheta, + mx_sin(phi) * sinTheta, cosTheta); } diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_diffuse.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_diffuse.glsl index 622db85012..f26c15df37 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet_diffuse.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_diffuse.glsl @@ -89,7 +89,7 @@ float mx_oren_nayar_fujii_diffuse_dir_albedo(float cosTheta, float roughness) float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness); float B = roughness * A; float Si = sqrt(max(0.0, 1.0 - mx_square(cosTheta))); - float G = Si * (acos(clamp(cosTheta, -1.0, 1.0)) - Si * cosTheta) + + float G = Si * (mx_acos(clamp(cosTheta, -1.0, 1.0)) - Si * cosTheta) + 2.0 * ((Si / cosTheta) * (1.0 - Si * Si * Si) - Si) / 3.0; return A + (B * G * M_PI_INV); } @@ -169,7 +169,7 @@ vec3 mx_burley_diffusion_profile(float dist, vec3 shape) // Inspired by Eric Penner's presentation in http://advances.realtimerendering.com/s2011/ vec3 mx_integrate_burley_diffusion(vec3 N, vec3 L, float radius, vec3 mfp) { - float theta = acos(dot(N, L)); + float theta = mx_acos(dot(N, L)); // Estimate the Burley diffusion shape from mean free path. vec3 shape = vec3(1.0) / max(mfp, 0.1); @@ -182,9 +182,9 @@ vec3 mx_integrate_burley_diffusion(vec3 N, vec3 L, float radius, vec3 mfp) for (int i = 0; i < SAMPLE_COUNT; i++) { float x = -M_PI + (float(i) + 0.5) * SAMPLE_WIDTH; - float dist = radius * abs(2.0 * sin(x * 0.5)); + float dist = radius * abs(2.0 * mx_sin(x * 0.5)); vec3 R = mx_burley_diffusion_profile(dist, shape); - sumD += R * max(cos(theta + x), 0.0); + sumD += R * max(mx_cos(theta + x), 0.0); sumR += R; } diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl index 0e77e545e9..fd52bd7435 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl @@ -48,8 +48,8 @@ vec3 mx_ggx_importance_sample_VNDF(vec2 Xi, vec3 V, vec2 alpha) float phi = 2.0 * M_PI * Xi.x; float z = (1.0 - Xi.y) * (1.0 + V.z) - V.z; float sinTheta = sqrt(clamp(1.0 - z * z, 0.0, 1.0)); - float x = sinTheta * cos(phi); - float y = sinTheta * sin(phi); + float x = sinTheta * mx_cos(phi); + float y = sinTheta * mx_sin(phi); vec3 c = vec3(x, y, z); // Compute the microfacet normal. @@ -286,9 +286,9 @@ void mx_fresnel_conductor_phase_polarized(float cosTheta, float eta1, vec3 eta2, vec3 U = sqrt((A+B)/2.0); vec3 V = max(vec3(0.0), sqrt((B-A)/2.0)); - phiS = atan(2.0*eta1*V*cosTheta, U*U + V*V - mx_square(eta1*cosTheta)); - phiP = atan(2.0*eta1*eta2*eta2*cosTheta * (2.0*k2*U - (vec3(1.0)-k2*k2) * V), - mx_square(eta2*eta2*(vec3(1.0)+k2*k2)*cosTheta) - eta1*eta1*(U*U+V*V)); + phiS = mx_atan(2.0*eta1*V*cosTheta, U*U + V*V - mx_square(eta1*cosTheta)); + phiP = mx_atan(2.0*eta1*eta2*eta2*cosTheta * (2.0*k2*U - (vec3(1.0)-k2*k2) * V), + mx_square(eta2*eta2*(vec3(1.0)+k2*k2)*cosTheta) - eta1*eta1*(U*U+V*V)); } // https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html @@ -299,8 +299,8 @@ vec3 mx_eval_sensitivity(float opd, vec3 shift) vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13); vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06); vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09); - vec3 xyz = val * sqrt(2.0*M_PI * var) * cos(pos * phase + shift) * exp(- var * phase*phase); - xyz.x += 9.7470e-14 * sqrt(2.0*M_PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(- 4.5282e+09 * phase*phase); + vec3 xyz = val * sqrt(2.0*M_PI * var) * mx_cos(pos * phase + shift) * exp(- var * phase*phase); + xyz.x += 9.7470e-14 * sqrt(2.0*M_PI * 4.5282e+09) * mx_cos(2.2399e+06 * phase + shift[0]) * exp(- 4.5282e+09 * phase*phase); return xyz / 1.0685e-7; } @@ -341,7 +341,7 @@ vec3 mx_fresnel_airy(float cosTheta, FresnelData fd) } // Phase shift - float cosB = cos(atan(eta2 / eta1)); + float cosB = mx_cos(mx_atan(eta2 / eta1)); vec2 phi21 = vec2(cosTheta < cosB ? 0.0 : M_PI, M_PI); vec3 phi23p, phi23s; if (fd.model == FRESNEL_MODEL_SCHLICK) @@ -486,8 +486,8 @@ vec3 mx_refraction_solid_sphere(vec3 R, vec3 N, float ior) vec2 mx_latlong_projection(vec3 dir) { - float latitude = -asin(dir.y) * M_PI_INV + 0.5; - float longitude = atan(dir.x, -dir.z) * M_PI_INV * 0.5 + 0.5; + float latitude = -mx_asin(dir.y) * M_PI_INV + 0.5; + float longitude = mx_atan(dir.x, -dir.z) * M_PI_INV * 0.5 + 0.5; return vec2(longitude, latitude); } diff --git a/libraries/stdlib/genglsl/lib/mx_math.glsl b/libraries/stdlib/genglsl/lib/mx_math.glsl index cff7835a4c..838fe1f3dd 100644 --- a/libraries/stdlib/genglsl/lib/mx_math.glsl +++ b/libraries/stdlib/genglsl/lib/mx_math.glsl @@ -4,12 +4,10 @@ float mx_square(float x) { return x*x; } - vec2 mx_square(vec2 x) { return x*x; } - vec3 mx_square(vec3 x) { return x*x; @@ -27,3 +25,114 @@ float mx_inversesqrt(float x) { return inversesqrt(x); } + +float mx_radians(float degree) +{ + return radians(degree); +} + +float mx_sin(float x) +{ + return sin(x); +} +vec2 mx_sin(vec2 x) +{ + return sin(x); +} +vec3 mx_sin(vec3 x) +{ + return sin(x); +} +vec4 mx_sin(vec4 x) +{ + return sin(x); +} + +float mx_cos(float x) +{ + return cos(x); +} +vec2 mx_cos(vec2 x) +{ + return cos(x); +} +vec3 mx_cos(vec3 x) +{ + return cos(x); +} +vec4 mx_cos(vec4 x) +{ + return cos(x); +} + +float mx_tan(float x) +{ + return tan(x); +} +vec2 mx_tan(vec2 x) +{ + return tan(x); +} +vec3 mx_tan(vec3 x) +{ + return tan(x); +} +vec4 mx_tan(vec4 x) +{ + return tan(x); +} + +float mx_asin(float x) +{ + return asin(x); +} +vec2 mx_asin(vec2 x) +{ + return asin(x); +} +vec3 mx_asin(vec3 x) +{ + return asin(x); +} +vec4 mx_asin(vec4 x) +{ + return asin(x); +} + +float mx_acos(float x) +{ + return acos(x); +} +vec2 mx_acos(vec2 x) +{ + return acos(x); +} +vec3 mx_acos(vec3 x) +{ + return acos(x); +} +vec4 mx_acos(vec4 x) +{ + return acos(x); +} + +float mx_atan(float y_over_x) +{ + return atan(y_over_x); +} +float mx_atan(float y, float x) +{ + return atan(y, x); +} +vec2 mx_atan(vec2 y, vec2 x) +{ + return atan(y, x); +} +vec3 mx_atan(vec3 y, vec3 x) +{ + return atan(y, x); +} +vec4 mx_atan(vec4 y, vec4 x) +{ + return atan(y, x); +} diff --git a/libraries/stdlib/genglsl/mx_rotate_vector2.glsl b/libraries/stdlib/genglsl/mx_rotate_vector2.glsl index a66c17d0ab..d01270d8ce 100644 --- a/libraries/stdlib/genglsl/mx_rotate_vector2.glsl +++ b/libraries/stdlib/genglsl/mx_rotate_vector2.glsl @@ -1,7 +1,7 @@ void mx_rotate_vector2(vec2 _in, float amount, out vec2 result) { - float rotationRadians = radians(amount); - float sa = sin(rotationRadians); - float ca = cos(rotationRadians); + float rotationRadians = mx_radians(amount); + float sa = mx_sin(rotationRadians); + float ca = mx_cos(rotationRadians); result = vec2(ca*_in.x + sa*_in.y, -sa*_in.x + ca*_in.y); } diff --git a/libraries/stdlib/genglsl/mx_rotate_vector3.glsl b/libraries/stdlib/genglsl/mx_rotate_vector3.glsl index fb06e120ec..fda1188379 100644 --- a/libraries/stdlib/genglsl/mx_rotate_vector3.glsl +++ b/libraries/stdlib/genglsl/mx_rotate_vector3.glsl @@ -1,8 +1,8 @@ mat4 mx_rotationMatrix(vec3 axis, float angle) { axis = normalize(axis); - float s = sin(angle); - float c = cos(angle); + float s = mx_sin(angle); + float c = mx_cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, @@ -13,7 +13,7 @@ mat4 mx_rotationMatrix(vec3 axis, float angle) void mx_rotate_vector3(vec3 _in, float amount, vec3 axis, out vec3 result) { - float rotationRadians = radians(amount); + float rotationRadians = mx_radians(amount); mat4 m = mx_rotationMatrix(axis, rotationRadians); result = (m * vec4(_in, 1.0)).xyz; } diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index c3ee147e13..765c48c77b 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -326,30 +326,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/stdlib/genmsl/lib/mx_math.metal b/libraries/stdlib/genmsl/lib/mx_math.metal index 46a8c5d57e..cda4e867e4 100644 --- a/libraries/stdlib/genmsl/lib/mx_math.metal +++ b/libraries/stdlib/genmsl/lib/mx_math.metal @@ -4,12 +4,10 @@ float mx_square(float x) { return x*x; } - vec2 mx_square(vec2 x) { return x*x; } - vec3 mx_square(vec3 x) { return x*x; @@ -26,11 +24,12 @@ float mx_inversesqrt(float x) return ::rsqrt(x); } -#ifdef __DECL_GL_MATH_FUNCTIONS__ - -float radians(float degree) { return (degree * M_PI_F / 180.0f); } +float mx_radians(float degree) +{ + return (degree * M_PI_F / 180.0f); +} -float3x3 inverse(float3x3 m) +float3x3 mx_inverse(float3x3 m) { float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0]; float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1]; @@ -56,7 +55,7 @@ float3x3 inverse(float3x3 m) return ret; } -float4x4 inverse(float4x4 m) +float4x4 mx_inverse(float4x4 m) { float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0]; float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1]; @@ -96,17 +95,108 @@ float4x4 inverse(float4x4 m) return ret; } -template -T atan(T y_over_x) { return ::atan(y_over_x); } +float mx_sin(float x) +{ + return sin(x); +} +vec2 mx_sin(vec2 x) +{ + return sin(x); +} +vec3 mx_sin(vec3 x) +{ + return sin(x); +} +vec4 mx_sin(vec4 x) +{ + return sin(x); +} -template -T atan(T y, T x) { return ::atan2(y, x); } +float mx_cos(float x) +{ + return cos(x); +} +vec2 mx_cos(vec2 x) +{ + return cos(x); +} +vec3 mx_cos(vec3 x) +{ + return cos(x); +} +vec4 mx_cos(vec4 x) +{ + return cos(x); +} -#define lessThan(a, b) ((a) < (b)) -#define lessThanEqual(a, b) ((a) <= (b)) -#define greaterThan(a, b) ((a) > (b)) -#define greaterThanEqual(a, b) ((a) >= (b)) -#define equal(a, b) ((a) == (b)) -#define notEqual(a, b) ((a) != (b)) +float mx_tan(float x) +{ + return tan(x); +} +vec2 mx_tan(vec2 x) +{ + return tan(x); +} +vec3 mx_tan(vec3 x) +{ + return tan(x); +} +vec4 mx_tan(vec4 x) +{ + return tan(x); +} -#endif +float mx_asin(float x) +{ + return asin(x); +} +vec2 mx_asin(vec2 x) +{ + return asin(x); +} +vec3 mx_asin(vec3 x) +{ + return asin(x); +} +vec4 mx_asin(vec4 x) +{ + return asin(x); +} + +float mx_acos(float x) +{ + return acos(x); +} +vec2 mx_acos(vec2 x) +{ + return acos(x); +} +vec3 mx_acos(vec3 x) +{ + return acos(x); +} +vec4 mx_acos(vec4 x) +{ + return acos(x); +} + +float mx_atan(float y_over_x) +{ + return ::atan(y_over_x); +} +float mx_atan(float y, float x) +{ + return ::atan2(y, x); +} +vec2 mx_atan(vec2 y, vec2 x) +{ + return ::atan2(y, x); +} +vec3 mx_atan(vec3 y, vec3 x) +{ + return ::atan2(y, x); +} +vec4 mx_atan(vec4 y, vec4 x) +{ + return ::atan2(y, x); +} diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index 2f69a1bb90..ab4461cad4 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -327,30 +327,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -459,8 +459,8 @@ - - + +