Skip to content

Commit

Permalink
Merge pull request #3323 from Autodesk/gamaj/EMSUSD-612/support_mater…
Browse files Browse the repository at this point in the history
…ialx_1_38_8

EMSUSD-612 - Add support for MaterialX 1.38.8
  • Loading branch information
seando-adsk authored Sep 13, 2023
2 parents 27aea82 + a559d0e commit 28fa170
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 21 deletions.
11 changes: 11 additions & 0 deletions lib/mayaUsd/render/MaterialXGenOgsXml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ if(MaterialX_VERSION VERSION_LESS "1.38.4")
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/pbrlib/genglsl/ogsxml
)
endforeach()
elseif(MaterialX_VERSION VERSION_LESS "1.38.8")
MESSAGE(STATUS "Using 1.38.[4-7] libraries with MaterialX ${MaterialX_VERSION}")
install(FILES ${NODE_GLSL_IMPLEMENTATIONS_VERSIONED}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/adsk/maya/genglsl
)
foreach(MTLX_FILE ${LIGHT_IMPLEMENTATIONS})
string(REPLACE "libraries/" "libraries/1.38.7/" MTLX_FILE ${MTLX_FILE})
install(FILES "${MTLX_FILE}"
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/pbrlib/genglsl/ogsxml
)
endforeach()
else()
MESSAGE(STATUS "Using latest libraries with MaterialX ${MaterialX_VERSION}")
install(FILES ${NODE_GLSL_IMPLEMENTATIONS_VERSIONED}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This is the same algorithm as found in libraries\pbrlib\genglsl\lib\mx_environment_prefilter.glsl
// but adjusted for Maya. At this time we will compute a roughness based on the radiance and
// irradiance samples, so materials with small amount of roughness will look wrong.
//
// A more precise roughness computation can be done using Maya samplers, but this requires
// knowing that the Maya sampling functions are there, otherwise compilation will fail unless
// there is an IBL active in the Maya lighting.

#include "libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl"

vec3 mx_environment_irradiance(vec3 N)
{
return vec3(0);
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
return vec3(0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This is the same algorithm as found in libraries\pbrlib\genglsl\lib\mx_environment_prefilter.glsl
// but adjusted for Maya. At this time we will compute a roughness based on the radiance and
// irradiance samples, so materials with small amount of roughness will look wrong.
//
// A more precise roughness computation can be done using Maya samplers, but this requires
// knowing that the Maya sampling functions are there, otherwise compilation will fail unless
// there is an IBL active in the Maya lighting.

#include "libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl"

vec3 mx_environment_irradiance(vec3 N)
{
return g_diffuseI;
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = reflect(-V, N);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);
vec3 F = mx_compute_fresnel(NdotV, fd);
float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 Li = mix(g_specularI, g_diffuseI, avgAlpha);
return Li * F * G * comp;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This is the same algorithm as found in libraries\pbrlib\genglsl\lib\mx_environment_prefilter.glsl
// but adjusted for Maya.
//
// Since we are on a more recent versions of Maya, we have external lighting functions that can be
// called to fetch environment samples:

#include "libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl"

vec3 mx_environment_irradiance(vec3 N)
{
return mayaGetIrradianceEnvironment(N);
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = reflect(-V, N);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);
vec3 F = mx_compute_fresnel(NdotV, fd);
float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
float phongExp = mayaRoughnessToPhongExp(sqrt(avgAlpha));
vec3 Li = mayaGetSpecularEnvironment(N, V, phongExp);

return Li * F * G * comp;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// This is the same algorithm as found in libraries\pbrlib\genglsl\lib\mx_environment_fis.glsl
// but adjusted for Maya.
//
// Since we are on a more recent versions of Maya, we have external lighting functions that can be
// called to fetch environment samples:
#include "libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl"

// https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html
// Section 20.4 Equation 13
float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamples)
{
const float MIP_LEVEL_OFFSET = 1.5;
float effectiveMaxMipLevel = maxMipLevel - MIP_LEVEL_OFFSET;
float distortion = sqrt(1.0 - mx_square(dir.y));
return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0);
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
if (mayaGetSpecularEnvironmentNumLOD() == 0) {
return vec3(0);
}

// Generate tangent frame.
vec3 Y = normalize(cross(N, X));
X = cross(Y, N);
mat3 tangentToWorld = mat3(X, Y, N);

// Transform the view vector to tangent space.
V = vec3(dot(V, X), dot(V, Y), dot(V, N));

// Compute derived properties.
float NdotV = clamp(V.z, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);

// Integrate outgoing radiance using filtered importance sampling.
// http://cgg.mff.cuni.cz/~jaroslav/papers/2008-egsr-fis/2008-egsr-fis-final-embedded.pdf
vec3 radiance = vec3(0.0);
for (int i = 0; i < MX_NUM_FIS_SAMPLES; i++)
{
vec2 Xi = mx_spherical_fibonacci(i, MX_NUM_FIS_SAMPLES);

// Compute the half vector and incoming light direction.
vec3 H = mx_ggx_importance_sample_NDF(Xi, alpha);
vec3 L = -reflect(V, H);

// Compute dot products for this sample.
float NdotH = clamp(H.z, M_FLOAT_EPS, 1.0);
float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
float LdotH = VdotH;

// Sample the environment light from the given direction.
vec3 Lw = tangentToWorld * L;
float pdf = mx_ggx_PDF(H, LdotH, alpha);
float lod = mx_latlong_compute_lod(Lw, pdf, float(mayaGetSpecularEnvironmentNumLOD() - 1), MX_NUM_FIS_SAMPLES);
vec3 sampleColor = mayaSampleSpecularEnvironmentAtLOD(Lw, lod);

// Compute the Fresnel term.
vec3 F = mx_compute_fresnel(VdotH, fd);

// Compute the geometric term.
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

// Add the radiance contribution of this sample.
// From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
// incidentLight = sampleColor * NdotL
// microfacetSpecular = D * F * G / (4 * NdotL * NdotV)
// pdf = D * NdotH / (4 * VdotH)
// radiance = incidentLight * microfacetSpecular / pdf
radiance += sampleColor * F * G * VdotH / (NdotV * NdotH);
}

// Normalize and return the final radiance.
radiance /= float(MX_NUM_FIS_SAMPLES);
return radiance;
}

vec3 mx_environment_irradiance(vec3 N)
{
return mayaGetIrradianceEnvironment(N);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

vec3 mx_environment_irradiance(vec3 N)
{
return vec3(0);
return vec3(0.0);
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 roughness, int distribution, FresnelData fd)
{
return vec3(0);
return vec3(0.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ vec3 mx_environment_irradiance(vec3 N)
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = reflect(-V, N);
vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, N);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);
vec3 F = mx_compute_fresnel(NdotV, fd);
float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;
vec3 Li = mix(g_specularI, g_diffuseI, avgAlpha);
return Li * F * G * comp;
return Li * FG;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ vec3 mx_environment_irradiance(vec3 N)
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = reflect(-V, N);
vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, N);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);
vec3 F = mx_compute_fresnel(NdotV, fd);
float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;
float phongExp = mayaRoughnessToPhongExp(sqrt(avgAlpha));
vec3 Li = mayaGetSpecularEnvironment(N, V, phongExp);

