-
Notifications
You must be signed in to change notification settings - Fork 366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shader generation support for new OSL closures in MaterialXGenOsl #1039
Changes from all commits
005822f
87e0121
207dea8
7f84e38
7df7590
aad506a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ | ||
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}" MESSAGE_NEVER | ||
PATTERN "CMakeLists.txt" EXCLUDE) | ||
PATTERN "CMakeLists.txt" EXCLUDE | ||
PATTERN "pbrlib_genosl_impl.legacy" EXCLUDE) | ||
|
||
if (MATERIALX_OSL_LEGACY_CLOSURES) | ||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.legacy" | ||
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx) | ||
endif() | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
void mx_anisotropic_vdf(vector absorption, vector scattering, float anisotropy, output VDF vdf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Old code snippets are move into a "legacy" directory. |
||
{ | ||
// Not implemented in vanilla OSL | ||
vdf = 0; // volume_henyey_greenstein(color(absorption), color(scattering), color(0.0), anisotropy); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result) | ||
{ | ||
float opacity_weight = clamp(opacity, 0.0, 1.0); | ||
result = (bsdf.response + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
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); | ||
// TODO: Need to remap parameters to match the new closure, | ||
// or change the MaterialX spec to OSL parameterization. | ||
vdf = 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,15 @@ | ||
#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") | ||
if (scatter_mode == "R") | ||
{ | ||
bsdf.response = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); | ||
bsdf.throughput = tint * weight; | ||
return; | ||
bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution); | ||
} | ||
|
||
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") | ||
else if (scatter_mode == "T") | ||
{ | ||
bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 0); | ||
bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution); | ||
} | ||
else | ||
{ | ||
bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 2); | ||
bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For refraction to occur this has to be paired with a medium closure. Is it expected that the user will have a medium node in the graph if they want refraction? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If refraction with absorption/scattering is requested then it is expected that the user sets a But it would be good if the I'm imagining the following behavior could be used for the two dielectric BSDF's.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good point. Do you think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To my mind it would be better to just have ior=1.0 and get no refraction for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we should start with the current MaterialX behavior, where IOR is derived from F0 in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. Thanks for the input @jstone-lucasfilm. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,15 @@ | ||
#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") | ||
if (scatter_mode == "R") | ||
{ | ||
bsdf.response = weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); | ||
bsdf.throughput = weight; | ||
return; | ||
bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution); | ||
} | ||
|
||
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") | ||
else if (scatter_mode == "T") | ||
{ | ||
bsdf.response += bsdf.throughput * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 1); | ||
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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +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.response = _color * weight * diffuse(N); | ||
bsdf.throughput = color(0.0); | ||
bsdf = _color * weight * diffuse(N); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result) | ||
{ | ||
float opacity_weight = clamp(opacity, 0.0, 1.0); | ||
result = (bsdf.response + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); | ||
result = (bsdf + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?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" file="legacy/mx_oren_nayar_diffuse_bsdf.osl" function="mx_oren_nayar_diffuse_bsdf" target="genosl" /> | ||
|
||
<!-- <burley_diffuse_bsdf> --> | ||
<implementation name="IM_burley_diffuse_bsdf_genosl" nodedef="ND_burley_diffuse_bsdf" file="legacy/mx_burley_diffuse_bsdf.osl" function="mx_burley_diffuse_bsdf" target="genosl" /> | ||
|
||
<!-- <translucent_bsdf> --> | ||
<implementation name="IM_translucent_bsdf_genosl" nodedef="ND_translucent_bsdf" file="legacy/mx_translucent_bsdf.osl" function="mx_translucent_bsdf" target="genosl" /> | ||
|
||
<!-- <dielectric_bsdf> --> | ||
<implementation name="IM_dielectric_bsdf_genosl" nodedef="ND_dielectric_bsdf" file="legacy/mx_dielectric_bsdf.osl" function="mx_dielectric_bsdf" target="genosl" /> | ||
|
||
<!-- <conductor_bsdf> --> | ||
<implementation name="IM_conductor_bsdf_genosl" nodedef="ND_conductor_bsdf" file="legacy/mx_conductor_bsdf.osl" function="mx_conductor_bsdf" target="genosl" /> | ||
|
||
<!-- <generalized_schlick_bsdf> --> | ||
<implementation name="IM_generalized_schlick_bsdf_genosl" nodedef="ND_generalized_schlick_bsdf" file="legacy/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="legacy/mx_subsurface_bsdf.osl" function="mx_subsurface_bsdf" target="genosl" /> | ||
|
||
<!-- <sheen_bsdf> --> | ||
<implementation name="IM_sheen_bsdf_genosl" nodedef="ND_sheen_bsdf" file="legacy/mx_sheen_bsdf.osl" function="mx_sheen_bsdf" target="genosl" /> | ||
|
||
<!-- <anisotropic_vdf> --> | ||
<implementation name="IM_anisotropic_vdf_genosl" nodedef="ND_anisotropic_vdf" file="legacy/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="{{color}} * emission()" 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" target="genosl" /> | ||
<implementation name="IM_mix_edf_genosl" nodedef="ND_mix_edf" target="genosl" /> | ||
|
||
<!-- <add> --> | ||
<implementation name="IM_add_bsdf_genosl" nodedef="ND_add_bsdf" target="genosl" /> | ||
<implementation name="IM_add_edf_genosl" nodedef="ND_add_edf" target="genosl" /> | ||
|
||
<!-- <multiply> --> | ||
<implementation name="IM_multiply_bsdfC_genosl" nodedef="ND_multiply_bsdfC" target="genosl" /> | ||
<implementation name="IM_multiply_bsdfF_genosl" nodedef="ND_multiply_bsdfF" target="genosl" /> | ||
<implementation name="IM_multiply_edfC_genosl" nodedef="ND_multiply_edfC" target="genosl" /> | ||
<implementation name="IM_multiply_edfF_genosl" nodedef="ND_multiply_edfF" target="genosl" /> | ||
|
||
<!-- <surface> --> | ||
<implementation name="IM_surface_genosl" nodedef="ND_surface" file="legacy/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" /> | ||
|
||
</materialx> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the code snippets are different when using the legacy OSL closures. This will install a separate mtlx file with implementation elements pointing to the right code.