Ajout du projet Depths sur Git
This commit is contained in:
+69
@@ -0,0 +1,69 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
|
||||
{
|
||||
// Generate tangent frame.
|
||||
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.
|
||||
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);
|
||||
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
|
||||
vec3 radiance = vec3(0.0);
|
||||
int envRadianceSamples = $envRadianceSamples;
|
||||
for (int i = 0; i < envRadianceSamples; i++)
|
||||
{
|
||||
vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples);
|
||||
|
||||
// Compute the half vector and incoming light direction.
|
||||
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 NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
|
||||
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
// Sample the environment light from the given direction.
|
||||
vec3 Lw = tangentToWorld * L;
|
||||
float pdf = mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV);
|
||||
float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
|
||||
vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
|
||||
|
||||
// Compute the Fresnel term.
|
||||
vec3 F = mx_compute_fresnel(VdotH, fd);
|
||||
|
||||
// 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 * G1V / (4 * NdotV);
|
||||
// radiance = incidentLight * microfacetSpecular / pdf
|
||||
radiance += sampleColor * FG;
|
||||
}
|
||||
|
||||
// Apply the global component of the geometric term and normalize.
|
||||
radiance /= G1V * float(envRadianceSamples);
|
||||
|
||||
// Return the final radiance.
|
||||
return radiance * $envLightIntensity;
|
||||
}
|
||||
|
||||
vec3 mx_environment_irradiance(vec3 N)
|
||||
{
|
||||
vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
|
||||
return Li * $envLightIntensity;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 roughness, int distribution, FresnelData fd)
|
||||
{
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
vec3 mx_environment_irradiance(vec3 N)
|
||||
{
|
||||
return vec3(0.0);
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
// Return the mip level associated with the given alpha in a prefiltered environment.
|
||||
float mx_latlong_alpha_to_lod(float alpha)
|
||||
{
|
||||
float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375;
|
||||
return lodBias * float($envRadianceMips - 1);
|
||||
}
|
||||
|
||||
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 = 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 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;
|
||||
|
||||
vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance);
|
||||
return Li * FG * $envLightIntensity;
|
||||
}
|
||||
|
||||
vec3 mx_environment_irradiance(vec3 N)
|
||||
{
|
||||
vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
|
||||
return Li * $envLightIntensity;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#include "mx_microfacet_sheen.glsl"
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
vec3 mx_generate_dir_albedo_table()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / $albedoTableSize;
|
||||
vec2 ggxDirAlbedo = mx_ggx_dir_albedo(uv.x, uv.y, vec3(1, 0, 0), vec3(0, 1, 0)).xy;
|
||||
float sheenDirAlbedo = mx_imageworks_sheen_dir_albedo(uv.x, uv.y);
|
||||
return vec3(ggxDirAlbedo, sheenDirAlbedo);
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
// Construct an orthonormal basis from a unit vector.
|
||||
// https://graphics.pixar.com/library/OrthonormalB/paper.pdf
|
||||
mat3 mx_orthonormal_basis(vec3 N)
|
||||
{
|
||||
float sign = (N.z < 0.0) ? -1.0 : 1.0;
|
||||
float a = -1.0 / (sign + N.z);
|
||||
float b = N.x * N.y * a;
|
||||
vec3 X = vec3(1.0 + sign * N.x * N.x * a, sign * b, -sign * N.x);
|
||||
vec3 Y = vec3(b, sign + N.y * N.y * a, -N.y);
|
||||
return mat3(X, Y, N);
|
||||
}
|
||||
|
||||
// Return the alpha associated with the given mip level in a prefiltered environment.
|
||||
float mx_latlong_lod_to_alpha(float lod)
|
||||
{
|
||||
float lodBias = lod / float($envRadianceMips - 1);
|
||||
return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375);
|
||||
}
|
||||
|
||||
// The inverse of mx_latlong_projection.
|
||||
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);
|
||||
|
||||
return vec3(x, y, z);
|
||||
}
|
||||
|
||||
vec3 mx_generate_prefilter_env()
|
||||
{
|
||||
// The tangent view vector is aligned with the normal.
|
||||
vec3 V = vec3(0.0, 0.0, 1.0);
|
||||
float NdotV = 1.0;
|
||||
|
||||
// Compute derived properties.
|
||||
vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(textureSize($envRadiance, 0));
|
||||
vec3 worldN = mx_latlong_map_projection_inverse(uv);
|
||||
mat3 tangentToWorld = mx_orthonormal_basis(worldN);
|
||||
float alpha = mx_latlong_lod_to_alpha(float($envPrefilterMip));
|
||||
float G1V = mx_ggx_smith_G1(NdotV, alpha);
|
||||
|
||||
// Integrate the LD term for the given environment and alpha.
|
||||
vec3 radiance = vec3(0.0, 0.0, 0.0);
|
||||
float weight = 0.0;
|
||||
int envRadianceSamples = 1024;
|
||||
for (int i = 0; i < envRadianceSamples; i++)
|
||||
{
|
||||
vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples);
|
||||
|
||||
// Compute the half vector and incoming light direction.
|
||||
vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, vec2(alpha));
|
||||
vec3 L = -V + 2.0 * H.z * H;
|
||||
|
||||
// Compute dot products for this sample.
|
||||
float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
|
||||
|
||||
// Compute the geometric term.
|
||||
float G = mx_ggx_smith_G2(NdotL, NdotV, alpha);
|
||||
|
||||
// Sample the environment light from the given direction.
|
||||
vec3 Lw = tangentToWorld * L;
|
||||
float pdf = mx_ggx_NDF(H, vec2(alpha)) * G1V / (4.0 * NdotV);
|
||||
float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
|
||||
vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
|
||||
|
||||
// Add the radiance contribution of this sample.
|
||||
radiance += G * sampleColor;
|
||||
weight += G;
|
||||
}
|
||||
|
||||
return radiance / weight;
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
#define M_PI 3.1415926535897932
|
||||
#define M_PI_INV (1.0 / M_PI)
|
||||
|
||||
float mx_pow5(float x)
|
||||
{
|
||||
return mx_square(mx_square(x)) * x;
|
||||
}
|
||||
|
||||
// Standard Schlick Fresnel
|
||||
float mx_fresnel_schlick(float cosTheta, float F0)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return F0 + (1.0 - F0) * x5;
|
||||
}
|
||||
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return F0 + (1.0 - F0) * x5;
|
||||
}
|
||||
|
||||
// Generalized Schlick Fresnel
|
||||
float mx_fresnel_schlick(float cosTheta, float F0, float F90)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return mix(F0, F90, x5);
|
||||
}
|
||||
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0, vec3 F90)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return mix(F0, F90, x5);
|
||||
}
|
||||
|
||||
// Generalized Schlick Fresnel with a variable exponent
|
||||
float mx_fresnel_schlick(float cosTheta, float F0, float F90, float exponent)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
return mix(F0, F90, pow(x, exponent));
|
||||
}
|
||||
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0, vec3 F90, float exponent)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
return mix(F0, F90, pow(x, exponent));
|
||||
}
|
||||
|
||||
// Enforce that the given normal is forward-facing from the specified view direction.
|
||||
vec3 mx_forward_facing_normal(vec3 N, vec3 V)
|
||||
{
|
||||
return (dot(N, V) < 0.0) ? -N : N;
|
||||
}
|
||||
|
||||
// https://www.graphics.rwth-aachen.de/publication/2/jgt.pdf
|
||||
float mx_golden_ratio_sequence(int i)
|
||||
{
|
||||
const float GOLDEN_RATIO = 1.6180339887498948;
|
||||
return fract((float(i) + 1.0) * GOLDEN_RATIO);
|
||||
}
|
||||
|
||||
// https://people.irisa.fr/Ricardo.Marques/articles/2013/SF_CGF.pdf
|
||||
vec2 mx_spherical_fibonacci(int i, int numSamples)
|
||||
{
|
||||
return vec2((float(i) + 0.5) / float(numSamples), mx_golden_ratio_sequence(i));
|
||||
}
|
||||
|
||||
// Generate a uniform-weighted sample in the unit hemisphere.
|
||||
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,
|
||||
cosTheta);
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#include "mx_microfacet.glsl"
|
||||
|
||||
// Based on the OSL implementation of Oren-Nayar diffuse, which is in turn
|
||||
// based on https://mimosa-pudica.net/improved-oren-nayar.html.
|
||||
float mx_oren_nayar_diffuse(vec3 L, vec3 V, vec3 N, float NdotL, float roughness)
|
||||
{
|
||||
float LdotV = clamp(dot(L, V), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
float s = LdotV - NdotL * NdotV;
|
||||
float stinv = (s > 0.0f) ? s / max(NdotL, NdotV) : 0.0;
|
||||
|
||||
float sigma2 = mx_square(roughness * M_PI);
|
||||
float A = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));
|
||||
float B = 0.45 * sigma2 / (sigma2 + 0.09);
|
||||
|
||||
return A + B * stinv;
|
||||
}
|
||||
|
||||
// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
|
||||
// Section 5.3
|
||||
float mx_burley_diffuse(vec3 L, vec3 V, vec3 N, float NdotL, float roughness)
|
||||
{
|
||||
vec3 H = normalize(L + V);
|
||||
float LdotH = clamp(dot(L, H), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
float F90 = 0.5 + (2.0 * roughness * mx_square(LdotH));
|
||||
float refL = mx_fresnel_schlick(NdotL, 1.0, F90);
|
||||
float refV = mx_fresnel_schlick(NdotV, 1.0, F90);
|
||||
return refL * refV;
|
||||
}
|
||||
|
||||
// Compute the directional albedo component of Burley diffuse for the given
|
||||
// view angle and roughness. Curve fit provided by Stephen Hill.
|
||||
float mx_burley_diffuse_dir_albedo(float NdotV, float roughness)
|
||||
{
|
||||
float x = NdotV;
|
||||
float fit0 = 0.97619 - 0.488095 * mx_pow5(1.0 - x);
|
||||
float fit1 = 1.55754 + (-2.02221 + (2.56283 - 1.06244 * x) * x) * x;
|
||||
return mix(fit0, fit1, roughness);
|
||||
}
|
||||
|
||||
// Evaluate the Burley diffusion profile for the given distance and diffusion shape.
|
||||
// Based on https://graphics.pixar.com/library/ApproxBSSRDF/
|
||||
vec3 mx_burley_diffusion_profile(float dist, vec3 shape)
|
||||
{
|
||||
vec3 num1 = exp(-shape * dist);
|
||||
vec3 num2 = exp(-shape * dist / 3.0);
|
||||
float denom = max(dist, M_FLOAT_EPS);
|
||||
return (num1 + num2) / denom;
|
||||
}
|
||||
|
||||
// Integrate the Burley diffusion profile over a sphere of the given radius.
|
||||
// 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));
|
||||
|
||||
// Estimate the Burley diffusion shape from mean free path.
|
||||
vec3 shape = vec3(1.0) / max(mfp, 0.1);
|
||||
|
||||
// Integrate the profile over the sphere.
|
||||
vec3 sumD = vec3(0.0);
|
||||
vec3 sumR = vec3(0.0);
|
||||
const int SAMPLE_COUNT = 32;
|
||||
const float SAMPLE_WIDTH = (2.0 * M_PI) / float(SAMPLE_COUNT);
|
||||
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));
|
||||
vec3 R = mx_burley_diffusion_profile(dist, shape);
|
||||
sumD += R * max(cos(theta + x), 0.0);
|
||||
sumR += R;
|
||||
}
|
||||
|
||||
return sumD / sumR;
|
||||
}
|
||||
|
||||
vec3 mx_subsurface_scattering_approx(vec3 N, vec3 L, vec3 P, vec3 albedo, vec3 mfp)
|
||||
{
|
||||
float curvature = length(fwidth(N)) / length(fwidth(P));
|
||||
float radius = 1.0 / max(curvature, 0.01);
|
||||
return albedo * mx_integrate_burley_diffusion(N, L, radius, mfp) / vec3(M_PI);
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
#include "mx_microfacet.glsl"
|
||||
|
||||
// http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
|
||||
// Equation 2
|
||||
float mx_imageworks_sheen_NDF(float NdotH, float roughness)
|
||||
{
|
||||
float invRoughness = 1.0 / max(roughness, 0.005);
|
||||
float cos2 = NdotH * NdotH;
|
||||
float sin2 = 1.0 - cos2;
|
||||
return (2.0 + invRoughness) * pow(sin2, invRoughness * 0.5) / (2.0 * M_PI);
|
||||
}
|
||||
|
||||
float mx_imageworks_sheen_brdf(float NdotL, float NdotV, float NdotH, float roughness)
|
||||
{
|
||||
// Microfacet distribution.
|
||||
float D = mx_imageworks_sheen_NDF(NdotH, roughness);
|
||||
|
||||
// Fresnel and geometry terms are ignored.
|
||||
float F = 1.0;
|
||||
float G = 1.0;
|
||||
|
||||
// We use a smoother denominator, as in:
|
||||
// https://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
|
||||
return D * F * G / (4.0 * (NdotL + NdotV - NdotL*NdotV));
|
||||
}
|
||||
|
||||
// Rational quadratic fit to Monte Carlo data for Imageworks sheen directional albedo.
|
||||
float mx_imageworks_sheen_dir_albedo_analytic(float NdotV, float roughness)
|
||||
{
|
||||
vec2 r = vec2(13.67300, 1.0) +
|
||||
vec2(-68.78018, 61.57746) * NdotV +
|
||||
vec2(799.08825, 442.78211) * roughness +
|
||||
vec2(-905.00061, 2597.49308) * NdotV * roughness +
|
||||
vec2(60.28956, 121.81241) * mx_square(NdotV) +
|
||||
vec2(1086.96473, 3045.55075) * mx_square(roughness);
|
||||
return r.x / r.y;
|
||||
}
|
||||
|
||||
float mx_imageworks_sheen_dir_albedo_table_lookup(float NdotV, float roughness)
|
||||
{
|
||||
#if DIRECTIONAL_ALBEDO_METHOD == 1
|
||||
if (textureSize($albedoTable, 0).x > 1)
|
||||
{
|
||||
return texture($albedoTable, vec2(NdotV, roughness)).b;
|
||||
}
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float mx_imageworks_sheen_dir_albedo_monte_carlo(float NdotV, float roughness)
|
||||
{
|
||||
NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
|
||||
vec3 V = vec3(sqrt(1.0f - mx_square(NdotV)), 0, NdotV);
|
||||
|
||||
float radiance = 0.0;
|
||||
const int SAMPLE_COUNT = 64;
|
||||
for (int i = 0; i < SAMPLE_COUNT; i++)
|
||||
{
|
||||
vec2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);
|
||||
|
||||
// Compute the incoming light direction and half vector.
|
||||
vec3 L = mx_uniform_sample_hemisphere(Xi);
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
// Compute dot products for this sample.
|
||||
float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
|
||||
float NdotH = clamp(H.z, M_FLOAT_EPS, 1.0);
|
||||
|
||||
// Compute sheen reflectance.
|
||||
float reflectance = mx_imageworks_sheen_brdf(NdotL, NdotV, NdotH, roughness);
|
||||
|
||||
// Add the radiance contribution of this sample.
|
||||
// uniform_pdf = 1 / (2 * PI)
|
||||
// radiance = reflectance * NdotL / uniform_pdf;
|
||||
radiance += reflectance * NdotL * 2.0 * M_PI;
|
||||
}
|
||||
|
||||
// Return the final directional albedo.
|
||||
return radiance / float(SAMPLE_COUNT);
|
||||
}
|
||||
|
||||
float mx_imageworks_sheen_dir_albedo(float NdotV, float roughness)
|
||||
{
|
||||
#if DIRECTIONAL_ALBEDO_METHOD == 0
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo_analytic(NdotV, roughness);
|
||||
#elif DIRECTIONAL_ALBEDO_METHOD == 1
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo_table_lookup(NdotV, roughness);
|
||||
#else
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo_monte_carlo(NdotV, roughness);
|
||||
#endif
|
||||
return clamp(dirAlbedo, 0.0, 1.0);
|
||||
}
|
||||
+606
@@ -0,0 +1,606 @@
|
||||
#include "mx_microfacet.glsl"
|
||||
|
||||
// Fresnel model options.
|
||||
const int FRESNEL_MODEL_DIELECTRIC = 0;
|
||||
const int FRESNEL_MODEL_CONDUCTOR = 1;
|
||||
const int FRESNEL_MODEL_SCHLICK = 2;
|
||||
const int FRESNEL_MODEL_AIRY = 3;
|
||||
const int FRESNEL_MODEL_SCHLICK_AIRY = 4;
|
||||
|
||||
// XYZ to CIE 1931 RGB color space (using neutral E illuminant)
|
||||
const mat3 XYZ_TO_RGB = mat3(2.3706743, -0.5138850, 0.0052982, -0.9000405, 1.4253036, -0.0146949, -0.4706338, 0.0885814, 1.0093968);
|
||||
|
||||
// Parameters for Fresnel calculations.
|
||||
struct FresnelData
|
||||
{
|
||||
int model;
|
||||
|
||||
// Physical Fresnel
|
||||
vec3 ior;
|
||||
vec3 extinction;
|
||||
|
||||
// Generalized Schlick Fresnel
|
||||
vec3 F0;
|
||||
vec3 F90;
|
||||
float exponent;
|
||||
|
||||
// Thin film
|
||||
float tf_thickness;
|
||||
float tf_ior;
|
||||
|
||||
// Refraction
|
||||
bool refraction;
|
||||
|
||||
#ifdef __METAL__
|
||||
FresnelData(int _model = 0,
|
||||
vec3 _ior = vec3(0.0f),
|
||||
vec3 _extinction = vec3(0.0f),
|
||||
vec3 _F0 = vec3(0.0f),
|
||||
vec3 _F90 = vec3(0.0f),
|
||||
float _exponent = 0.0f,
|
||||
float _tf_thickness = 0.0f,
|
||||
float _tf_ior = 0.0f,
|
||||
bool _refraction = false) :
|
||||
model(_model),
|
||||
ior(_ior),
|
||||
extinction(_extinction),
|
||||
F0(_F0), F90(_F90), exponent(_exponent),
|
||||
tf_thickness(_tf_thickness),
|
||||
tf_ior(_tf_ior),
|
||||
refraction(_refraction) {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
|
||||
// Appendix B.2 Equation 13
|
||||
float mx_ggx_NDF(vec3 H, vec2 alpha)
|
||||
{
|
||||
vec2 He = H.xy / alpha;
|
||||
float denom = dot(He, He) + mx_square(H.z);
|
||||
return 1.0 / (M_PI * alpha.x * alpha.y * mx_square(denom));
|
||||
}
|
||||
|
||||
// https://ggx-research.github.io/publication/2023/06/09/publication-ggx.html
|
||||
vec3 mx_ggx_importance_sample_VNDF(vec2 Xi, vec3 V, vec2 alpha)
|
||||
{
|
||||
// Transform the view direction to the hemisphere configuration.
|
||||
V = normalize(vec3(V.xy * alpha, V.z));
|
||||
|
||||
// Sample a spherical cap in (-V.z, 1].
|
||||
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);
|
||||
vec3 c = vec3(x, y, z);
|
||||
|
||||
// Compute the microfacet normal.
|
||||
vec3 H = c + V;
|
||||
|
||||
// Transform the microfacet normal back to the ellipsoid configuration.
|
||||
H = normalize(vec3(H.xy * alpha, max(H.z, 0.0)));
|
||||
|
||||
return H;
|
||||
}
|
||||
|
||||
// https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
|
||||
// Equation 34
|
||||
float mx_ggx_smith_G1(float cosTheta, float alpha)
|
||||
{
|
||||
float cosTheta2 = mx_square(cosTheta);
|
||||
float tanTheta2 = (1.0 - cosTheta2) / cosTheta2;
|
||||
return 2.0 / (1.0 + sqrt(1.0 + mx_square(alpha) * tanTheta2));
|
||||
}
|
||||
|
||||
// Height-correlated Smith masking-shadowing
|
||||
// http://jcgt.org/published/0003/02/03/paper.pdf
|
||||
// Equations 72 and 99
|
||||
float mx_ggx_smith_G2(float NdotL, float NdotV, float alpha)
|
||||
{
|
||||
float alpha2 = mx_square(alpha);
|
||||
float lambdaL = sqrt(alpha2 + (1.0 - alpha2) * mx_square(NdotL));
|
||||
float lambdaV = sqrt(alpha2 + (1.0 - alpha2) * mx_square(NdotV));
|
||||
return 2.0 / (lambdaL / NdotL + lambdaV / NdotV);
|
||||
}
|
||||
|
||||
// Rational quadratic fit to Monte Carlo data for GGX directional albedo.
|
||||
vec3 mx_ggx_dir_albedo_analytic(float NdotV, float alpha, vec3 F0, vec3 F90)
|
||||
{
|
||||
float x = NdotV;
|
||||
float y = alpha;
|
||||
float x2 = mx_square(x);
|
||||
float y2 = mx_square(y);
|
||||
vec4 r = vec4(0.1003, 0.9345, 1.0, 1.0) +
|
||||
vec4(-0.6303, -2.323, -1.765, 0.2281) * x +
|
||||
vec4(9.748, 2.229, 8.263, 15.94) * y +
|
||||
vec4(-2.038, -3.748, 11.53, -55.83) * x * y +
|
||||
vec4(29.34, 1.424, 28.96, 13.08) * x2 +
|
||||
vec4(-8.245, -0.7684, -7.507, 41.26) * y2 +
|
||||
vec4(-26.44, 1.436, -36.11, 54.9) * x2 * y +
|
||||
vec4(19.99, 0.2913, 15.86, 300.2) * x * y2 +
|
||||
vec4(-5.448, 0.6286, 33.37, -285.1) * x2 * y2;
|
||||
vec2 AB = clamp(r.xy / r.zw, 0.0, 1.0);
|
||||
return F0 * AB.x + F90 * AB.y;
|
||||
}
|
||||
|
||||
vec3 mx_ggx_dir_albedo_table_lookup(float NdotV, float alpha, vec3 F0, vec3 F90)
|
||||
{
|
||||
#if DIRECTIONAL_ALBEDO_METHOD == 1
|
||||
if (textureSize($albedoTable, 0).x > 1)
|
||||
{
|
||||
vec2 AB = texture($albedoTable, vec2(NdotV, alpha)).rg;
|
||||
return F0 * AB.x + F90 * AB.y;
|
||||
}
|
||||
#endif
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
|
||||
vec3 mx_ggx_dir_albedo_monte_carlo(float NdotV, float alpha, vec3 F0, vec3 F90)
|
||||
{
|
||||
NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
|
||||
vec3 V = vec3(sqrt(1.0 - mx_square(NdotV)), 0, NdotV);
|
||||
|
||||
vec2 AB = vec2(0.0);
|
||||
const int SAMPLE_COUNT = 64;
|
||||
for (int i = 0; i < SAMPLE_COUNT; i++)
|
||||
{
|
||||
vec2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);
|
||||
|
||||
// Compute the half vector and incoming light direction.
|
||||
vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, vec2(alpha));
|
||||
vec3 L = -reflect(V, H);
|
||||
|
||||
// Compute dot products for this sample.
|
||||
float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
|
||||
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
// Compute the Fresnel term.
|
||||
float Fc = mx_fresnel_schlick(VdotH, 0.0, 1.0);
|
||||
|
||||
// Compute the per-sample geometric term.
|
||||
// https://hal.inria.fr/hal-00996995v2/document, Algorithm 2
|
||||
float G2 = mx_ggx_smith_G2(NdotL, NdotV, alpha);
|
||||
|
||||
// Add the contribution of this sample.
|
||||
AB += vec2(G2 * (1.0 - Fc), G2 * Fc);
|
||||
}
|
||||
|
||||
// Apply the global component of the geometric term and normalize.
|
||||
AB /= mx_ggx_smith_G1(NdotV, alpha) * float(SAMPLE_COUNT);
|
||||
|
||||
// Return the final directional albedo.
|
||||
return F0 * AB.x + F90 * AB.y;
|
||||
}
|
||||
|
||||
vec3 mx_ggx_dir_albedo(float NdotV, float alpha, vec3 F0, vec3 F90)
|
||||
{
|
||||
#if DIRECTIONAL_ALBEDO_METHOD == 0
|
||||
return mx_ggx_dir_albedo_analytic(NdotV, alpha, F0, F90);
|
||||
#elif DIRECTIONAL_ALBEDO_METHOD == 1
|
||||
return mx_ggx_dir_albedo_table_lookup(NdotV, alpha, F0, F90);
|
||||
#else
|
||||
return mx_ggx_dir_albedo_monte_carlo(NdotV, alpha, F0, F90);
|
||||
#endif
|
||||
}
|
||||
|
||||
float mx_ggx_dir_albedo(float NdotV, float alpha, float F0, float F90)
|
||||
{
|
||||
return mx_ggx_dir_albedo(NdotV, alpha, vec3(F0), vec3(F90)).x;
|
||||
}
|
||||
|
||||
// https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf
|
||||
// Equations 14 and 16
|
||||
vec3 mx_ggx_energy_compensation(float NdotV, float alpha, vec3 Fss)
|
||||
{
|
||||
float Ess = mx_ggx_dir_albedo(NdotV, alpha, 1.0, 1.0);
|
||||
return 1.0 + Fss * (1.0 - Ess) / Ess;
|
||||
}
|
||||
|
||||
float mx_ggx_energy_compensation(float NdotV, float alpha, float Fss)
|
||||
{
|
||||
return mx_ggx_energy_compensation(NdotV, alpha, vec3(Fss)).x;
|
||||
}
|
||||
|
||||
// Compute the average of an anisotropic alpha pair.
|
||||
float mx_average_alpha(vec2 alpha)
|
||||
{
|
||||
return sqrt(alpha.x * alpha.y);
|
||||
}
|
||||
|
||||
// Convert a real-valued index of refraction to normal-incidence reflectivity.
|
||||
float mx_ior_to_f0(float ior)
|
||||
{
|
||||
return mx_square((ior - 1.0) / (ior + 1.0));
|
||||
}
|
||||
|
||||
// Convert normal-incidence reflectivity to real-valued index of refraction.
|
||||
float mx_f0_to_ior(float F0)
|
||||
{
|
||||
float sqrtF0 = sqrt(clamp(F0, 0.01, 0.99));
|
||||
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
|
||||
}
|
||||
|
||||
vec3 mx_f0_to_ior_colored(vec3 F0)
|
||||
{
|
||||
vec3 sqrtF0 = sqrt(clamp(F0, 0.01, 0.99));
|
||||
return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0);
|
||||
}
|
||||
|
||||
// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
|
||||
float mx_fresnel_dielectric(float cosTheta, float ior)
|
||||
{
|
||||
if (cosTheta < 0.0)
|
||||
return 1.0;
|
||||
|
||||
float g = ior*ior + cosTheta*cosTheta - 1.0;
|
||||
// Check for total internal reflection
|
||||
if (g < 0.0)
|
||||
return 1.0;
|
||||
|
||||
g = sqrt(g);
|
||||
float gmc = g - cosTheta;
|
||||
float gpc = g + cosTheta;
|
||||
float x = gmc / gpc;
|
||||
float y = (gpc * cosTheta - 1.0) / (gmc * cosTheta + 1.0);
|
||||
return 0.5 * x * x * (1.0 + y * y);
|
||||
}
|
||||
|
||||
void mx_fresnel_dielectric_polarized(float cosTheta, float n, out float Rp, out float Rs)
|
||||
{
|
||||
if (cosTheta < 0.0) {
|
||||
Rp = 1.0;
|
||||
Rs = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
float cosTheta2 = cosTheta * cosTheta;
|
||||
float sinTheta2 = 1.0 - cosTheta2;
|
||||
float n2 = n * n;
|
||||
|
||||
float t0 = n2 - sinTheta2;
|
||||
float a2plusb2 = sqrt(t0 * t0);
|
||||
float t1 = a2plusb2 + cosTheta2;
|
||||
float a = sqrt(max(0.5 * (a2plusb2 + t0), 0.0));
|
||||
float t2 = 2.0 * a * cosTheta;
|
||||
Rs = (t1 - t2) / (t1 + t2);
|
||||
|
||||
float t3 = cosTheta2 * a2plusb2 + sinTheta2 * sinTheta2;
|
||||
float t4 = t2 * sinTheta2;
|
||||
Rp = Rs * (t3 - t4) / (t3 + t4);
|
||||
}
|
||||
|
||||
void mx_fresnel_dielectric_polarized(float cosTheta, float eta1, float eta2, out float Rp, out float Rs)
|
||||
{
|
||||
float n = eta2 / eta1;
|
||||
mx_fresnel_dielectric_polarized(cosTheta, n, Rp, Rs);
|
||||
}
|
||||
|
||||
void mx_fresnel_conductor_polarized(float cosTheta, vec3 n, vec3 k, out vec3 Rp, out vec3 Rs)
|
||||
{
|
||||
cosTheta = clamp(cosTheta, 0.0, 1.0);
|
||||
float cosTheta2 = cosTheta * cosTheta;
|
||||
float sinTheta2 = 1.0 - cosTheta2;
|
||||
vec3 n2 = n * n;
|
||||
vec3 k2 = k * k;
|
||||
|
||||
vec3 t0 = n2 - k2 - vec3(sinTheta2);
|
||||
vec3 a2plusb2 = sqrt(t0 * t0 + 4.0 * n2 * k2);
|
||||
vec3 t1 = a2plusb2 + vec3(cosTheta2);
|
||||
vec3 a = sqrt(max(0.5 * (a2plusb2 + t0), 0.0));
|
||||
vec3 t2 = 2.0 * a * cosTheta;
|
||||
Rs = (t1 - t2) / (t1 + t2);
|
||||
|
||||
vec3 t3 = cosTheta2 * a2plusb2 + vec3(sinTheta2 * sinTheta2);
|
||||
vec3 t4 = t2 * sinTheta2;
|
||||
Rp = Rs * (t3 - t4) / (t3 + t4);
|
||||
}
|
||||
|
||||
void mx_fresnel_conductor_polarized(float cosTheta, float eta1, vec3 eta2, vec3 kappa2, out vec3 Rp, out vec3 Rs)
|
||||
{
|
||||
vec3 n = eta2 / eta1;
|
||||
vec3 k = kappa2 / eta1;
|
||||
mx_fresnel_conductor_polarized(cosTheta, n, k, Rp, Rs);
|
||||
}
|
||||
|
||||
vec3 mx_fresnel_conductor(float cosTheta, vec3 n, vec3 k)
|
||||
{
|
||||
vec3 Rp, Rs;
|
||||
mx_fresnel_conductor_polarized(cosTheta, n, k, Rp, Rs);
|
||||
return 0.5 * (Rp + Rs);
|
||||
}
|
||||
|
||||
// Phase shift due to a dielectric material
|
||||
void mx_fresnel_dielectric_phase_polarized(float cosTheta, float eta1, float eta2, out float phiP, out float phiS)
|
||||
{
|
||||
float cosB = cos(atan(eta2 / eta1)); // Brewster's angle
|
||||
if (eta2 > eta1) {
|
||||
phiP = cosTheta < cosB ? M_PI : 0.0f;
|
||||
phiS = 0.0f;
|
||||
} else {
|
||||
phiP = cosTheta < cosB ? 0.0f : M_PI;
|
||||
phiS = M_PI;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase shift due to a conducting material
|
||||
void mx_fresnel_conductor_phase_polarized(float cosTheta, float eta1, vec3 eta2, vec3 kappa2, out vec3 phiP, out vec3 phiS)
|
||||
{
|
||||
if (dot(kappa2, kappa2) == 0.0 && eta2.x == eta2.y && eta2.y == eta2.z) {
|
||||
// Use dielectric formula to increase performance
|
||||
float phiPx, phiSx;
|
||||
mx_fresnel_dielectric_phase_polarized(cosTheta, eta1, eta2.x, phiPx, phiSx);
|
||||
phiP = vec3(phiPx, phiPx, phiPx);
|
||||
phiS = vec3(phiSx, phiSx, phiSx);
|
||||
return;
|
||||
}
|
||||
vec3 k2 = kappa2 / eta2;
|
||||
vec3 sinThetaSqr = vec3(1.0) - cosTheta * cosTheta;
|
||||
vec3 A = eta2*eta2*(vec3(1.0)-k2*k2) - eta1*eta1*sinThetaSqr;
|
||||
vec3 B = sqrt(A*A + mx_square(2.0*eta2*eta2*k2));
|
||||
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));
|
||||
}
|
||||
|
||||
// Evaluation XYZ sensitivity curves in Fourier space
|
||||
vec3 mx_eval_sensitivity(float opd, vec3 shift)
|
||||
{
|
||||
// Use Gaussian fits, given by 3 parameters: val, pos and var
|
||||
float phase = 2.0*M_PI * opd;
|
||||
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);
|
||||
return xyz / 1.0685e-7;
|
||||
}
|
||||
|
||||
// A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence
|
||||
// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html
|
||||
vec3 mx_fresnel_airy(float cosTheta, vec3 ior, vec3 extinction, float tf_thickness, float tf_ior,
|
||||
vec3 f0, vec3 f90, float exponent, bool use_schlick)
|
||||
{
|
||||
// Convert nm -> m
|
||||
float d = tf_thickness * 1.0e-9;
|
||||
|
||||
// Assume vacuum on the outside
|
||||
float eta1 = 1.0;
|
||||
float eta2 = max(tf_ior, eta1);
|
||||
vec3 eta3 = use_schlick ? mx_f0_to_ior_colored(f0) : ior;
|
||||
vec3 kappa3 = use_schlick ? vec3(0.0) : extinction;
|
||||
|
||||
// Compute the Spectral versions of the Fresnel reflectance and
|
||||
// transmitance for each interface.
|
||||
float R12p, T121p, R12s, T121s;
|
||||
vec3 R23p, R23s;
|
||||
|
||||
// Reflected and transmitted parts in the thin film
|
||||
mx_fresnel_dielectric_polarized(cosTheta, eta1, eta2, R12p, R12s);
|
||||
|
||||
// Reflected part by the base
|
||||
float scale = eta1 / eta2;
|
||||
float cosThetaTSqr = 1.0 - (1.0-cosTheta*cosTheta) * scale*scale;
|
||||
float cosTheta2 = sqrt(cosThetaTSqr);
|
||||
if (use_schlick)
|
||||
{
|
||||
vec3 f = mx_fresnel_schlick(cosTheta2, f0, f90, exponent);
|
||||
R23p = 0.5 * f;
|
||||
R23s = 0.5 * f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx_fresnel_conductor_polarized(cosTheta2, eta2, eta3, kappa3, R23p, R23s);
|
||||
}
|
||||
|
||||
// Check for total internal reflection
|
||||
if (cosThetaTSqr <= 0.0f)
|
||||
{
|
||||
R12s = 1.0;
|
||||
R12p = 1.0;
|
||||
}
|
||||
|
||||
// Compute the transmission coefficients
|
||||
T121p = 1.0 - R12p;
|
||||
T121s = 1.0 - R12s;
|
||||
|
||||
// Optical path difference
|
||||
float D = 2.0 * eta2 * d * cosTheta2;
|
||||
|
||||
float phi21p, phi21s;
|
||||
vec3 phi23p, phi23s, r123s, r123p;
|
||||
|
||||
// Evaluate the phase shift
|
||||
mx_fresnel_dielectric_phase_polarized(cosTheta, eta1, eta2, phi21p, phi21s);
|
||||
if (use_schlick)
|
||||
{
|
||||
phi23p = vec3(
|
||||
(eta3[0] < eta2) ? M_PI : 0.0,
|
||||
(eta3[1] < eta2) ? M_PI : 0.0,
|
||||
(eta3[2] < eta2) ? M_PI : 0.0);
|
||||
phi23s = phi23p;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx_fresnel_conductor_phase_polarized(cosTheta2, eta2, eta3, kappa3, phi23p, phi23s);
|
||||
}
|
||||
|
||||
phi21p = M_PI - phi21p;
|
||||
phi21s = M_PI - phi21s;
|
||||
|
||||
r123p = max(vec3(0.0), sqrt(R12p*R23p));
|
||||
r123s = max(vec3(0.0), sqrt(R12s*R23s));
|
||||
|
||||
// Evaluate iridescence term
|
||||
vec3 I = vec3(0.0);
|
||||
vec3 C0, Cm, Sm;
|
||||
|
||||
// Iridescence term using spectral antialiasing for Parallel polarization
|
||||
|
||||
vec3 S0 = vec3(1.0);
|
||||
|
||||
// Reflectance term for m=0 (DC term amplitude)
|
||||
vec3 Rs = (T121p*T121p*R23p) / (vec3(1.0) - R12p*R23p);
|
||||
C0 = R12p + Rs;
|
||||
I += C0 * S0;
|
||||
|
||||
// Reflectance term for m>0 (pairs of diracs)
|
||||
Cm = Rs - T121p;
|
||||
for (int m=1; m<=2; ++m)
|
||||
{
|
||||
Cm *= r123p;
|
||||
Sm = 2.0 * mx_eval_sensitivity(float(m)*D, float(m)*(phi23p+vec3(phi21p)));
|
||||
I += Cm*Sm;
|
||||
}
|
||||
|
||||
// Iridescence term using spectral antialiasing for Perpendicular polarization
|
||||
|
||||
// Reflectance term for m=0 (DC term amplitude)
|
||||
vec3 Rp = (T121s*T121s*R23s) / (vec3(1.0) - R12s*R23s);
|
||||
C0 = R12s + Rp;
|
||||
I += C0 * S0;
|
||||
|
||||
// Reflectance term for m>0 (pairs of diracs)
|
||||
Cm = Rp - T121s ;
|
||||
for (int m=1; m<=2; ++m)
|
||||
{
|
||||
Cm *= r123s;
|
||||
Sm = 2.0 * mx_eval_sensitivity(float(m)*D, float(m)*(phi23s+vec3(phi21s)));
|
||||
I += Cm*Sm;
|
||||
}
|
||||
|
||||
// Average parallel and perpendicular polarization
|
||||
I *= 0.5;
|
||||
|
||||
// Convert back to RGB reflectance
|
||||
I = clamp(XYZ_TO_RGB * I, vec3(0.0), vec3(1.0));
|
||||
|
||||
return I;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_data(int model)
|
||||
{
|
||||
return FresnelData(model, vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), 0.0, 0.0, 0.0, false);
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_dielectric(float ior)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_DIELECTRIC);
|
||||
fd.ior = vec3(ior);
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_conductor(vec3 ior, vec3 extinction)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_CONDUCTOR);
|
||||
fd.ior = ior;
|
||||
fd.extinction = extinction;
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_schlick(vec3 F0)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_SCHLICK);
|
||||
fd.F0 = F0;
|
||||
fd.F90 = vec3(1.0);
|
||||
fd.exponent = 5.0f;
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_schlick(vec3 F0, vec3 F90, float exponent)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_SCHLICK);
|
||||
fd.F0 = F0;
|
||||
fd.F90 = F90;
|
||||
fd.exponent = exponent;
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_schlick_airy(vec3 F0, vec3 F90, float exponent, float tf_thickness, float tf_ior)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_SCHLICK_AIRY);
|
||||
fd.F0 = F0;
|
||||
fd.F90 = F90;
|
||||
fd.exponent = exponent;
|
||||
fd.tf_thickness = tf_thickness;
|
||||
fd.tf_ior = tf_ior;
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_dielectric_airy(float ior, float tf_thickness, float tf_ior)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_AIRY);
|
||||
fd.ior = vec3(ior);
|
||||
fd.tf_thickness = tf_thickness;
|
||||
fd.tf_ior = tf_ior;
|
||||
return fd;
|
||||
}
|
||||
|
||||
FresnelData mx_init_fresnel_conductor_airy(vec3 ior, vec3 extinction, float tf_thickness, float tf_ior)
|
||||
{
|
||||
FresnelData fd = mx_init_fresnel_data(FRESNEL_MODEL_AIRY);
|
||||
fd.ior = ior;
|
||||
fd.extinction = extinction;
|
||||
fd.tf_thickness = tf_thickness;
|
||||
fd.tf_ior = tf_ior;
|
||||
return fd;
|
||||
}
|
||||
|
||||
vec3 mx_compute_fresnel(float cosTheta, FresnelData fd)
|
||||
{
|
||||
if (fd.model == FRESNEL_MODEL_DIELECTRIC)
|
||||
{
|
||||
return vec3(mx_fresnel_dielectric(cosTheta, fd.ior.x));
|
||||
}
|
||||
else if (fd.model == FRESNEL_MODEL_CONDUCTOR)
|
||||
{
|
||||
return mx_fresnel_conductor(cosTheta, fd.ior, fd.extinction);
|
||||
}
|
||||
else if (fd.model == FRESNEL_MODEL_SCHLICK)
|
||||
{
|
||||
return mx_fresnel_schlick(cosTheta, fd.F0, fd.F90, fd.exponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mx_fresnel_airy(cosTheta, fd.ior, fd.extinction, fd.tf_thickness, fd.tf_ior,
|
||||
fd.F0, fd.F90, fd.exponent,
|
||||
fd.model == FRESNEL_MODEL_SCHLICK_AIRY);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the refraction of a ray through a solid sphere.
|
||||
vec3 mx_refraction_solid_sphere(vec3 R, vec3 N, float ior)
|
||||
{
|
||||
R = refract(R, N, 1.0 / ior);
|
||||
vec3 N1 = normalize(R * dot(R, N) - N * 0.5);
|
||||
return refract(R, N1, 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;
|
||||
return vec2(longitude, latitude);
|
||||
}
|
||||
|
||||
vec3 mx_latlong_map_lookup(vec3 dir, mat4 transform, float lod, sampler2D envSampler)
|
||||
{
|
||||
vec3 envDir = normalize((transform * vec4(dir,0.0)).xyz);
|
||||
vec2 uv = mx_latlong_projection(envDir);
|
||||
return textureLod(envSampler, uv, lod).rgb;
|
||||
}
|
||||
|
||||
// Return the mip level with the appropriate coverage for a filtered importance sample.
|
||||
// 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);
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
// https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-8-summed-area-variance-shadow-maps
|
||||
float mx_variance_shadow_occlusion(vec2 moments, float fragmentDepth)
|
||||
{
|
||||
const float MIN_VARIANCE = 0.00001;
|
||||
|
||||
// One-tailed inequality valid if fragmentDepth > moments.x.
|
||||
float p = (fragmentDepth <= moments.x) ? 1.0 : 0.0;
|
||||
|
||||
// Compute variance.
|
||||
float variance = moments.y - mx_square(moments.x);
|
||||
variance = max(variance, MIN_VARIANCE);
|
||||
|
||||
// Compute probabilistic upper bound.
|
||||
float d = fragmentDepth - moments.x;
|
||||
float pMax = variance / (variance + mx_square(d));
|
||||
return max(p, pMax);
|
||||
}
|
||||
|
||||
vec2 mx_compute_depth_moments()
|
||||
{
|
||||
float depth = gl_FragCoord.z;
|
||||
return vec2(depth, mx_square(depth));
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd, vec3 tint)
|
||||
{
|
||||
return tint;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
#include "mx_microfacet_specular.glsl"
|
||||
|
||||
vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd, vec3 tint)
|
||||
{
|
||||
// Approximate the appearance of surface transmission as glossy
|
||||
// environment map refraction, ignoring any scene geometry that might
|
||||
// be visible through the surface.
|
||||
fd.refraction = true;
|
||||
if ($refractionTwoSided)
|
||||
{
|
||||
tint = mx_square(tint);
|
||||
}
|
||||
return mx_environment_radiance(N, V, X, alpha, distribution, fd) * tint;
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
void mx_add_edf(vec3 N, vec3 L, EDF in1, EDF in2, out EDF result)
|
||||
{
|
||||
result = in1 + in2;
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
void mx_anisotropic_vdf(vec3 absorption, vec3 scattering, float anisotropy, inout BSDF bsdf)
|
||||
{
|
||||
// TODO: Add some approximation for volumetric light absorption.
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
void mx_artistic_ior(vec3 reflectivity, vec3 edge_color, out vec3 ior, out vec3 extinction)
|
||||
{
|
||||
// "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
|
||||
// http://jcgt.org/published/0003/04/03/paper.pdf
|
||||
|
||||
vec3 r = clamp(reflectivity, 0.0, 0.99);
|
||||
vec3 r_sqrt = sqrt(r);
|
||||
vec3 n_min = (1.0 - r) / (1.0 + r);
|
||||
vec3 n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt);
|
||||
ior = mix(n_max, n_min, edge_color);
|
||||
|
||||
vec3 np1 = ior + 1.0;
|
||||
vec3 nm1 = ior - 1.0;
|
||||
vec3 k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r);
|
||||
k2 = max(k2, 0.0);
|
||||
extinction = sqrt(k2);
|
||||
}
|
||||
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
/// XYZ to Rec.709 RGB colorspace conversion
|
||||
const mat3 XYZ_to_RGB = mat3( 3.2406, -0.9689, 0.0557,
|
||||
-1.5372, 1.8758, -0.2040,
|
||||
-0.4986, 0.0415, 1.0570);
|
||||
|
||||
void mx_blackbody(float temperatureKelvin, out vec3 colorValue)
|
||||
{
|
||||
float xc, yc;
|
||||
float t, t2, t3, xc2, xc3;
|
||||
|
||||
// if value outside valid range of approximation clamp to accepted temperature range
|
||||
temperatureKelvin = clamp(temperatureKelvin, 1667.0, 25000.0);
|
||||
|
||||
t = 1000.0 / temperatureKelvin;
|
||||
t2 = t * t;
|
||||
t3 = t * t * t;
|
||||
|
||||
// Cubic spline approximation for Kelvin temperature to sRGB conversion
|
||||
// (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
|
||||
if (temperatureKelvin < 4000.0) { // 1667K <= temperatureKelvin < 4000K
|
||||
xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
|
||||
}
|
||||
else { // 4000K <= temperatureKelvin <= 25000K
|
||||
xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
|
||||
}
|
||||
xc2 = xc * xc;
|
||||
xc3 = xc * xc * xc;
|
||||
|
||||
if (temperatureKelvin < 2222.0) { // 1667K <= temperatureKelvin < 2222K
|
||||
yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
|
||||
}
|
||||
else if (temperatureKelvin < 4000.0) { // 2222K <= temperatureKelvin < 4000K
|
||||
yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
|
||||
}
|
||||
else { // 4000K <= temperatureKelvin <= 25000K
|
||||
yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
|
||||
}
|
||||
|
||||
if (yc <= 0.0) { // avoid division by zero
|
||||
colorValue = vec3(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 XYZ = vec3(xc / yc, 1.0, (1.0 - xc - yc) / yc);
|
||||
|
||||
colorValue = XYZ_to_RGB * XYZ;
|
||||
colorValue = max(colorValue, vec3(0.0));
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#include "lib/mx_microfacet_diffuse.glsl"
|
||||
|
||||
void mx_burley_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
|
||||
|
||||
bsdf.response = color * occlusion * weight * NdotL * M_PI_INV;
|
||||
bsdf.response *= mx_burley_diffuse(L, V, normal, NdotL, roughness);
|
||||
}
|
||||
|
||||
void mx_burley_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
float NdotV = clamp(dot(normal, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
vec3 Li = mx_environment_irradiance(normal) *
|
||||
mx_burley_diffuse_dir_albedo(NdotV, roughness);
|
||||
bsdf.response = Li * color * weight;
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#include "lib/mx_microfacet_specular.glsl"
|
||||
|
||||
void mx_conductor_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
X = normalize(X - dot(X, N) * N);
|
||||
vec3 Y = cross(N, X);
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
|
||||
|
||||
FresnelData fd;
|
||||
if (bsdf.thickness > 0.0)
|
||||
fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, bsdf.thickness, bsdf.ior);
|
||||
else
|
||||
fd = mx_init_fresnel_conductor(ior_n, ior_k);
|
||||
|
||||
vec3 F = mx_compute_fresnel(VdotH, fd);
|
||||
float D = mx_ggx_NDF(Ht, safeAlpha);
|
||||
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
|
||||
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
|
||||
// Note: NdotL is cancelled out
|
||||
bsdf.response = D * F * G * comp * occlusion * weight / (4.0 * NdotV);
|
||||
}
|
||||
|
||||
void mx_conductor_bsdf_indirect(vec3 V, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
FresnelData fd;
|
||||
if (bsdf.thickness > 0.0)
|
||||
fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, bsdf.thickness, bsdf.ior);
|
||||
else
|
||||
fd = mx_init_fresnel_conductor(ior_n, ior_k);
|
||||
|
||||
vec3 F = mx_compute_fresnel(NdotV, fd);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
|
||||
vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
|
||||
|
||||
bsdf.response = Li * comp * weight;
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
#include "lib/mx_microfacet_specular.glsl"
|
||||
|
||||
void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
X = normalize(X - dot(X, N) * N);
|
||||
vec3 Y = cross(N, X);
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeTint = max(tint, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric(ior);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(VdotH, fd);
|
||||
float D = mx_ggx_NDF(Ht, safeAlpha);
|
||||
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
|
||||
|
||||
float F0 = mx_ior_to_f0(ior);
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
|
||||
bsdf.throughput = 1.0 - dirAlbedo * weight;
|
||||
|
||||
// Note: NdotL is cancelled out
|
||||
bsdf.response = D * F * G * comp * safeTint * occlusion * weight / (4.0 * NdotV);
|
||||
}
|
||||
|
||||
void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeTint = max(tint, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric(ior);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(NdotV, fd);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
|
||||
float F0 = mx_ior_to_f0(ior);
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
|
||||
bsdf.throughput = 1.0 - dirAlbedo * weight;
|
||||
|
||||
if (scatter_mode != 0)
|
||||
{
|
||||
bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeTint) * weight;
|
||||
}
|
||||
}
|
||||
|
||||
void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeTint = max(tint, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_dielectric(ior);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(NdotV, fd);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
|
||||
float F0 = mx_ior_to_f0(ior);
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
|
||||
bsdf.throughput = 1.0 - dirAlbedo * weight;
|
||||
|
||||
vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
|
||||
bsdf.response = Li * safeTint * comp * weight;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
void mx_displacement_float(float disp, float scale, out displacementshader result)
|
||||
{
|
||||
result.offset = vec3(disp);
|
||||
result.scale = scale;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
void mx_displacement_vector3(vec3 disp, float scale, out displacementshader result)
|
||||
{
|
||||
result.offset = disp;
|
||||
result.scale = scale;
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
#include "lib/mx_microfacet_specular.glsl"
|
||||
|
||||
void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
X = normalize(X - dot(X, N) * N);
|
||||
vec3 Y = cross(N, X);
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeColor0 = max(color0, 0.0);
|
||||
vec3 safeColor90 = max(color90, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(VdotH, fd);
|
||||
float D = mx_ggx_NDF(Ht, safeAlpha);
|
||||
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
|
||||
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
|
||||
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
|
||||
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
|
||||
|
||||
// Note: NdotL is cancelled out
|
||||
bsdf.response = D * F * G * comp * occlusion * weight / (4.0 * NdotV);
|
||||
}
|
||||
|
||||
void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeColor0 = max(color0, 0.0);
|
||||
vec3 safeColor90 = max(color90, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(NdotV, fd);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
|
||||
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
|
||||
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
|
||||
|
||||
if (scatter_mode != 0)
|
||||
{
|
||||
float avgF0 = dot(safeColor0, vec3(1.0 / 3.0));
|
||||
fd.ior = vec3(mx_f0_to_ior(avgF0));
|
||||
bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeColor0) * weight;
|
||||
}
|
||||
}
|
||||
|
||||
void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
FresnelData fd;
|
||||
vec3 safeColor0 = max(color0, 0.0);
|
||||
vec3 safeColor90 = max(color90, 0.0);
|
||||
if (bsdf.thickness > 0.0)
|
||||
{
|
||||
fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent);
|
||||
}
|
||||
vec3 F = mx_compute_fresnel(NdotV, fd);
|
||||
|
||||
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
|
||||
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
|
||||
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
|
||||
|
||||
vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
|
||||
bsdf.response = Li * comp * weight;
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#include "lib/mx_microfacet.glsl"
|
||||
|
||||
void mx_generalized_schlick_edf(vec3 N, vec3 V, vec3 color0, vec3 color90, float exponent, EDF base, out EDF result)
|
||||
{
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
vec3 f = mx_fresnel_schlick(NdotV, color0, color90, exponent);
|
||||
result = base * f;
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#include "lib/mx_microfacet_diffuse.glsl"
|
||||
|
||||
void mx_oren_nayar_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
|
||||
|
||||
bsdf.response = color * occlusion * weight * NdotL * M_PI_INV;
|
||||
if (roughness > 0.0)
|
||||
{
|
||||
bsdf.response *= mx_oren_nayar_diffuse(L, V, normal, NdotL, roughness);
|
||||
}
|
||||
}
|
||||
|
||||
void mx_oren_nayar_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
vec3 Li = mx_environment_irradiance(normal);
|
||||
bsdf.response = Li * color * weight;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
void mx_roughness_anisotropy(float roughness, float anisotropy, out vec2 result)
|
||||
{
|
||||
float roughness_sqr = clamp(roughness*roughness, M_FLOAT_EPS, 1.0);
|
||||
if (anisotropy > 0.0)
|
||||
{
|
||||
float aspect = sqrt(1.0 - clamp(anisotropy, 0.0, 0.98));
|
||||
result.x = min(roughness_sqr / aspect, 1.0);
|
||||
result.y = roughness_sqr * aspect;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.x = roughness_sqr;
|
||||
result.y = roughness_sqr;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
void mx_roughness_dual(vec2 roughness, out vec2 result)
|
||||
{
|
||||
if (roughness.y < 0.0)
|
||||
{
|
||||
roughness.y = roughness.x;
|
||||
}
|
||||
result.x = clamp(roughness.x * roughness.x, M_FLOAT_EPS, 1.0);
|
||||
result.y = clamp(roughness.y * roughness.y, M_FLOAT_EPS, 1.0);
|
||||
}
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
#include "lib/mx_microfacet_sheen.glsl"
|
||||
|
||||
void mx_sheen_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 N, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
float NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);
|
||||
|
||||
vec3 fr = color * mx_imageworks_sheen_brdf(NdotL, NdotV, NdotH, roughness);
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo(NdotV, roughness);
|
||||
bsdf.throughput = vec3(1.0 - dirAlbedo * weight);
|
||||
|
||||
// We need to include NdotL from the light integral here
|
||||
// as in this case it's not cancelled out by the BRDF denominator.
|
||||
bsdf.response = fr * NdotL * occlusion * weight;
|
||||
}
|
||||
|
||||
void mx_sheen_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 N, inout BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
N = mx_forward_facing_normal(N, V);
|
||||
|
||||
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
|
||||
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo(NdotV, roughness);
|
||||
bsdf.throughput = vec3(1.0 - dirAlbedo * weight);
|
||||
|
||||
vec3 Li = mx_environment_irradiance(N);
|
||||
bsdf.response = Li * color * dirAlbedo * weight;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#include "lib/mx_microfacet_diffuse.glsl"
|
||||
|
||||
void mx_subsurface_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, vec3 radius, float anisotropy, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
vec3 sss = mx_subsurface_scattering_approx(normal, L, P, color, radius);
|
||||
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
|
||||
float visibleOcclusion = 1.0 - NdotL * (1.0 - occlusion);
|
||||
bsdf.response = sss * visibleOcclusion * weight;
|
||||
}
|
||||
|
||||
void mx_subsurface_bsdf_indirect(vec3 V, float weight, vec3 color, vec3 radius, float anisotropy, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
normal = mx_forward_facing_normal(normal, V);
|
||||
|
||||
// For now, we render indirect subsurface as simple indirect diffuse.
|
||||
vec3 Li = mx_environment_irradiance(normal);
|
||||
bsdf.response = Li * color * weight;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// We fake diffuse transmission by using diffuse reflection from the opposite side.
|
||||
// So this BTDF is really a BRDF.
|
||||
void mx_translucent_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
// Invert normal since we're transmitting light from the other side
|
||||
float NdotL = dot(L, -normal);
|
||||
if (NdotL <= 0.0 || weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bsdf.response = color * weight * NdotL * M_PI_INV;
|
||||
}
|
||||
|
||||
void mx_translucent_bsdf_indirect(vec3 V, float weight, vec3 color, vec3 normal, inout BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = vec3(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Invert normal since we're transmitting light from the other side
|
||||
vec3 Li = mx_environment_irradiance(-normal);
|
||||
bsdf.response = Li * color * weight;
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
void mx_uniform_edf(vec3 N, vec3 L, vec3 color, out EDF result)
|
||||
{
|
||||
result = color;
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
|
||||
<!-- <oren_nayar_diffuse_bsdf> -->
|
||||
<implementation name="IM_oren_nayar_diffuse_bsdf_genglsl" nodedef="ND_oren_nayar_diffuse_bsdf" file="mx_oren_nayar_diffuse_bsdf.glsl" function="mx_oren_nayar_diffuse_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <burley_diffuse_bsdf> -->
|
||||
<implementation name="IM_burley_diffuse_bsdf_genglsl" nodedef="ND_burley_diffuse_bsdf" file="mx_burley_diffuse_bsdf.glsl" function="mx_burley_diffuse_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <translucent_bsdf> -->
|
||||
<implementation name="IM_translucent_bsdf_genglsl" nodedef="ND_translucent_bsdf" file="mx_translucent_bsdf.glsl" function="mx_translucent_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <dielectric_bsdf> -->
|
||||
<implementation name="IM_dielectric_bsdf_genglsl" nodedef="ND_dielectric_bsdf" file="mx_dielectric_bsdf.glsl" function="mx_dielectric_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <conductor_bsdf> -->
|
||||
<implementation name="IM_conductor_bsdf_genglsl" nodedef="ND_conductor_bsdf" file="mx_conductor_bsdf.glsl" function="mx_conductor_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <generalized_schlick_bsdf> -->
|
||||
<implementation name="IM_generalized_schlick_bsdf_genglsl" nodedef="ND_generalized_schlick_bsdf" file="mx_generalized_schlick_bsdf.glsl" function="mx_generalized_schlick_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <subsurface_bsdf> -->
|
||||
<implementation name="IM_subsurface_bsdf_genglsl" nodedef="ND_subsurface_bsdf" file="mx_subsurface_bsdf.glsl" function="mx_subsurface_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <sheen_bsdf> -->
|
||||
<implementation name="IM_sheen_bsdf_genglsl" nodedef="ND_sheen_bsdf" file="mx_sheen_bsdf.glsl" function="mx_sheen_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <anisotropic_vdf> -->
|
||||
<implementation name="IM_anisotropic_vdf_genglsl" nodedef="ND_anisotropic_vdf" file="mx_anisotropic_vdf.glsl" function="mx_anisotropic_vdf" target="genglsl" />
|
||||
|
||||
<!-- <thin_film_bsdf> -->
|
||||
<implementation name="IM_thin_film_bsdf_genglsl" nodedef="ND_thin_film_bsdf" target="genglsl" />
|
||||
|
||||
<!-- <layer> -->
|
||||
<implementation name="IM_layer_bsdf_genglsl" nodedef="ND_layer_bsdf" target="genglsl" />
|
||||
<implementation name="IM_layer_vdf_genglsl" nodedef="ND_layer_vdf" target="genglsl" />
|
||||
|
||||
<!-- <mix> -->
|
||||
<implementation name="IM_mix_bsdf_genglsl" nodedef="ND_mix_bsdf" target="genglsl" />
|
||||
<implementation name="IM_mix_edf_genglsl" nodedef="ND_mix_edf" target="genglsl" />
|
||||
|
||||
<!-- <add> -->
|
||||
<implementation name="IM_add_bsdf_genglsl" nodedef="ND_add_bsdf" target="genglsl" />
|
||||
<implementation name="IM_add_edf_genglsl" nodedef="ND_add_edf" target="genglsl" />
|
||||
|
||||
<!-- <multiply> -->
|
||||
<implementation name="IM_multiply_bsdfC_genglsl" nodedef="ND_multiply_bsdfC" target="genglsl" />
|
||||
<implementation name="IM_multiply_bsdfF_genglsl" nodedef="ND_multiply_bsdfF" target="genglsl" />
|
||||
<implementation name="IM_multiply_edfC_genglsl" nodedef="ND_multiply_edfC" target="genglsl" />
|
||||
<implementation name="IM_multiply_edfF_genglsl" nodedef="ND_multiply_edfF" target="genglsl" />
|
||||
|
||||
<!-- <uniform_edf> -->
|
||||
<implementation name="IM_uniform_edf_genglsl" nodedef="ND_uniform_edf" file="mx_uniform_edf.glsl" function="mx_uniform_edf" target="genglsl" />
|
||||
|
||||
<!-- <generalized_schlick_edf> -->
|
||||
<implementation name="IM_generalized_schlick_edf_genglsl" nodedef="ND_generalized_schlick_edf" file="mx_generalized_schlick_edf.glsl" function="mx_generalized_schlick_edf" target="genglsl" />
|
||||
|
||||
<!-- <surface> -->
|
||||
<implementation name="IM_surface_genglsl" nodedef="ND_surface" target="genglsl" />
|
||||
|
||||
<!-- <displacement> -->
|
||||
<implementation name="IM_displacement_float_genglsl" nodedef="ND_displacement_float" file="mx_displacement_float.glsl" function="mx_displacement_float" target="genglsl" />
|
||||
<implementation name="IM_displacement_vector3_genglsl" nodedef="ND_displacement_vector3" file="mx_displacement_vector3.glsl" function="mx_displacement_vector3" target="genglsl" />
|
||||
|
||||
<!-- <light> -->
|
||||
<implementation name="IM_light_genglsl" nodedef="ND_light" target="genglsl" />
|
||||
|
||||
<!-- <roughness_anisotropy> -->
|
||||
<implementation name="IM_roughness_anisotropy_genglsl" nodedef="ND_roughness_anisotropy" file="mx_roughness_anisotropy.glsl" function="mx_roughness_anisotropy" target="genglsl" />
|
||||
|
||||
<!-- <roughness_dual> -->
|
||||
<implementation name="IM_roughness_dual_genglsl" nodedef="ND_roughness_dual" file="mx_roughness_dual.glsl" function="mx_roughness_dual" target="genglsl" />
|
||||
|
||||
<!-- <artistic_ior> -->
|
||||
<implementation name="IM_artistic_ior_genglsl" nodedef="ND_artistic_ior" file="mx_artistic_ior.glsl" function="mx_artistic_ior" target="genglsl" />
|
||||
|
||||
<!-- <blackbody> -->
|
||||
<implementation name="IM_blackbody_genglsl" nodedef="ND_blackbody" file="mx_blackbody.glsl" function="mx_blackbody" target="genglsl" />
|
||||
|
||||
</materialx>
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
|
||||
<!-- <oren_nayar_diffuse_bsdf> -->
|
||||
<implementation name="IM_oren_nayar_diffuse_bsdf_genmdl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_oren_nayar_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}})" target="genmdl" />
|
||||
|
||||
<!-- <burley_diffuse_bsdf> -->
|
||||
<implementation name="IM_burley_diffuse_bsdf_genmdl" nodedef="ND_burley_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_burley_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}})" target="genmdl" />
|
||||
|
||||
<!-- <translucent_bsdf> -->
|
||||
<implementation name="IM_translucent_bsdf_genmdl" nodedef="ND_translucent_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_translucent_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_normal:{{normal}})" target="genmdl" />
|
||||
|
||||
<!-- <dielectric_bsdf> -->
|
||||
<implementation name="IM_dielectric_bsdf_genmdl" nodedef="ND_dielectric_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_dielectric_bsdf(mxp_weight:{{weight}}, mxp_tint:{{tint}}, mxp_ior:{{ior}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}})" target="genmdl" />
|
||||
|
||||
<!-- <conductor_bsdf> -->
|
||||
<implementation name="IM_conductor_bsdf_genmdl" nodedef="ND_conductor_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_conductor_bsdf(mxp_weight:{{weight}}, mxp_ior:{{ior}}, mxp_extinction:{{extinction}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}})" target="genmdl" />
|
||||
|
||||
<!-- <generalized_schlick_bsdf> -->
|
||||
<implementation name="IM_generalized_schlick_bsdf_genmdl" nodedef="ND_generalized_schlick_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_bsdf(mxp_weight:{{weight}}, mxp_color0:{{color0}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}},mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}})" target="genmdl" />
|
||||
|
||||
<!-- <subsurface_bsdf> -->
|
||||
<implementation name="IM_subsurface_bsdf_genmdl" nodedef="ND_subsurface_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_subsurface_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_radius:{{radius}}, mxp_anisotropy:{{anisotropy}}, mxp_normal:{{normal}})" target="genmdl" />
|
||||
|
||||
<!-- <sheen_bsdf> -->
|
||||
<implementation name="IM_sheen_bsdf_genmdl" nodedef="ND_sheen_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_sheen_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_base:{{base}})" target="genmdl" />
|
||||
|
||||
<!-- <thin_film_bsdf> -->
|
||||
<implementation name="IM_thin_film_bsdf_genmdl" nodedef="ND_thin_film_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_thin_film_bsdf(mxp_thickness:{{thickness}}, mxp_ior:{{ior}}, mxp_base:{{base}})" target="genmdl" />
|
||||
|
||||
<!-- <uniform_edf> -->
|
||||
<implementation name="IM_uniform_edf_genmdl" nodedef="ND_uniform_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_uniform_edf(mxp_color:{{color}})" target="genmdl" />
|
||||
|
||||
<!-- <conical_edf> -->
|
||||
<implementation name="IM_conical_edf_genmdl" nodedef="ND_conical_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_conical_edf(mxp_color:{{color}}, mxp_normal:{{normal}}, mxp_inner_angle:{{inner_angle}}, mxp_outer_angle:{{outer_angle}})" target="genmdl" />
|
||||
|
||||
<!-- <measured_edf> -->
|
||||
<implementation name="IM_measured_edf_genmdl" nodedef="ND_measured_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_measured_edf(mxp_color:{{color}}, mxp_normal:{{normal}}, mxp_file:{{file}}" target="genmdl" />
|
||||
|
||||
<!-- <generalized_schlick_edf> -->
|
||||
<implementation name="IM_generalized_schlick_edf_genmdl" nodedef="ND_generalized_schlick_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_edf(mxp_color0:{{color0}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}}, mxp_base:{{base}})" target="genmdl" />
|
||||
|
||||
<!-- <absorption_vdf> -->
|
||||
<implementation name="IM_absorption_vdf_genmdl" nodedef="ND_absorption_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_absorption_vdf(mxp_absorption:{{absorption}})" target="genmdl" />
|
||||
|
||||
<!-- <anisotropic_vdf> -->
|
||||
<implementation name="IM_anisotropic_vdf_genmdl" nodedef="ND_anisotropic_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_anisotropic_vdf(mxp_absorption:{{absorption}}, mxp_scattering:{{scattering}}, mxp_anisotropy:{{anisotropy}})" target="genmdl" />
|
||||
|
||||
<!-- <surface> -->
|
||||
<implementation name="IM_surface_genmdl" nodedef="ND_surface" target="genmdl" />
|
||||
|
||||
<!-- <thin_surface> -->
|
||||
<implementation name="IM_thin_surface_genmdl" nodedef="ND_thin_surface" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_thin_surface(mxp_front_bsdf:{{front_bsdf}}, mxp_front_edf:{{front_edf}}, mxp_back_bsdf:{{back_bsdf}}, mxp_back_edf:{{back_edf}}, mxp_opacity:{{opacity}})" target="genmdl" />
|
||||
|
||||
<!-- <volume> -->
|
||||
<implementation name="IM_volume_genmdl" nodedef="ND_volume" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_volume(mxp_vdf:{{vdf}}, mxp_edf:{{edf}})" target="genmdl" />
|
||||
|
||||
<!-- <light> -->
|
||||
<implementation name="IM_light_genmdl" nodedef="ND_light" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_light(mxp_edf:{{edf}}, mxp_intensity:{{intensity}}, mxp_exposure:{{exposure}})" target="genmdl" />
|
||||
|
||||
<!-- <displacement> -->
|
||||
<implementation name="IM_displacement_float_genmdl" nodedef="ND_displacement_float" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_displacement_float(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />
|
||||
<implementation name="IM_displacement_vector3_genmdl" nodedef="ND_displacement_vector3" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_displacement_vector3(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />
|
||||
|
||||
<!-- <layer> -->
|
||||
<implementation name="IM_layer_bsdf_genmdl" nodedef="ND_layer_bsdf" target="genmdl" />
|
||||
<implementation name="IM_layer_vdf_genmdl" nodedef="ND_layer_vdf" target="genmdl" />
|
||||
|
||||
<!-- <mix> -->
|
||||
<implementation name="IM_mix_bsdf_genmdl" nodedef="ND_mix_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_bsdf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />
|
||||
<implementation name="IM_mix_edf_genmdl" nodedef="ND_mix_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_edf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />
|
||||
<implementation name="IM_mix_vdf_genmdl" nodedef="ND_mix_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_vdf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />
|
||||
|
||||
<!-- <add> -->
|
||||
<implementation name="IM_add_bsdf_genmdl" nodedef="ND_add_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_bsdf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_add_edf_genmdl" nodedef="ND_add_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_edf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_add_vdf_genmdl" nodedef="ND_add_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_vdf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
|
||||
<!-- <multiply> -->
|
||||
<implementation name="IM_multiply_bsdfC_genmdl" nodedef="ND_multiply_bsdfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_bsdf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_multiply_bsdfF_genmdl" nodedef="ND_multiply_bsdfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_bsdf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_multiply_edfC_genmdl" nodedef="ND_multiply_edfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_edf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_multiply_edfF_genmdl" nodedef="ND_multiply_edfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_edf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_multiply_vdfC_genmdl" nodedef="ND_multiply_vdfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_vdf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
<implementation name="IM_multiply_vdfF_genmdl" nodedef="ND_multiply_vdfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_vdf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
|
||||
|
||||
<!-- <roughness_anisotropy> -->
|
||||
<implementation name="IM_roughness_anisotropy_genmdl" nodedef="ND_roughness_anisotropy" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_roughness_anisotropy(mxp_roughness:{{roughness}}, mxp_anisotropy:{{anisotropy}})" target="genmdl" />
|
||||
|
||||
<!-- <roughness_dual> -->
|
||||
<implementation name="IM_roughness_dual_genmdl" nodedef="ND_roughness_dual" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_roughness_dual(mxp_roughness:{{roughness}})" target="genmdl" />
|
||||
|
||||
<!-- <artistic_ior> -->
|
||||
<implementation name="IM_artistic_ior_genmdl" nodedef="ND_artistic_ior" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_artistic_ior(mxp_reflectivity:{{reflectivity}}, mxp_edge_color:{{edge_color}})" target="genmdl" />
|
||||
|
||||
<!-- <blackbody> -->
|
||||
<implementation name="IM_blackbody_genmdl" nodedef="ND_blackbody" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_blackbody(mxp_temperature:{{temperature}})" target="genmdl" />
|
||||
|
||||
</materialx>
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
|
||||
<!-- <oren_nayar_diffuse_bsdf> -->
|
||||
<implementation name="IM_oren_nayar_diffuse_bsdf_genmsl" nodedef="ND_oren_nayar_diffuse_bsdf" file="../genglsl/mx_oren_nayar_diffuse_bsdf.glsl" function="mx_oren_nayar_diffuse_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <burley_diffuse_bsdf> -->
|
||||
<implementation name="IM_burley_diffuse_bsdf_genmsl" nodedef="ND_burley_diffuse_bsdf" file="../genglsl/mx_burley_diffuse_bsdf.glsl" function="mx_burley_diffuse_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <translucent_bsdf> -->
|
||||
<implementation name="IM_translucent_bsdf_genmsl" nodedef="ND_translucent_bsdf" file="../genglsl/mx_translucent_bsdf.glsl" function="mx_translucent_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <dielectric_bsdf> -->
|
||||
<implementation name="IM_dielectric_bsdf_genmsl" nodedef="ND_dielectric_bsdf" file="../genglsl/mx_dielectric_bsdf.glsl" function="mx_dielectric_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <conductor_bsdf> -->
|
||||
<implementation name="IM_conductor_bsdf_genmsl" nodedef="ND_conductor_bsdf" file="../genglsl/mx_conductor_bsdf.glsl" function="mx_conductor_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <generalized_schlick_bsdf> -->
|
||||
<implementation name="IM_generalized_schlick_bsdf_genmsl" nodedef="ND_generalized_schlick_bsdf" file="../genglsl/mx_generalized_schlick_bsdf.glsl" function="mx_generalized_schlick_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <subsurface_bsdf> -->
|
||||
<implementation name="IM_subsurface_bsdf_genmsl" nodedef="ND_subsurface_bsdf" file="../genglsl/mx_subsurface_bsdf.glsl" function="mx_subsurface_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <sheen_bsdf> -->
|
||||
<implementation name="IM_sheen_bsdf_genmsl" nodedef="ND_sheen_bsdf" file="../genglsl/mx_sheen_bsdf.glsl" function="mx_sheen_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <anisotropic_vdf> -->
|
||||
<implementation name="IM_anisotropic_vdf_genmsl" nodedef="ND_anisotropic_vdf" file="../genglsl/mx_anisotropic_vdf.glsl" function="mx_anisotropic_vdf" target="genmsl" />
|
||||
|
||||
<!-- <thin_film_bsdf> -->
|
||||
<implementation name="IM_thin_film_bsdf_genmsl" nodedef="ND_thin_film_bsdf" target="genmsl" />
|
||||
|
||||
<!-- <layer> -->
|
||||
<implementation name="IM_layer_bsdf_genmsl" nodedef="ND_layer_bsdf" target="genmsl" />
|
||||
<implementation name="IM_layer_vdf_genmsl" nodedef="ND_layer_vdf" target="genmsl" />
|
||||
|
||||
<!-- <mix> -->
|
||||
<implementation name="IM_mix_bsdf_genmsl" nodedef="ND_mix_bsdf" target="genmsl" />
|
||||
<implementation name="IM_mix_edf_genmsl" nodedef="ND_mix_edf" target="genmsl" />
|
||||
|
||||
<!-- <add> -->
|
||||
<implementation name="IM_add_bsdf_genmsl" nodedef="ND_add_bsdf" target="genmsl" />
|
||||
<implementation name="IM_add_edf_genmsl" nodedef="ND_add_edf" target="genmsl" />
|
||||
|
||||
<!-- <multiply> -->
|
||||
<implementation name="IM_multiply_bsdfC_genmsl" nodedef="ND_multiply_bsdfC" target="genmsl" />
|
||||
<implementation name="IM_multiply_bsdfF_genmsl" nodedef="ND_multiply_bsdfF" target="genmsl" />
|
||||
<implementation name="IM_multiply_edfC_genmsl" nodedef="ND_multiply_edfC" target="genmsl" />
|
||||
<implementation name="IM_multiply_edfF_genmsl" nodedef="ND_multiply_edfF" target="genmsl" />
|
||||
|
||||
<!-- <uniform_edf> -->
|
||||
<implementation name="IM_uniform_edf_genmsl" nodedef="ND_uniform_edf" file="../genglsl/mx_uniform_edf.glsl" function="mx_uniform_edf" target="genmsl" />
|
||||
|
||||
<!-- <surface> -->
|
||||
<implementation name="IM_surface_genmsl" nodedef="ND_surface" target="genmsl" />
|
||||
|
||||
<!-- <displacement> -->
|
||||
<implementation name="IM_displacement_float_genmsl" nodedef="ND_displacement_float" file="../genglsl/mx_displacement_float.glsl" function="mx_displacement_float" target="genmsl" />
|
||||
<implementation name="IM_displacement_vector3_genmsl" nodedef="ND_displacement_vector3" file="../genglsl/mx_displacement_vector3.glsl" function="mx_displacement_vector3" target="genmsl" />
|
||||
|
||||
<!-- <light> -->
|
||||
<implementation name="IM_light_genmsl" nodedef="ND_light" target="genmsl" />
|
||||
|
||||
<!-- <roughness_anisotropy> -->
|
||||
<implementation name="IM_roughness_anisotropy_genmsl" nodedef="ND_roughness_anisotropy" file="../genglsl/mx_roughness_anisotropy.glsl" function="mx_roughness_anisotropy" target="genmsl" />
|
||||
|
||||
<!-- <roughness_dual> -->
|
||||
<implementation name="IM_roughness_dual_genmsl" nodedef="ND_roughness_dual" file="../genglsl/mx_roughness_dual.glsl" function="mx_roughness_dual" target="genmsl" />
|
||||
|
||||
<!-- <artistic_ior> -->
|
||||
<implementation name="IM_artistic_ior_genmsl" nodedef="ND_artistic_ior" file="../genglsl/mx_artistic_ior.glsl" function="mx_artistic_ior" target="genmsl" />
|
||||
|
||||
<!-- <blackbody> -->
|
||||
<implementation name="IM_blackbody_genmsl" nodedef="ND_blackbody" file="../genglsl/mx_blackbody.glsl" function="mx_blackbody" target="genmsl" />
|
||||
|
||||
</materialx>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
void mx_anisotropic_vdf(vector absorption, vector scattering, float anisotropy, output VDF vdf)
|
||||
{
|
||||
// Not implemented in vanilla OSL
|
||||
vdf = 0; // volume_henyey_greenstein(color(absorption), color(scattering), color(0.0), anisotropy);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
void mx_burley_diffuse_bsdf(float weight, color reflectance, float roughness, normal N, output BSDF bsdf)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
bsdf.response = reflectance * weight * oren_nayar(N, roughness);
|
||||
bsdf.throughput = color(0.0);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#include "../lib/mx_microfacet_specular.osl"
|
||||
|
||||
void mx_conductor_bsdf(float weight, color ior_n, color ior_k, vector2 roughness, normal N, vector U, string distribution, output BSDF bsdf)
|
||||
{
|
||||
bsdf.throughput = color(0.0);
|
||||
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
bsdf.response = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate conductor fresnel
|
||||
//
|
||||
// Fresnel should be based on microfacet normal
|
||||
// but we have no access to that from here, so just use
|
||||
// view direction and surface normal instead
|
||||
//
|
||||
float NdotV = fabs(dot(N,-I));
|
||||
color F = mx_fresnel_conductor(NdotV, ior_n, ior_k);
|
||||
|
||||
// Calculate compensation for multiple scattering.
|
||||
// This should normally be done inside the closure
|
||||
// but since vanilla OSL doesen't support this we
|
||||
// add it here in shader code instead.
|
||||
vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
color comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
|
||||
// Set ior to 0.0 to disable the internal dielectric fresnel
|
||||
bsdf.response = F * comp * weight * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, 0.0, false);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#include "../lib/mx_microfacet_specular.osl"
|
||||
|
||||
void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
|
||||
{
|
||||
if (scatter_mode == "T")
|
||||
{
|
||||
bsdf.response = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1);
|
||||
bsdf.throughput = tint * weight;
|
||||
return;
|
||||
}
|
||||
|
||||
float NdotV = clamp(dot(N,-I), M_FLOAT_EPS, 1.0);
|
||||
float F0 = mx_ior_to_f0(ior);
|
||||
float F = mx_fresnel_schlick(NdotV, F0);
|
||||
|
||||
// Calculate compensation for multiple scattering.
|
||||
// This should normally be done inside the closure
|
||||
// but since vanilla OSL doesen't support this we
|
||||
// add it here in shader code instead.
|
||||
vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
float comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
|
||||
// Calculate throughput from directional albedo.
|
||||
float dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, ior) * comp;
|
||||
bsdf.throughput = 1.0 - dirAlbedo * weight;
|
||||
|
||||
if (scatter_mode == "R")
|
||||
{
|
||||
bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 2);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#include "../lib/mx_microfacet_specular.osl"
|
||||
|
||||
void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
|
||||
{
|
||||
float avgF0 = dot(color0, color(1.0 / 3.0));
|
||||
float ior = mx_f0_to_ior(avgF0);
|
||||
|
||||
if (scatter_mode == "T")
|
||||
{
|
||||
bsdf.response = weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1);
|
||||
bsdf.throughput = weight;
|
||||
return;
|
||||
}
|
||||
|
||||
float NdotV = fabs(dot(N,-I));
|
||||
color F = mx_fresnel_schlick(NdotV, color0, color90, exponent);
|
||||
|
||||
// Calculate compensation for multiple scattering.
|
||||
// This should normally be done inside the closure
|
||||
// but since vanilla OSL doesen't support this we
|
||||
// add it here in shader code instead.
|
||||
vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float avgAlpha = mx_average_alpha(safeAlpha);
|
||||
color comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
|
||||
|
||||
// Calculate throughput from directional albedo.
|
||||
color dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp;
|
||||
float avgDirAlbedo = dot(dirAlbedo, color(1.0 / 3.0));
|
||||
bsdf.throughput = 1.0 - avgDirAlbedo * weight;
|
||||
|
||||
// Calculate the reflection response, setting IOR to zero to disable internal Fresnel.
|
||||
bsdf.response = F * comp * weight * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, 0.0, 0);
|
||||
|
||||
if (scatter_mode == "RT")
|
||||
{
|
||||
bsdf.response += bsdf.throughput * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 1);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
void mx_oren_nayar_diffuse_bsdf(float weight, color _color, float roughness, normal N, output BSDF bsdf)
|
||||
{
|
||||
bsdf.response = _color * weight * oren_nayar(N, roughness);
|
||||
bsdf.throughput = color(0.0);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#include "../lib/mx_microfacet_sheen.osl"
|
||||
|
||||
// TODO: Vanilla OSL doesn't have a proper sheen closure,
|
||||
// so use 'diffuse' scaled by sheen directional albedo for now.
|
||||
void mx_sheen_bsdf(float weight, color Ks, float roughness, vector N, output BSDF bsdf)
|
||||
{
|
||||
if (weight < M_FLOAT_EPS)
|
||||
{
|
||||
bsdf.response = 0;
|
||||
bsdf.throughput = color(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Normalization should not be needed. My suspicion is that
|
||||
// BSDF sampling of new outgoing direction in 'testrender' needs
|
||||
// to be fixed.
|
||||
vector V = normalize(-I);
|
||||
|
||||
float NdotV = fabs(dot(N,V));
|
||||
float alpha = clamp(roughness, M_FLOAT_EPS, 1.0);
|
||||
float albedo = weight * mx_imageworks_sheen_dir_albedo(NdotV, alpha);
|
||||
bsdf.response = albedo * Ks * diffuse(N);
|
||||
bsdf.throughput = 1.0 - albedo;
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, normal N, output BSDF bsdf)
|
||||
{
|
||||
// TODO: Subsurface closure is not supported by vanilla OSL.
|
||||
bsdf.response = _color * weight * diffuse(N);
|
||||
bsdf.throughput = color(0.0);
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result)
|
||||
{
|
||||
result.bsdf = bsdf.response;
|
||||
result.edf = edf;
|
||||
result.opacity = clamp(opacity, 0.0, 1.0);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
void mx_translucent_bsdf(float weight, color _color, normal N, output BSDF bsdf)
|
||||
{
|
||||
bsdf.response = _color * weight * translucent(N);
|
||||
bsdf.throughput = color(0.0);
|
||||
}
|
||||
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
float mx_square(float x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
vector2 mx_square(vector2 x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
vector mx_square(vector x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
vector4 mx_square(vector4 x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
float mx_pow5(float x)
|
||||
{
|
||||
return mx_square(mx_square(x)) * x;
|
||||
}
|
||||
|
||||
color mx_fresnel_conductor(float cosTheta, vector n, vector k)
|
||||
{
|
||||
float c2 = cosTheta*cosTheta;
|
||||
vector n2_k2 = n*n + k*k;
|
||||
vector nc2 = 2.0 * n * cosTheta;
|
||||
|
||||
vector rs_a = n2_k2 + c2;
|
||||
vector rp_a = n2_k2 * c2 + 1.0;
|
||||
vector rs = (rs_a - nc2) / (rs_a + nc2);
|
||||
vector rp = (rp_a - nc2) / (rp_a + nc2);
|
||||
|
||||
return 0.5 * (rs + rp);
|
||||
}
|
||||
|
||||
// Standard Schlick Fresnel
|
||||
float mx_fresnel_schlick(float cosTheta, float F0)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return F0 + (1.0 - F0) * x5;
|
||||
}
|
||||
color mx_fresnel_schlick(float cosTheta, color F0)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return F0 + (1.0 - F0) * x5;
|
||||
}
|
||||
|
||||
// Generalized Schlick Fresnel
|
||||
float mx_fresnel_schlick(float cosTheta, float F0, float F90)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return mix(F0, F90, x5);
|
||||
}
|
||||
color mx_fresnel_schlick(float cosTheta, color F0, color F90)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
float x5 = mx_pow5(x);
|
||||
return mix(F0, F90, x5);
|
||||
}
|
||||
|
||||
// Generalized Schlick Fresnel with a variable exponent
|
||||
color mx_fresnel_schlick(float cosTheta, float f0, float f90, float exponent)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
return mix(f0, f90, pow(x, exponent));
|
||||
}
|
||||
color mx_fresnel_schlick(float cosTheta, color f0, color f90, float exponent)
|
||||
{
|
||||
float x = clamp(1.0 - cosTheta, 0.0, 1.0);
|
||||
return mix(f0, f90, pow(x, exponent));
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#include "mx_microfacet.osl"
|
||||
|
||||
// Rational curve fit approximation for the directional albedo of Imageworks sheen.
|
||||
float mx_imageworks_sheen_dir_albedo_analytic(float NdotV, float roughness)
|
||||
{
|
||||
float a = 5.25248 - 7.66024 * NdotV + 14.26377 * roughness;
|
||||
float b = 1.0 + 30.66449 * NdotV + 32.53420 * roughness;
|
||||
return a / b;
|
||||
}
|
||||
|
||||
float mx_imageworks_sheen_dir_albedo(float NdotV, float roughness)
|
||||
{
|
||||
float dirAlbedo = mx_imageworks_sheen_dir_albedo_analytic(NdotV, roughness);
|
||||
return clamp(dirAlbedo, 0.0, 1.0);
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
#include "mx_microfacet.osl"
|
||||
|
||||
// Compute the average of an anisotropic alpha pair.
|
||||
float mx_average_alpha(vector2 alpha)
|
||||
{
|
||||
return sqrt(alpha.x * alpha.y);
|
||||
}
|
||||
|
||||
// Convert a real-valued index of refraction to normal-incidence reflectivity.
|
||||
float mx_ior_to_f0(float ior)
|
||||
{
|
||||
return mx_square((ior - 1.0) / (ior + 1.0));
|
||||
}
|
||||
|
||||
// Convert normal-incidence reflectivity to real-valued index of refraction.
|
||||
float mx_f0_to_ior(float F0)
|
||||
{
|
||||
float sqrtF0 = sqrt(clamp(F0, 0.01, 0.99));
|
||||
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
|
||||
}
|
||||
|
||||
// Rational quadratic fit to Monte Carlo data for GGX directional albedo.
|
||||
color mx_ggx_dir_albedo(float NdotV, float alpha, color F0, color F90)
|
||||
{
|
||||
float x = NdotV;
|
||||
float y = alpha;
|
||||
float x2 = mx_square(x);
|
||||
float y2 = mx_square(y);
|
||||
vector4 r = vector4(0.1003, 0.9345, 1.0, 1.0) +
|
||||
vector4(-0.6303, -2.323, -1.765, 0.2281) * x +
|
||||
vector4(9.748, 2.229, 8.263, 15.94) * y +
|
||||
vector4(-2.038, -3.748, 11.53, -55.83) * x * y +
|
||||
vector4(29.34, 1.424, 28.96, 13.08) * x2 +
|
||||
vector4(-8.245, -0.7684, -7.507, 41.26) * y2 +
|
||||
vector4(-26.44, 1.436, -36.11, 54.9) * x2 * y +
|
||||
vector4(19.99, 0.2913, 15.86, 300.2) * x * y2 +
|
||||
vector4(-5.448, 0.6286, 33.37, -285.1) * x2 * y2;
|
||||
vector2 AB = vector2(r.x, r.y) / vector2(r.z, r.w);
|
||||
AB.x = clamp(AB.x, 0.0, 1.0);
|
||||
AB.y = clamp(AB.y, 0.0, 1.0);
|
||||
return F0 * AB.x + F90 * AB.y;
|
||||
}
|
||||
|
||||
float mx_ggx_dir_albedo(float NdotV, float alpha, float F0, float F90)
|
||||
{
|
||||
color result = mx_ggx_dir_albedo(NdotV, alpha, color(F0), color(F90));
|
||||
return result[0];
|
||||
}
|
||||
|
||||
float mx_ggx_dir_albedo(float NdotV, float alpha, float ior)
|
||||
{
|
||||
color result = mx_ggx_dir_albedo(NdotV, alpha, color(mx_ior_to_f0(ior)), color(1.0));
|
||||
return result[0];
|
||||
}
|
||||
|
||||
// https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf
|
||||
// Equations 14 and 16
|
||||
color mx_ggx_energy_compensation(float NdotV, float alpha, color Fss)
|
||||
{
|
||||
float Ess = mx_ggx_dir_albedo(NdotV, alpha, 1.0, 1.0);
|
||||
return 1.0 + Fss * (1.0 - Ess) / Ess;
|
||||
}
|
||||
|
||||
float mx_ggx_energy_compensation(float NdotV, float alpha, float Fss)
|
||||
{
|
||||
color result = mx_ggx_energy_compensation(NdotV, alpha, color(Fss));
|
||||
return result[0];
|
||||
}
|
||||
Packaged/Windows/Engine/Binaries/ThirdParty/MaterialX/libraries/pbrlib/genosl/mx_anisotropic_vdf.osl
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
void mx_anisotropic_vdf(vector absorption, vector scattering, float anisotropy, output VDF vdf)
|
||||
{
|
||||
// TODO: Need to remap parameters to match the new closure,
|
||||
// or change the MaterialX spec to OSL parameterization.
|
||||
vdf = 0;
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
void mx_artistic_ior(color reflectivity, color edge_color, output vector ior, output vector extinction)
|
||||
{
|
||||
// "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
|
||||
// http://jcgt.org/published/0003/04/03/paper.pdf
|
||||
|
||||
color r = clamp(reflectivity, 0.0, 0.99);
|
||||
color r_sqrt = sqrt(r);
|
||||
color n_min = (1.0 - r) / (1.0 + r);
|
||||
color n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt);
|
||||
ior = mix(n_max, n_min, edge_color);
|
||||
|
||||
color np1 = ior + 1.0;
|
||||
color nm1 = ior - 1.0;
|
||||
color k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r);
|
||||
k2 = max(k2, 0.0);
|
||||
extinction = sqrt(k2);
|
||||
}
|
||||
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
void mx_blackbody(float temp, output color color_value)
|
||||
{
|
||||
float xc, yc;
|
||||
float t, t2, t3, xc2, xc3;
|
||||
|
||||
// if value outside valid range of approximation clamp to accepted temperature range
|
||||
float temperature = clamp(temp, 1667.0, 25000.0);
|
||||
|
||||
t = 1000.0 / temperature;
|
||||
t2 = t * t;
|
||||
t3 = t * t * t;
|
||||
|
||||
// Cubic spline approximation for Kelvin temperature to sRGB conversion
|
||||
// (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
|
||||
if (temperature < 4000.0) { // 1667K <= temperature < 4000K
|
||||
xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
|
||||
}
|
||||
else { // 4000K <= temperature <= 25000K
|
||||
xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
|
||||
}
|
||||
xc2 = xc * xc;
|
||||
xc3 = xc * xc * xc;
|
||||
|
||||
if (temperature < 2222.0) { // 1667K <= temperature < 2222K
|
||||
yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
|
||||
}
|
||||
else if (temperature < 4000.0) { // 2222K <= temperature < 4000K
|
||||
yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
|
||||
}
|
||||
else { // 4000K <= temperature <= 25000K
|
||||
yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
|
||||
}
|
||||
|
||||
if (yc <= 0.0) { // avoid division by zero
|
||||
color_value = color(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vector XYZ = vector(xc / yc, 1.0, (1 - xc - yc) / yc);
|
||||
|
||||
/// XYZ to Rec.709 RGB colorspace conversion
|
||||
matrix XYZ_to_RGB = matrix( 3.2406, -0.9689, 0.0557, 0.0,
|
||||
-1.5372, 1.8758, -0.2040, 0.0,
|
||||
-0.4986, 0.0415, 1.0570, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
color_value = transform(XYZ_to_RGB, XYZ);
|
||||
color_value = max(color_value, vector(0.0));
|
||||
}
|
||||
Packaged/Windows/Engine/Binaries/ThirdParty/MaterialX/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
|
||||
{
|
||||
if (scatter_mode == "R")
|
||||
{
|
||||
bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution);
|
||||
}
|
||||
else if (scatter_mode == "T")
|
||||
{
|
||||
bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution);
|
||||
}
|
||||
else
|
||||
{
|
||||
bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
void mx_displacement_float(float displacement, float scale, output displacementshader result)
|
||||
{
|
||||
result = vector(displacement * scale);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
void mx_displacement_vector3(vector displacement, float scale, output displacementshader result)
|
||||
{
|
||||
result = displacement * scale;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
|
||||
{
|
||||
if (scatter_mode == "R")
|
||||
{
|
||||
bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
|
||||
}
|
||||
else if (scatter_mode == "T")
|
||||
{
|
||||
bsdf = weight * generalized_schlick_bsdf(N, U, color(0.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
|
||||
}
|
||||
else
|
||||
{
|
||||
bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#include "lib/mx_microfacet.osl"
|
||||
|
||||
void mx_generalized_schlick_edf(color color0, color color90, float exponent, EDF base, output EDF result)
|
||||
{
|
||||
float NdotV = fabs(dot(N,-I));
|
||||
color f = mx_fresnel_schlick(NdotV, color0, color90, exponent);
|
||||
result = base * f;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
void mx_roughness_anisotropy(float roughness, float anisotropy, output vector2 result)
|
||||
{
|
||||
float roughness_sqr = clamp(roughness*roughness, M_FLOAT_EPS, 1.0);
|
||||
if (anisotropy > 0.0)
|
||||
{
|
||||
float aspect = sqrt(1.0 - clamp(anisotropy, 0.0, 0.98));
|
||||
result.x = min(roughness_sqr / aspect, 1.0);
|
||||
result.y = roughness_sqr * aspect;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.x = roughness_sqr;
|
||||
result.y = roughness_sqr;
|
||||
}
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
void mx_roughness_dual(vector2 roughness, output vector2 result)
|
||||
{
|
||||
result.x = clamp(roughness.x * roughness.x, M_FLOAT_EPS, 1.0);
|
||||
if (roughness.y < 0.0)
|
||||
{
|
||||
result.y = result.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.y = clamp(roughness.y * roughness.y, M_FLOAT_EPS, 1.0);
|
||||
}
|
||||
}
|
||||
Packaged/Windows/Engine/Binaries/ThirdParty/MaterialX/libraries/pbrlib/genosl/mx_subsurface_bsdf.osl
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, normal N, output BSDF bsdf)
|
||||
{
|
||||
// TODO: Subsurface closure is not supported by vanilla OSL.
|
||||
bsdf = _color * weight * diffuse(N);
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result)
|
||||
{
|
||||
result.bsdf = bsdf;
|
||||
result.edf = edf;
|
||||
result.opacity = clamp(opacity, 0.0, 1.0);
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
|
||||
<!-- <oren_nayar_diffuse_bsdf> -->
|
||||
<implementation name="IM_oren_nayar_diffuse_bsdf_genosl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="{{weight}} * oren_nayar_diffuse_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />
|
||||
|
||||
<!-- <burley_diffuse_bsdf> -->
|
||||
<implementation name="IM_burley_diffuse_bsdf_genosl" nodedef="ND_burley_diffuse_bsdf" sourcecode="{{weight}} * burley_diffuse_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />
|
||||
|
||||
<!-- <translucent_bsdf> -->
|
||||
<implementation name="IM_translucent_bsdf_genosl" nodedef="ND_translucent_bsdf" sourcecode="{{weight}} * translucent_bsdf({{normal}}, {{color}})" target="genosl" />
|
||||
|
||||
<!-- <dielectric_bsdf> -->
|
||||
<implementation name="IM_dielectric_bsdf_genosl" nodedef="ND_dielectric_bsdf" file="mx_dielectric_bsdf.osl" function="mx_dielectric_bsdf" target="genosl" />
|
||||
|
||||
<!-- <conductor_bsdf> -->
|
||||
<implementation name="IM_conductor_bsdf_genosl" nodedef="ND_conductor_bsdf" sourcecode="{{weight}} * conductor_bsdf({{normal}}, {{tangent}}, {{roughness}}.x, {{roughness}}.y, {{ior}}, {{extinction}}, {{distribution}})" target="genosl" />
|
||||
|
||||
<!-- <generalized_schlick_bsdf> -->
|
||||
<implementation name="IM_generalized_schlick_bsdf_genosl" nodedef="ND_generalized_schlick_bsdf" file="mx_generalized_schlick_bsdf.osl" function="mx_generalized_schlick_bsdf" target="genosl" />
|
||||
|
||||
<!-- <subsurface_bsdf> -->
|
||||
<implementation name="IM_subsurface_bsdf_genosl" nodedef="ND_subsurface_bsdf" file="mx_subsurface_bsdf.osl" function="mx_subsurface_bsdf" target="genosl" />
|
||||
|
||||
<!-- <sheen_bsdf> -->
|
||||
<implementation name="IM_sheen_bsdf_genosl" nodedef="ND_sheen_bsdf" sourcecode="{{weight}} * sheen_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />
|
||||
|
||||
<!-- <anisotropic_vdf> -->
|
||||
<implementation name="IM_anisotropic_vdf_genosl" nodedef="ND_anisotropic_vdf" file="mx_anisotropic_vdf.osl" function="mx_anisotropic_vdf" target="genosl" />
|
||||
|
||||
<!-- <thin_film_bsdf> -->
|
||||
<implementation name="IM_thin_film_bsdf_genosl" nodedef="ND_thin_film_bsdf" target="genosl" />
|
||||
|
||||
<!-- <uniform_edf> -->
|
||||
<implementation name="IM_uniform_edf_genosl" nodedef="ND_uniform_edf" sourcecode="uniform_edf({{color}})" target="genosl" />
|
||||
|
||||
<!-- <generalized_schlick_edf> -->
|
||||
<implementation name="IM_generalized_schlick_edf_genosl" nodedef="ND_generalized_schlick_edf" file="mx_generalized_schlick_edf.osl" function="mx_generalized_schlick_edf" target="genosl" />
|
||||
|
||||
<!-- <layer> -->
|
||||
<implementation name="IM_layer_bsdf_genosl" nodedef="ND_layer_bsdf" target="genosl" />
|
||||
<implementation name="IM_layer_vdf_genosl" nodedef="ND_layer_vdf" target="genosl" />
|
||||
|
||||
<!-- <mix> -->
|
||||
<implementation name="IM_mix_bsdf_genosl" nodedef="ND_mix_bsdf" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" target="genosl" />
|
||||
<implementation name="IM_mix_edf_genosl" nodedef="ND_mix_edf" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" target="genosl" />
|
||||
|
||||
<!-- <add> -->
|
||||
<implementation name="IM_add_bsdf_genosl" nodedef="ND_add_bsdf" sourcecode="({{in1}} + {{in2}})" target="genosl" />
|
||||
<implementation name="IM_add_edf_genosl" nodedef="ND_add_edf" sourcecode="({{in1}} + {{in2}})" target="genosl" />
|
||||
|
||||
<!-- <multiply> -->
|
||||
<implementation name="IM_multiply_bsdfC_genosl" nodedef="ND_multiply_bsdfC" sourcecode="({{in2}} * {{in1}})" target="genosl" />
|
||||
<implementation name="IM_multiply_bsdfF_genosl" nodedef="ND_multiply_bsdfF" sourcecode="({{in2}} * {{in1}})" target="genosl" />
|
||||
<implementation name="IM_multiply_edfC_genosl" nodedef="ND_multiply_edfC" sourcecode="({{in2}} * {{in1}})" target="genosl" />
|
||||
<implementation name="IM_multiply_edfF_genosl" nodedef="ND_multiply_edfF" sourcecode="({{in2}} * {{in1}})" target="genosl" />
|
||||
|
||||
<!-- <surface> -->
|
||||
<implementation name="IM_surface_genosl" nodedef="ND_surface" file="mx_surface.osl" function="mx_surface" target="genosl" />
|
||||
|
||||
<!-- <displacement> -->
|
||||
<implementation name="IM_displacement_float_genosl" nodedef="ND_displacement_float" file="mx_displacement_float.osl" function="mx_displacement_float" target="genosl" />
|
||||
<implementation name="IM_displacement_vector3_genosl" nodedef="ND_displacement_vector3" file="mx_displacement_vector3.osl" function="mx_displacement_vector3" target="genosl" />
|
||||
|
||||
<!-- <roughness_anisotropy> -->
|
||||
<implementation name="IM_roughness_anisotropy_genosl" nodedef="ND_roughness_anisotropy" file="mx_roughness_anisotropy.osl" function="mx_roughness_anisotropy" target="genosl" />
|
||||
|
||||
<!-- <roughness_dual> -->
|
||||
<implementation name="IM_roughness_dual_genosl" nodedef="ND_roughness_dual" file="mx_roughness_dual.osl" function="mx_roughness_dual" target="genosl" />
|
||||
|
||||
<!-- <artistic_ior> -->
|
||||
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />
|
||||
|
||||
<!-- <blackbody> -->
|
||||
<implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />
|
||||
|
||||
</materialx>
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
<!--
|
||||
Copyright Contributors to the MaterialX Project
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
Declarations of standard data types and nodes included in the MaterialX specification.
|
||||
-->
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- Data Types -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<typedef name="BSDF" doc="Bidirectional scattering distribution function" />
|
||||
<typedef name="EDF" doc="Emission distribution function" />
|
||||
<typedef name="VDF" doc="Volume distribution function" />
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- BSDF Nodes -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!--
|
||||
Node: <oren_nayar_diffuse_bsdf>
|
||||
A BSDF node for diffuse reflection.
|
||||
-->
|
||||
<nodedef name="ND_oren_nayar_diffuse_bsdf" node="oren_nayar_diffuse_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for diffuse reflections.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color" type="color3" value="0.18, 0.18, 0.18" />
|
||||
<input name="roughness" type="float" value="0.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <burley_diffuse_bsdf>
|
||||
A BSDF node for Burley diffuse reflection.
|
||||
-->
|
||||
<nodedef name="ND_burley_diffuse_bsdf" node="burley_diffuse_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for Burley diffuse reflections.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color" type="color3" value="0.18, 0.18, 0.18" />
|
||||
<input name="roughness" type="float" value="0.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <translucent_bsdf>
|
||||
A BSDF node for diffuse transmission.
|
||||
-->
|
||||
<nodedef name="ND_translucent_bsdf" node="translucent_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for pure diffuse transmission.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <dielectric_bsdf>
|
||||
A reflection/transmission BSDF node based on a microfacet model and a Fresnel curve for dielectrics.
|
||||
-->
|
||||
<nodedef name="ND_dielectric_bsdf" node="dielectric_bsdf" nodegroup="pbr" doc="A reflection/transmission BSDF node based on a microfacet model and a Fresnel curve for dielectrics.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="tint" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="ior" type="float" value="1.5" />
|
||||
<input name="roughness" type="vector2" value="0.05, 0.05" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<input name="tangent" type="vector3" defaultgeomprop="Tworld" />
|
||||
<input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
|
||||
<input name="scatter_mode" type="string" value="R" enum="R,T,RT" uniform="true" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <conductor_bsdf>
|
||||
A reflection BSDF node based on a microfacet model and a Fresnel curve for conductors/metals.
|
||||
-->
|
||||
<nodedef name="ND_conductor_bsdf" node="conductor_bsdf" bsdf="R" nodegroup="pbr" doc="A reflection BSDF node based on a microfacet model and a Fresnel curve for conductors/metals.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="ior" type="color3" value="0.183, 0.421, 1.373" colorspace="none" />
|
||||
<input name="extinction" type="color3" value="3.424, 2.346, 1.770" colorspace="none" />
|
||||
<input name="roughness" type="vector2" value="0.05, 0.05" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<input name="tangent" type="vector3" defaultgeomprop="Tworld" />
|
||||
<input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <generalized_schlick_bsdf>
|
||||
A reflection/transmission BSDF node based on a microfacet model and a generalized Schlick Fresnel curve.
|
||||
-->
|
||||
<nodedef name="ND_generalized_schlick_bsdf" node="generalized_schlick_bsdf" nodegroup="pbr" doc="A reflection/transmission BSDF node based on a microfacet model and a generalized Schlick Fresnel curve.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color0" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="color90" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="exponent" type="float" value="5.0" />
|
||||
<input name="roughness" type="vector2" value="0.05, 0.05" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<input name="tangent" type="vector3" defaultgeomprop="Tworld" />
|
||||
<input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
|
||||
<input name="scatter_mode" type="string" value="R" enum="R,T,RT" uniform="true" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <subsurface_bsdf>
|
||||
A subsurface scattering BSDF for true subsurface scattering.
|
||||
-->
|
||||
<nodedef name="ND_subsurface_bsdf" node="subsurface_bsdf" bsdf="R" nodegroup="pbr" doc="A subsurface scattering BSDF for true subsurface scattering.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color" type="color3" value="0.18, 0.18, 0.18" />
|
||||
<input name="radius" type="vector3" value="1.0, 1.0, 1.0" />
|
||||
<input name="anisotropy" type="float" value="0.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <sheen_bsdf>
|
||||
A microfacet BSDF for the back-scattering properties of cloth-like materials.
|
||||
-->
|
||||
<nodedef name="ND_sheen_bsdf" node="sheen_bsdf" bsdf="R" nodegroup="pbr" doc="A microfacet BSDF for the back-scattering properties of cloth-like materials.">
|
||||
<input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="color" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="roughness" type="float" value="0.3" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <thin_film_bsdf>
|
||||
Adds an iridescent thin film layer over a microfacet base BSDF.
|
||||
-->
|
||||
<nodedef name="ND_thin_film_bsdf" node="thin_film_bsdf" bsdf="R" nodegroup="pbr" doc="Adds an iridescent thin film layer over a microfacet base BSDF.">
|
||||
<input name="thickness" type="float" value="550" unittype="distance" unit="nanometer" />
|
||||
<input name="ior" type="float" value="1.5" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- EDF Nodes -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!--
|
||||
Node: <uniform_edf>
|
||||
An EDF node for uniform emission.
|
||||
-->
|
||||
<nodedef name="ND_uniform_edf" node="uniform_edf" nodegroup="pbr" doc="An EDF node for uniform emission.">
|
||||
<input name="color" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <conical_edf>
|
||||
Constructs an EDF emitting light inside a cone around the normal direction.
|
||||
-->
|
||||
<nodedef name="ND_conical_edf" node="conical_edf" nodegroup="pbr" doc="Constructs an EDF emitting light inside a cone around the normal direction.">
|
||||
<input name="color" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<input name="inner_angle" type="float" value="60.0" />
|
||||
<input name="outer_angle" type="float" value="0.0" />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <measured_edf>
|
||||
Constructs an EDF emitting light according to a measured IES light profile.
|
||||
-->
|
||||
<nodedef name="ND_measured_edf" node="measured_edf" nodegroup="pbr" doc="Constructs an EDF emitting light according to a measured IES light profile.">
|
||||
<input name="color" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
|
||||
<input name="file" type="filename" value="" uniform="true" />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <generalized_schlick_edf>
|
||||
Modifies an EDF with a directional factor. Attenuates the emission distribution of the base EDF according to
|
||||
a generalized Schlick fresnel function.
|
||||
-->
|
||||
<nodedef name="ND_generalized_schlick_edf" node="generalized_schlick_edf" nodegroup="pbr" doc="Modifies an EDF with a directional factor.">
|
||||
<input name="color0" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="color90" type="color3" value="1.0, 1.0, 1.0" />
|
||||
<input name="exponent" type="float" value="5.0" />
|
||||
<input name="base" type="EDF" value="" />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- VDF Nodes -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!--
|
||||
Node: <absorption_vdf>
|
||||
Constructs a VDF for pure light absorption.
|
||||
-->
|
||||
<nodedef name="ND_absorption_vdf" node="absorption_vdf" nodegroup="pbr" doc="Constructs a VDF for pure light absorption.">
|
||||
<input name="absorption" type="vector3" value="0.0, 0.0, 0.0" />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <anisotropic_vdf>
|
||||
Constructs a VDF scattering light for a participating medium, based on the
|
||||
Henyey-Greenstein phase function.
|
||||
-->
|
||||
<nodedef name="ND_anisotropic_vdf" node="anisotropic_vdf" nodegroup="pbr" doc="Constructs a VDF scattering light for a participating medium, based on the Henyey-Greenstein phase function.">
|
||||
<input name="absorption" type="vector3" value="0.0, 0.0, 0.0" />
|
||||
<input name="scattering" type="vector3" value="0.0, 0.0, 0.0" />
|
||||
<input name="anisotropy" type="float" value="0.0" />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- Shader Nodes -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!--
|
||||
Node: <surface>
|
||||
Construct a surface shader from scattering and emission distribution functions.
|
||||
-->
|
||||
<nodedef name="ND_surface" node="surface" nodegroup="pbr" doc="A constructor node for the surfaceshader type.">
|
||||
<input name="bsdf" type="BSDF" value="" doc="Distribution function for surface scattering." />
|
||||
<input name="edf" type="EDF" value="" doc="Distribution function for surface emission." />
|
||||
<input name="opacity" type="float" value="1.0" doc="Surface cutout opacity" />
|
||||
<output name="out" type="surfaceshader" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <thin_surface>
|
||||
Construct a surface shader from scattering and emission distribution functions for non-closed "thin" objects.
|
||||
-->
|
||||
<nodedef name="ND_thin_surface" node="thin_surface" nodegroup="pbr" doc="A constructor node for the surfaceshader type for non-closed 'thin' objects.">
|
||||
<input name="front_bsdf" type="BSDF" value="" doc="Distribution function for front-side surface scattering." />
|
||||
<input name="front_edf" type="EDF" value="" doc="Distribution function for front-side surface emission." />
|
||||
<input name="back_bsdf" type="BSDF" value="" doc="Distribution function for back-side surface scattering." />
|
||||
<input name="back_edf" type="EDF" value="" doc="Distribution function for back-side surface emission." />
|
||||
<input name="opacity" type="float" value="1.0" doc="Surface cutout opacity" />
|
||||
<output name="out" type="surfaceshader" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <volume>
|
||||
Construct a volume shader describing a participating medium.
|
||||
-->
|
||||
<nodedef name="ND_volume" node="volume" nodegroup="pbr" doc="A constructor node for the volumeshader type.">
|
||||
<input name="vdf" type="VDF" value="" doc="Volume distribution function for the medium." />
|
||||
<input name="edf" type="EDF" value="" doc="Emission distribution function for the medium." />
|
||||
<output name="out" type="volumeshader" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <light>
|
||||
Construct a light shader from emission distribution functions.
|
||||
-->
|
||||
<nodedef name="ND_light" node="light" nodegroup="pbr" doc="A constructor node for the lightshader type.">
|
||||
<input name="edf" type="EDF" value="" doc="Distribution function for light emission." />
|
||||
<input name="intensity" type="float" value="1.0" doc="Multiplier for the light intensity" />
|
||||
<input name="exposure" type="float" value="0.0" doc="Exposure control for the light intensity" />
|
||||
<output name="out" type="lightshader" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <displacement>
|
||||
Construct a displacement shader.
|
||||
-->
|
||||
<nodedef name="ND_displacement_float" node="displacement" nodegroup="pbr" doc="A constructor node for the displacementshader type.">
|
||||
<input name="displacement" type="float" value="0.0" doc="Scalar displacement amount along the surface normal direction." />
|
||||
<input name="scale" type="float" value="1.0" doc="Scale factor for the displacement vector" />
|
||||
<output name="out" type="displacementshader" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_displacement_vector3" node="displacement" nodegroup="pbr" doc="A constructor node for the displacementshader type.">
|
||||
<input name="displacement" type="vector3" value="0.0, 0.0, 0.0" doc="Vector displacement in (dPdu, dPdv, N) tangent/normal space." />
|
||||
<input name="scale" type="float" value="1.0" doc="Scale factor for the displacement vector" />
|
||||
<output name="out" type="displacementshader" />
|
||||
</nodedef>
|
||||
|
||||
<!-- ======================================================================== -->
|
||||
<!-- Utility Nodes -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!--
|
||||
Node: <layer>
|
||||
-->
|
||||
<nodedef name="ND_layer_bsdf" node="layer" nodegroup="pbr" defaultinput="top" doc="Layer two BSDF's with vertical layering.">
|
||||
<input name="top" type="BSDF" value="" />
|
||||
<input name="base" type="BSDF" value="" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_layer_vdf" node="layer" nodegroup="pbr" defaultinput="top" doc="Layer a BSDF over a VDF describing the interior media.">
|
||||
<input name="top" type="BSDF" value="" />
|
||||
<input name="base" type="VDF" value="" />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <mix>
|
||||
-->
|
||||
<nodedef name="ND_mix_bsdf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two BSDF's according to an input mix amount.">
|
||||
<input name="fg" type="BSDF" value="" />
|
||||
<input name="bg" type="BSDF" value="" />
|
||||
<input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_mix_edf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two EDF's according to an input mix amount.">
|
||||
<input name="fg" type="EDF" value="" />
|
||||
<input name="bg" type="EDF" value="" />
|
||||
<input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_mix_vdf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two VDF's according to an input mix amount.">
|
||||
<input name="fg" type="VDF" value="" />
|
||||
<input name="bg" type="VDF" value="" />
|
||||
<input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <add>
|
||||
-->
|
||||
<nodedef name="ND_add_bsdf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of BSDF's.">
|
||||
<input name="in1" type="BSDF" value="" doc="First BSDF." />
|
||||
<input name="in2" type="BSDF" value="" doc="Second BSDF." />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_add_edf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of EDF's.">
|
||||
<input name="in1" type="EDF" value="" doc="First EDF." />
|
||||
<input name="in2" type="EDF" value="" doc="Second EDF." />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_add_vdf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of VDF's.">
|
||||
<input name="in1" type="VDF" value="" doc="First VDF." />
|
||||
<input name="in2" type="VDF" value="" doc="Second VDF." />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <multiply>
|
||||
-->
|
||||
<nodedef name="ND_multiply_bsdfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of a BSDF with a weight.">
|
||||
<input name="in1" type="BSDF" value="" doc="The BSDF to scale." />
|
||||
<input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_multiply_bsdfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of a BSDF with a weight.">
|
||||
<input name="in1" type="BSDF" value="" doc="The BSDF to scale." />
|
||||
<input name="in2" type="float" value="1.0" doc="Scaling weight." />
|
||||
<output name="out" type="BSDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_multiply_edfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an EDF with a weight.">
|
||||
<input name="in1" type="EDF" value="" doc="The EDF to scale." />
|
||||
<input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_multiply_edfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an EDF with a weight.">
|
||||
<input name="in1" type="EDF" value="" doc="The EDF to scale." />
|
||||
<input name="in2" type="float" value="1.0" doc="Scaling weight." />
|
||||
<output name="out" type="EDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_multiply_vdfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an VDF with a weight.">
|
||||
<input name="in1" type="VDF" value="" doc="The VDF to scale." />
|
||||
<input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
<nodedef name="ND_multiply_vdfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an VDF with a weight.">
|
||||
<input name="in1" type="VDF" value="" doc="The VDF to scale." />
|
||||
<input name="in2" type="float" value="1.0" doc="Scaling weight." />
|
||||
<output name="out" type="VDF" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <roughness_anisotropy>
|
||||
Calculates anisotropic surface roughness from a scalar roughness and anisotropy parameterization.
|
||||
-->
|
||||
<nodedef name="ND_roughness_anisotropy" node="roughness_anisotropy" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a scalar roughness/anisotropy parameterization.">
|
||||
<input name="roughness" type="float" value="0.0" />
|
||||
<input name="anisotropy" type="float" value="0.0" />
|
||||
<output name="out" type="vector2" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <roughness_dual>
|
||||
Calculates anisotropic surface roughness from a dual surface roughness parameterization.
|
||||
-->
|
||||
<nodedef name="ND_roughness_dual" node="roughness_dual" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a dual surface roughness parameterization.">
|
||||
<input name="roughness" type="vector2" value="0.0, 0.0" />
|
||||
<output name="out" type="vector2" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <glossiness_anisotropy>
|
||||
Calculates anisotropic surface roughness from a scalar glossiness and anisotropy parameterization.
|
||||
-->
|
||||
<nodedef name="ND_glossiness_anisotropy" node="glossiness_anisotropy" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a scalar glossiness/anisotropy parameterization.">
|
||||
<input name="glossiness" type="float" value="1.0" uimin="0.0" uimax="1.0" />
|
||||
<input name="anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" />
|
||||
<output name="out" type="vector2" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <blackbody>
|
||||
Returns the radiant emittance of a blackbody radiator with the given temperature.
|
||||
-->
|
||||
<nodedef name="ND_blackbody" node="blackbody" nodegroup="pbr" doc="Returns the radiant emittance of a blackbody radiator with the given temperature.">
|
||||
<input name="temperature" type="float" value="5000.0" />
|
||||
<output name="out" type="color3" />
|
||||
</nodedef>
|
||||
|
||||
<!--
|
||||
Node: <artistic_ior>
|
||||
Converts the artistic parameterization reflectivity and edge_color to complex IOR values.
|
||||
-->
|
||||
<nodedef name="ND_artistic_ior" node="artistic_ior" nodegroup="pbr" doc="Converts the artistic parameterization reflectivity and edge_color to complex IOR values.">
|
||||
<input name="reflectivity" type="color3" value="0.944, 0.776, 0.373" colorspace="lin_rec709" />
|
||||
<input name="edge_color" type="color3" value="0.998, 0.981, 0.751" colorspace="lin_rec709" />
|
||||
<output name="ior" type="color3" />
|
||||
<output name="extinction" type="color3" />
|
||||
</nodedef>
|
||||
|
||||
</materialx>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<materialx version="1.38">
|
||||
<!--
|
||||
Copyright Contributors to the MaterialX Project
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
Graph definitions of standard nodes included in the MaterialX specification.
|
||||
-->
|
||||
|
||||
<!-- <glossiness_anisotropy> -->
|
||||
<nodegraph name="IMP_glossiness_anisotropy" nodedef="ND_glossiness_anisotropy">
|
||||
<invert name="invert1" type="float">
|
||||
<input name="in" type="float" interfacename="glossiness" />
|
||||
</invert>
|
||||
<roughness_anisotropy name="roughness1" type="vector2">
|
||||
<input name="roughness" type="float" nodename="invert1" />
|
||||
<input name="anisotropy" type="float" interfacename="anisotropy" />
|
||||
</roughness_anisotropy>
|
||||
<output name="out" type="vector2" nodename="roughness1" />
|
||||
</nodegraph>
|
||||
|
||||
</materialx>
|
||||
Reference in New Issue
Block a user