return Li * F * G * comp;
return Li * FG;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
}

// Generate tangent frame.
vec3 Y = normalize(cross(N, X));
X = cross(Y, N);
X = normalize(X - dot(X, N) * N);
vec3 Y = cross(N, X);
mat3 tangentToWorld = mat3(X, Y, N);

// Transform the view vector to tangent space.
Expand All @@ -32,6 +32,7 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
// Compute derived properties.
float NdotV = clamp(V.z, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(alpha);
float G1V = mx_ggx_smith_G1(NdotV, avgAlpha);

// Integrate outgoing radiance using filtered importance sampling.
// http://cgg.mff.cuni.cz/~jaroslav/papers/2008-egsr-fis/2008-egsr-fis-final-embedded.pdf
Expand All @@ -41,18 +42,16 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
vec2 Xi = mx_spherical_fibonacci(i, MX_NUM_FIS_SAMPLES);

// Compute the half vector and incoming light direction.
vec3 H = mx_ggx_importance_sample_NDF(Xi, alpha);
vec3 L = -reflect(V, H);
vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, alpha);
vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, H, fd.ior.x) : -reflect(V, H);

// Compute dot products for this sample.
float NdotH = clamp(H.z, M_FLOAT_EPS, 1.0);
float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
float LdotH = VdotH;

// Sample the environment light from the given direction.
vec3 Lw = tangentToWorld * L;
float pdf = mx_ggx_PDF(H, LdotH, alpha);
float pdf = mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV);
float lod = mx_latlong_compute_lod(Lw, pdf, float(mayaGetSpecularEnvironmentNumLOD() - 1), MX_NUM_FIS_SAMPLES);
vec3 sampleColor = mayaSampleSpecularEnvironmentAtLOD(Lw, lod);

Expand All @@ -62,17 +61,22 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
// Compute the geometric term.
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

// Compute the combined FG term, which is inverted for refraction.
vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;

// Add the radiance contribution of this sample.
// From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
// incidentLight = sampleColor * NdotL
// microfacetSpecular = D * F * G / (4 * NdotL * NdotV)
// pdf = D * NdotH / (4 * VdotH)
// pdf = D * G1V / (4 * NdotV);
// radiance = incidentLight * microfacetSpecular / pdf
radiance += sampleColor * F * G * VdotH / (NdotV * NdotH);
radiance += sampleColor * FG;
}

// Normalize and return the final radiance.
radiance /= float(MX_NUM_FIS_SAMPLES);
// Apply the global component of the geometric term and normalize.
radiance /= G1V * float(MX_NUM_FIS_SAMPLES);

// Return the final radiance.
return radiance;
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ def testMayaSurfaces(self):
if os.getenv('MAYA_HAS_COLOR_MANAGEMENT_SUPPORT_API', 'FALSE') == 'TRUE':
suffix = "_ocio"

# MaterialX 1.38.8 has a new triplanar node with superior blending
if os.getenv('MATERIALX_VERSION', '1.38.0') >= '1.38.8':
suffix += "_blended"

mayaUtils.loadPlugin("mayaUsdPlugin")
panel = mayaUtils.activeModelPanel()
cmds.modelEditor(panel, edit=True, displayTextures=True)
Expand Down

0 comments on commit 28fa170

Please sign in to comment.