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 @@
-
-
+
+