WIP: MaterialX addon #104594

Closed
Bogdan Nagirniak wants to merge 34 commits from BogdanNagirniak/blender-addons:materialx-addon into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
929 changed files with 32383 additions and 0 deletions
Showing only changes of commit c78738087b - Show all commits

45
materialx/__init__.py Normal file
View File

@ -0,0 +1,45 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022, AMD
"""
MaterialX NodeTree addon + MaterialX online library
"""
bl_info = {
"name": "MaterialX NodeTree",
"description": "MaterialX NodeTree addon + MaterialX online library",
"author": "AMD",
"version": (1, 0, 0),
"blender": (3, 4, 0),
"location": "Editor Type -> MaterialX",
"doc_url": "{BLENDER_MANUAL_URL}/addons/materials/materialx.html",
"warning": "Alpha",
"support": "TESTING",
"category": "Material",
}
ADDON_PREFIX = "materialx"
import bpy
from . import preferences
from . import node_tree
from . import nodes
from . import logging
log = logging.Log("")
def register():
log("register")
bpy.utils.register_class(preferences.AddonPreferences)
bpy.utils.register_class(node_tree.MxNodeTree)
nodes.register()
def unregister():
log("unregister")
nodes.unregister()
bpy.utils.unregister_class(node_tree.MxNodeTree)
bpy.utils.unregister_class(preferences.AddonPreferences)

View File

@ -0,0 +1,70 @@
# MaterialX Data Libraries
The following is the layout of the definitions and implementations provided as part of the core libraries.
These libraries can be used to build shading networks which can be accepted by code generators to produce shader code.
The following core "targets": GLSL, MDL and OSL.
## Standard Library
- [stdlib](stdlib)
- [stdlib_defs.mtlx](stdlib/stdlib_defs.mtlx) : Single node nodedef definitions file.
- [stdlib_ng.mtlx](stdlib/stdlib_ng.mtlx) : Node graph definitions file.
- [genglsl](stdlib/genglsl): GLSL language support.
- lib : Shader utility files.
- [stdlib_genglsl_impl.mtlx](stdlib/genglsl/stdlib_genglsl_impl.mtlx) : Mapping from definitions to implementations
- [stdlib_genglsl_cm_impl.mtlx](stdlib/genglsl/stdlib_genglsl_cm_impl.mtlx) : Minimal set of "default" color management implementations.
- [stdlib_genglsl_unit_impl.mtlx](stdlib/genosl/stdlib_genglsl_unit_impl.mtlx) : Real world unit support implementations.
- GLSL implementation files.
- [genosl](stdlib/genosl): OSL language support.
- lib: Shader utility files.
- [stdlib_genosl_impl.mtlx](stdlib/genosl/stdlib_genosl_impl.mtlx) : Mapping from definitions to implementations
- [stdlib_genosl_cm_impl.mtlx](stdlib/genosl/stdlib_genosl_cm_impl.mtlx) : Minimal set of "default" color management implementations.
- [stdlib_genosl_unit_impl.mtlx](stdlib/genosl/stdlib_genosl_unit_impl.mtlx) : Real world unit support implementations.
- OSL implementation files.
- [osl](stdlib/osl): OSL reference implementation
- OSL implementation files.
- [genmdl](stdlib/genmdl): MDL language support.
- [stdlib_genmdl_impl.mtlx](stdlib/genosl/stdlib_genmdl_impl.mtlx) : Mapping from definitions to implementations
- [stdlib_genmdl_cm_impl.mtlx](stdlib/genosl/stdlib_genmdl_cm_impl.mtlx) : Minimal set of "default" color management implementations.
- [stdlib_genmdl_unit_impl.mtlx](stdlib/genosl/stdlib_genmdl_unit_impl.mtlx) : Real world unit support implementations.
## Physically-Based Shading Library
- [pbrlib](pbrlib)
- [pbrlib_defs.mtlx](pbrlib/pbrlib_defs.mtlx) : Single node definitions file.
- [pbrlib_ng.mtlx](pbrlib/pbrlib_ng.mtlx) : Node graph definitions file.
- [genglsl](pbrlib/genglsl) : GLSL language support
- lib : Shader utility files.
- [pbrlib_genglsl_impl.mtlx](pbrlib/genglsl/pbrlib_genglsl_impl.mtlx) : Mapping from definitions to implementations
- GLSL implementation files.
- [genosl](pbrlib/genosl) : OSL language support
- lib : Utilities
- [pbrlib_genosl_impl.mtlx](pbrlib/genosl/pbrlib_genosl_impl.mtlx) : Mapping from definitions to implementations
- OSL implementation files.
- [genmdl](pbrlib/genmdl) : MDL language support
- [pbrlib_genmdl_impl.mtlx](pbrlib/genosl/pbrlib_genmdl_impl.mtlx) : Mapping from definitions to implementations.
- Note: MDL implementation files are in a "package" folder found under
[source/MaterialXGenMdl/mdl/materialx](../source/MaterialXGenMdl/mdl/materialx)
## Target Definitions
- Each target implementation requires a target definition for definition / implementation correspondence to work.
- [targets](targets) is the folder holding documents which declare these definitions.
- There are definition files for the following core targets:
- OSL : `genosl`
- Desktop GLSL : `genglsl`
- MDL : `genmdl`
- Any additional target files should be added under this folder and loaded in as required.
### Target Support
- GLSL target support is for version 4.0 or higher.
- OSL target support is for version 1.9.10 or higher.
- MDL target support is for version 1.6.
- "Default" color management support includes OSL, GLSL, and MDL implementations for the following non-LUT transforms:
- lin_rec709, gamma18, gamma22, gamma24, acescg, g22_acescg, srgb_texture
- Basic GLSL `lightshader` node definitions and implementations are provided for the following light types:
- point, directional, spot
- Code generation does not currently support:
- `ambientocclusion` node.
- `arrayappend` node.
- `curveadjust` node.
- `displacementshader` and `volumeshader` nodes and associated operations (`add`, `multiply`, `mix`) for GLSL targets.

View File

@ -0,0 +1,93 @@
<?xml version="1.0"?>

Why are these node defs being included?

Why are these node defs being included?
<materialx version="1.38" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="stdlib/stdlib_defs.mtlx" />
<xi:include href="stdlib/stdlib_ng.mtlx" />
<nodedef name="ND_algclamp_float" node="algclamp">
<output name="out" type="float" />
<input name="val" type="float" value="0" uiname="Value" />
<input name="i_min" type="float" value="0" uiname="Min" />
<input name="i_max" type="float" value="1" uiname="Max" />
</nodedef>
<nodedef name="ND_algclamp_vector2" node="algclamp">
<output name="out" type="vector2" />
<input name="val" type="vector2" value="0, 0" uiname="Value" />
<input name="i_min" type="vector2" value="0, 0" uiname="Min" />
<input name="i_max" type="vector2" value="1, 1" uiname="Max" />
</nodedef>
<nodedef name="ND_algclamp_vector3" node="algclamp">
<output name="out" type="vector3" />
<input name="val" type="vector3" value="0, 0, 0" uiname="Value" />
<input name="i_min" type="vector3" value="0, 0, 0" uiname="Min" />
<input name="i_max" type="vector3" value="1, 1, 1" uiname="Max" />
</nodedef>
<nodedef name="ND_algclamp_vector4" node="algclamp">
<output name="out" type="vector4" />
<input name="val" type="vector4" value="0, 0, 0, 0" uiname="Value" />
<input name="i_min" type="vector4" value="0, 0, 0, 0" uiname="Min" />
<input name="i_max" type="vector4" value="1, 1, 1, 1" uiname="Max" />
</nodedef>
<nodedef name="ND_algclamp_color3" node="algclamp">
<output name="out" type="color3" />
<input name="val" type="color3" value="0, 0, 0" uiname="Value" />
<input name="i_min" type="color3" value="0, 0, 0" uiname="Min" />
<input name="i_max" type="color3" value="1, 1, 1" uiname="Max" />
</nodedef>
<nodedef name="ND_alglevels_float" node="alglevels">
<output name="out" type="float" />
<input name="pixel" type="float" value="0" uiname="Value" />
<input name="i_min" type="float" value="0" uiname="Min" />
<input name="i_max" type="float" value="1" uiname="Max" />
<input name="i_gamma" type="float" value="1" uiname="Gamma" />
</nodedef>
<nodedef name="ND_alglevels_vector2" node="alglevels">
<output name="out" type="vector2" />
<input name="pixel" type="vector2" value="0, 0" uiname="Value" />
<input name="i_min" type="vector2" value="0, 0" uiname="Min" />
<input name="i_max" type="vector2" value="1, 1" uiname="Max" />
<input name="i_gamma" type="float" value="1" uiname="Gamma" />
</nodedef>
<nodedef name="ND_alglevels_vector3" node="alglevels">
<output name="out" type="vector3" />
<input name="pixel" type="vector3" value="0, 0, 0" uiname="Value" />
<input name="i_min" type="vector3" value="0, 0, 0" uiname="Min" />
<input name="i_max" type="vector3" value="1, 1, 1" uiname="Max" />
<input name="i_gamma" type="float" value="1" uiname="Gamma" />
</nodedef>
<nodedef name="ND_alglevels_vector4" node="alglevels">
<output name="out" type="vector4" />
<input name="pixel" type="vector4" value="0, 0, 0, 0" uiname="Value" />
<input name="i_min" type="vector4" value="0, 0, 0, 0" uiname="Min" />
<input name="i_max" type="vector4" value="1, 1, 1, 1" uiname="Max" />
<input name="i_gamma" type="float" value="1" uiname="Gamma" />
</nodedef>
<nodedef name="ND_alglevels_color3" node="alglevels">
<output name="out" type="color3" />
<input name="pixel" type="color3" value="0, 0, 0" uiname="Value" />
<input name="i_min" type="color3" value="0, 0, 0" uiname="Min" />
<input name="i_max" type="color3" value="1, 1, 1" uiname="Max" />
<input name="i_gamma" type="float" value="1" uiname="Gamma" />
</nodedef>
<nodedef name="ND_algdot_color3" node="algdot">
<output name="out" type="float" />
<input name="in1" type="color3" value="0, 0, 0" uiname="Value" />
<input name="in2" type="color3" value="0, 0, 0" uiname="Min" />
</nodedef>
<nodedef name="ND_algheighttonormal" node="algheighttonormal">
<output name="out" type="vector3" />
<input name="h" type="float" value="0" uiname="Height" />
<input name="dU" type="float" value="0" uiname="HeightU" />
<input name="dV" type="float" value="0" uiname="HeightV" />
<input name="delta" type="float" value="0.0001" uiname="Delta" />
<input name="intensity" type="float" value="1" uimin="0.001" uimax="10.0" uiname="Normal Intensity" />
</nodedef>
<nodedef name="ND_algnormalTStoWS_vector3" node="algnormalTStoWS">
<output name="out" type="vector3" />
<input name="normalTS" type="vector3" value="0.5, 0.5, 1" uiname="Normal Tangent Space" />
<input name="openGL" type="boolean" value="true" uiname="OpenGL Tangent Space" uniform="true" />
<input name="index" type="integer" value="0" uiname="UV Index" uniform="true" />
</nodedef>
<nodedef name="ND_algsrgb_to_linear" node="algsrgb_to_linear">
<output name="out" type="color3" />
<input name="in" type="color3" value="0, 0, 0" uiname="In" />
</nodedef>
</materialx>

View File

@ -0,0 +1,518 @@
<?xml version="1.0"?>
<materialx version="1.38" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="stdlib/stdlib_defs.mtlx" />
<xi:include href="stdlib/stdlib_ng.mtlx" />
<nodegraph name="NG_algclamp_float" nodedef="ND_algclamp_float">
<max name="ND_max_float_1" type="float">
<input name="in1" type="float" interfacename="val" />
<input name="in2" type="float" interfacename="i_min" />
</max>
<min name="ND_min_float_2" type="float">
<input name="in1" type="float" nodename="ND_max_float_1" />
<input name="in2" type="float" interfacename="i_max" />
</min>
<output name="out" type="float" nodename="ND_min_float_2" />
</nodegraph>
<nodegraph name="NG_algclamp_vector2" nodedef="ND_algclamp_vector2">
<max name="ND_max_vector2_3" type="vector2">
<input name="in1" type="vector2" interfacename="val" />
<input name="in2" type="vector2" interfacename="i_min" />
</max>
<min name="ND_min_vector2_4" type="vector2">
<input name="in1" type="vector2" nodename="ND_max_vector2_3" />
<input name="in2" type="vector2" interfacename="i_max" />
</min>
<output name="out" type="vector2" nodename="ND_min_vector2_4" />
</nodegraph>
<nodegraph name="NG_algclamp_vector3" nodedef="ND_algclamp_vector3">
<max name="ND_max_vector3_5" type="vector3">
<input name="in1" type="vector3" interfacename="val" />
<input name="in2" type="vector3" interfacename="i_min" />
</max>
<min name="ND_min_vector3_6" type="vector3">
<input name="in1" type="vector3" nodename="ND_max_vector3_5" />
<input name="in2" type="vector3" interfacename="i_max" />
</min>
<output name="out" type="vector3" nodename="ND_min_vector3_6" />
</nodegraph>
<nodegraph name="NG_algclamp_vector4" nodedef="ND_algclamp_vector4">
<max name="ND_max_vector4_7" type="vector4">
<input name="in1" type="vector4" interfacename="val" />
<input name="in2" type="vector4" interfacename="i_min" />
</max>
<min name="ND_min_vector4_8" type="vector4">
<input name="in1" type="vector4" nodename="ND_max_vector4_7" />
<input name="in2" type="vector4" interfacename="i_max" />
</min>
<output name="out" type="vector4" nodename="ND_min_vector4_8" />
</nodegraph>
<nodegraph name="NG_algclamp_color3" nodedef="ND_algclamp_color3">
<max name="ND_max_color3_9" type="color3">
<input name="in1" type="color3" interfacename="val" />
<input name="in2" type="color3" interfacename="i_min" />
</max>
<min name="ND_min_color3_10" type="color3">
<input name="in1" type="color3" nodename="ND_max_color3_9" />
<input name="in2" type="color3" interfacename="i_max" />
</min>
<output name="out" type="color3" nodename="ND_min_color3_10" />
</nodegraph>
<nodegraph name="NG_alglevels_float" nodedef="ND_alglevels_float">
<subtract name="ND_subtract_float_11" type="float">
<input name="in1" type="float" interfacename="pixel" />
<input name="in2" type="float" interfacename="i_min" />
</subtract>
<subtract name="ND_subtract_float_12" type="float">
<input name="in1" type="float" interfacename="i_max" />
<input name="in2" type="float" interfacename="i_min" />
</subtract>
<divide name="ND_divide_float_13" type="float">
<input name="in1" type="float" nodename="ND_subtract_float_11" />
<input name="in2" type="float" nodename="ND_subtract_float_12" />
</divide>
<constant name="ND_constant_float_14" type="float">
<input name="value" type="float" value="0" />
</constant>
<constant name="ND_constant_float_15" type="float">
<input name="value" type="float" value="1" />
</constant>
<max name="ND_max_float_16" type="float">
<input name="in1" type="float" nodename="ND_divide_float_13" />
<input name="in2" type="float" nodename="ND_constant_float_14" />
</max>
<min name="ND_min_float_17" type="float">
<input name="in1" type="float" nodename="ND_max_float_16" />
<input name="in2" type="float" nodename="ND_constant_float_15" />
</min>
<constant name="ND_constant_float_18" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_19" type="float">
<input name="in1" type="float" nodename="ND_constant_float_18" />
<input name="in2" type="float" interfacename="i_gamma" />
</divide>
<power name="ND_power_float_20" type="float">
<input name="in1" type="float" nodename="ND_min_float_17" />
<input name="in2" type="float" nodename="ND_divide_float_19" />
</power>
<output name="out" type="float" nodename="ND_power_float_20" />
</nodegraph>
<nodegraph name="NG_alglevels_vector2" nodedef="ND_alglevels_vector2">
<subtract name="ND_subtract_vector2_21" type="vector2">
<input name="in1" type="vector2" interfacename="pixel" />
<input name="in2" type="vector2" interfacename="i_min" />
</subtract>
<subtract name="ND_subtract_vector2_22" type="vector2">
<input name="in1" type="vector2" interfacename="i_max" />
<input name="in2" type="vector2" interfacename="i_min" />
</subtract>
<divide name="ND_divide_vector2_23" type="vector2">
<input name="in1" type="vector2" nodename="ND_subtract_vector2_21" />
<input name="in2" type="vector2" nodename="ND_subtract_vector2_22" />
</divide>
<constant name="ND_constant_vector2_24" type="vector2">
<input name="value" type="vector2" value="0, 0" />
</constant>
<constant name="ND_constant_vector2_25" type="vector2">
<input name="value" type="vector2" value="1, 1" />
</constant>
<max name="ND_max_vector2_26" type="vector2">
<input name="in1" type="vector2" nodename="ND_divide_vector2_23" />
<input name="in2" type="vector2" nodename="ND_constant_vector2_24" />
</max>
<min name="ND_min_vector2_27" type="vector2">
<input name="in1" type="vector2" nodename="ND_max_vector2_26" />
<input name="in2" type="vector2" nodename="ND_constant_vector2_25" />
</min>
<constant name="ND_constant_float_28" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_29" type="float">
<input name="in1" type="float" nodename="ND_constant_float_28" />
<input name="in2" type="float" interfacename="i_gamma" />
</divide>
<power name="ND_power_vector2FA_30" type="vector2">
<input name="in1" type="vector2" nodename="ND_min_vector2_27" />
<input name="in2" type="float" nodename="ND_divide_float_29" />
</power>
<output name="out" type="vector2" nodename="ND_power_vector2FA_30" />
</nodegraph>
<nodegraph name="NG_alglevels_vector3" nodedef="ND_alglevels_vector3">
<subtract name="ND_subtract_vector3_31" type="vector3">
<input name="in1" type="vector3" interfacename="pixel" />
<input name="in2" type="vector3" interfacename="i_min" />
</subtract>
<subtract name="ND_subtract_vector3_32" type="vector3">
<input name="in1" type="vector3" interfacename="i_max" />
<input name="in2" type="vector3" interfacename="i_min" />
</subtract>
<divide name="ND_divide_vector3_33" type="vector3">
<input name="in1" type="vector3" nodename="ND_subtract_vector3_31" />
<input name="in2" type="vector3" nodename="ND_subtract_vector3_32" />
</divide>
<constant name="ND_constant_vector3_34" type="vector3">
<input name="value" type="vector3" value="0, 0, 0" />
</constant>
<constant name="ND_constant_vector3_35" type="vector3">
<input name="value" type="vector3" value="1, 1, 1" />
</constant>
<max name="ND_max_vector3_36" type="vector3">
<input name="in1" type="vector3" nodename="ND_divide_vector3_33" />
<input name="in2" type="vector3" nodename="ND_constant_vector3_34" />
</max>
<min name="ND_min_vector3_37" type="vector3">
<input name="in1" type="vector3" nodename="ND_max_vector3_36" />
<input name="in2" type="vector3" nodename="ND_constant_vector3_35" />
</min>
<constant name="ND_constant_float_38" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_39" type="float">
<input name="in1" type="float" nodename="ND_constant_float_38" />
<input name="in2" type="float" interfacename="i_gamma" />
</divide>
<power name="ND_power_vector3FA_40" type="vector3">
<input name="in1" type="vector3" nodename="ND_min_vector3_37" />
<input name="in2" type="float" nodename="ND_divide_float_39" />
</power>
<output name="out" type="vector3" nodename="ND_power_vector3FA_40" />
</nodegraph>
<nodegraph name="NG_alglevels_vector4" nodedef="ND_alglevels_vector4">
<subtract name="ND_subtract_vector4_41" type="vector4">
<input name="in1" type="vector4" interfacename="pixel" />
<input name="in2" type="vector4" interfacename="i_min" />
</subtract>
<subtract name="ND_subtract_vector4_42" type="vector4">
<input name="in1" type="vector4" interfacename="i_max" />
<input name="in2" type="vector4" interfacename="i_min" />
</subtract>
<divide name="ND_divide_vector4_43" type="vector4">
<input name="in1" type="vector4" nodename="ND_subtract_vector4_41" />
<input name="in2" type="vector4" nodename="ND_subtract_vector4_42" />
</divide>
<constant name="ND_constant_vector4_44" type="vector4">
<input name="value" type="vector4" value="0, 0, 0, 0" />
</constant>
<constant name="ND_constant_vector4_45" type="vector4">
<input name="value" type="vector4" value="1, 1, 1, 1" />
</constant>
<max name="ND_max_vector4_46" type="vector4">
<input name="in1" type="vector4" nodename="ND_divide_vector4_43" />
<input name="in2" type="vector4" nodename="ND_constant_vector4_44" />
</max>
<min name="ND_min_vector4_47" type="vector4">
<input name="in1" type="vector4" nodename="ND_max_vector4_46" />
<input name="in2" type="vector4" nodename="ND_constant_vector4_45" />
</min>
<constant name="ND_constant_float_48" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_49" type="float">
<input name="in1" type="float" nodename="ND_constant_float_48" />
<input name="in2" type="float" interfacename="i_gamma" />
</divide>
<power name="ND_power_vector4FA_50" type="vector4">
<input name="in1" type="vector4" nodename="ND_min_vector4_47" />
<input name="in2" type="float" nodename="ND_divide_float_49" />
</power>
<output name="out" type="vector4" nodename="ND_power_vector4FA_50" />
</nodegraph>
<nodegraph name="NG_alglevels_color3" nodedef="ND_alglevels_color3">
<subtract name="ND_subtract_color3_51" type="color3">
<input name="in1" type="color3" interfacename="pixel" />
<input name="in2" type="color3" interfacename="i_min" />
</subtract>
<subtract name="ND_subtract_color3_52" type="color3">
<input name="in1" type="color3" interfacename="i_max" />
<input name="in2" type="color3" interfacename="i_min" />
</subtract>
<divide name="ND_divide_color3_53" type="color3">
<input name="in1" type="color3" nodename="ND_subtract_color3_51" />
<input name="in2" type="color3" nodename="ND_subtract_color3_52" />
</divide>
<constant name="ND_constant_color3_54" type="color3">
<input name="value" type="color3" value="0, 0, 0" />
</constant>
<constant name="ND_constant_color3_55" type="color3">
<input name="value" type="color3" value="1, 1, 1" />
</constant>
<max name="ND_max_color3_56" type="color3">
<input name="in1" type="color3" nodename="ND_divide_color3_53" />
<input name="in2" type="color3" nodename="ND_constant_color3_54" />
</max>
<min name="ND_min_color3_57" type="color3">
<input name="in1" type="color3" nodename="ND_max_color3_56" />
<input name="in2" type="color3" nodename="ND_constant_color3_55" />
</min>
<constant name="ND_constant_float_58" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_59" type="float">
<input name="in1" type="float" nodename="ND_constant_float_58" />
<input name="in2" type="float" interfacename="i_gamma" />
</divide>
<power name="ND_power_color3FA_60" type="color3">
<input name="in1" type="color3" nodename="ND_min_color3_57" />
<input name="in2" type="float" nodename="ND_divide_float_59" />
</power>
<output name="out" type="color3" nodename="ND_power_color3FA_60" />
</nodegraph>
<nodegraph name="NG_algdot_color3" nodedef="ND_algdot_color3">
<swizzle name="ND_swizzle_color3_float_61" type="float">
<input name="in" type="color3" interfacename="in1" />
<input name="channels" type="string" value="r" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_62" type="float">
<input name="in" type="color3" interfacename="in2" />
<input name="channels" type="string" value="r" />
</swizzle>
<multiply name="ND_multiply_float_63" type="float">
<input name="in1" type="float" nodename="ND_swizzle_color3_float_61" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_62" />
</multiply>
<swizzle name="ND_swizzle_color3_float_64" type="float">
<input name="in" type="color3" interfacename="in1" />
<input name="channels" type="string" value="g" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_65" type="float">
<input name="in" type="color3" interfacename="in2" />
<input name="channels" type="string" value="g" />
</swizzle>
<multiply name="ND_multiply_float_66" type="float">
<input name="in1" type="float" nodename="ND_swizzle_color3_float_64" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_65" />
</multiply>
<add name="ND_add_float_67" type="float">
<input name="in1" type="float" nodename="ND_multiply_float_63" />
<input name="in2" type="float" nodename="ND_multiply_float_66" />
</add>
<swizzle name="ND_swizzle_color3_float_68" type="float">
<input name="in" type="color3" interfacename="in1" />
<input name="channels" type="string" value="b" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_69" type="float">
<input name="in" type="color3" interfacename="in2" />
<input name="channels" type="string" value="b" />
</swizzle>
<multiply name="ND_multiply_float_70" type="float">
<input name="in1" type="float" nodename="ND_swizzle_color3_float_68" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_69" />
</multiply>
<add name="ND_add_float_71" type="float">
<input name="in1" type="float" nodename="ND_add_float_67" />
<input name="in2" type="float" nodename="ND_multiply_float_70" />
</add>
<output name="out" type="float" nodename="ND_add_float_71" />
</nodegraph>
<nodegraph name="NG_algheighttonormal" nodedef="ND_algheighttonormal">
<subtract name="ND_subtract_float_72" type="float">
<input name="in1" type="float" interfacename="dU" />
<input name="in2" type="float" interfacename="h" />
</subtract>
<divide name="ND_divide_float_73" type="float">
<input name="in1" type="float" nodename="ND_subtract_float_72" />
<input name="in2" type="float" interfacename="delta" />
</divide>
<subtract name="ND_subtract_float_74" type="float">
<input name="in1" type="float" interfacename="dV" />
<input name="in2" type="float" interfacename="h" />
</subtract>
<divide name="ND_divide_float_75" type="float">
<input name="in1" type="float" nodename="ND_subtract_float_74" />
<input name="in2" type="float" interfacename="delta" />
</divide>
<constant name="ND_constant_float_76" type="float">
<input name="value" type="float" value="1" />
</constant>
<divide name="ND_divide_float_77" type="float">
<input name="in1" type="float" nodename="ND_constant_float_76" />
<input name="in2" type="float" interfacename="intensity" />
</divide>
<combine3 name="ND_combine3_vector3_78" type="vector3">
<input name="in1" type="float" nodename="ND_divide_float_73" />
<input name="in2" type="float" nodename="ND_divide_float_75" />
<input name="in3" type="float" nodename="ND_divide_float_77" />
</combine3>
<normalize name="ND_normalize_vector3_79" type="vector3">
<input name="in" type="vector3" nodename="ND_combine3_vector3_78" />
</normalize>
<constant name="ND_constant_vector3_80" type="vector3">
<input name="value" type="vector3" value="1, 1, 1" />
</constant>
<add name="ND_add_vector3_81" type="vector3">
<input name="in1" type="vector3" nodename="ND_normalize_vector3_79" />
<input name="in2" type="vector3" nodename="ND_constant_vector3_80" />
</add>
<constant name="ND_constant_float_82" type="float">
<input name="value" type="float" value="2" />
</constant>
<divide name="ND_divide_vector3FA_83" type="vector3">
<input name="in1" type="vector3" nodename="ND_add_vector3_81" />
<input name="in2" type="float" nodename="ND_constant_float_82" />
</divide>
<output name="out" type="vector3" nodename="ND_divide_vector3FA_83" />
</nodegraph>
<nodegraph name="NG_algnormalTStoWS_vector3" nodedef="ND_algnormalTStoWS_vector3">
<constant name="ND_constant_float_84" type="float">
<input name="value" type="float" value="0.5" />
</constant>
<subtract name="ND_subtract_vector3FA_85" type="vector3">
<input name="in1" type="vector3" interfacename="normalTS" />
<input name="in2" type="float" nodename="ND_constant_float_84" />
</subtract>
<constant name="ND_constant_float_86" type="float">
<input name="value" type="float" value="2" />
</constant>
<multiply name="ND_multiply_vector3FA_87" type="vector3">
<input name="in1" type="vector3" nodename="ND_subtract_vector3FA_85" />
<input name="in2" type="float" nodename="ND_constant_float_86" />
</multiply>
<swizzle name="ND_swizzle_vector3_float_88" type="float">
<input name="in" type="vector3" nodename="ND_multiply_vector3FA_87" />
<input name="channels" type="string" value="x" />
</swizzle>
<swizzle name="ND_swizzle_vector3_float_89" type="float">
<input name="in" type="vector3" nodename="ND_multiply_vector3FA_87" />
<input name="channels" type="string" value="y" />
</swizzle>
<swizzle name="ND_swizzle_vector3_float_90" type="float">
<input name="in" type="vector3" nodename="ND_multiply_vector3FA_87" />
<input name="channels" type="string" value="z" />
</swizzle>
<tangent name="ND_tangent_vector3_91" type="vector3">
<input name="space" type="string" value="world" />
<input name="index" type="integer" interfacename="index" />
</tangent>
<bitangent name="ND_bitangent_vector3_92" type="vector3">
<input name="space" type="string" value="world" />
<input name="index" type="integer" interfacename="index" />
</bitangent>
<normal name="ND_normal_vector3_93" type="vector3">
<input name="space" type="string" value="world" />
</normal>
<constant name="ND_constant_float_94" type="float">
<input name="value" type="float" value="-1" />
</constant>
<multiply name="ND_multiply_vector3FA_95" type="vector3">
<input name="in1" type="vector3" nodename="ND_bitangent_vector3_92" />
<input name="in2" type="float" nodename="ND_constant_float_94" />
</multiply>
<ifequal name="ND_ifequal_vector3B_96" type="vector3">
<input name="value1" type="boolean" interfacename="openGL" />
<input name="value2" type="boolean" value="false" />
<input name="in1" type="vector3" nodename="ND_bitangent_vector3_92" />
<input name="in2" type="vector3" nodename="ND_multiply_vector3FA_95" />
</ifequal>
<multiply name="ND_multiply_vector3FA_97" type="vector3">
<input name="in1" type="vector3" nodename="ND_tangent_vector3_91" />
<input name="in2" type="float" nodename="ND_swizzle_vector3_float_88" />
</multiply>
<multiply name="ND_multiply_vector3FA_98" type="vector3">
<input name="in1" type="vector3" nodename="ND_ifequal_vector3B_96" />
<input name="in2" type="float" nodename="ND_swizzle_vector3_float_89" />
</multiply>
<multiply name="ND_multiply_vector3FA_99" type="vector3">
<input name="in1" type="vector3" nodename="ND_normal_vector3_93" />
<input name="in2" type="float" nodename="ND_swizzle_vector3_float_90" />
</multiply>
<add name="ND_add_vector3_100" type="vector3">
<input name="in1" type="vector3" nodename="ND_multiply_vector3FA_97" />
<input name="in2" type="vector3" nodename="ND_multiply_vector3FA_98" />
</add>
<add name="ND_add_vector3_101" type="vector3">
<input name="in1" type="vector3" nodename="ND_add_vector3_100" />
<input name="in2" type="vector3" nodename="ND_multiply_vector3FA_99" />
</add>
<normalize name="ND_normalize_vector3_102" type="vector3">
<input name="in" type="vector3" nodename="ND_add_vector3_101" />
</normalize>
<output name="out" type="vector3" nodename="ND_normalize_vector3_102" />
</nodegraph>
<nodegraph name="NG_algsrgb_to_linear" nodedef="ND_algsrgb_to_linear">
<constant name="ND_constant_float_103" type="float">
<input name="value" type="float" value="12.92" />
</constant>
<divide name="ND_divide_color3FA_104" type="color3">
<input name="in1" type="color3" interfacename="in" />
<input name="in2" type="float" nodename="ND_constant_float_103" />
</divide>
<constant name="ND_constant_float_105" type="float">
<input name="value" type="float" value="0.055" />
</constant>
<add name="ND_add_color3FA_106" type="color3">
<input name="in1" type="color3" interfacename="in" />
<input name="in2" type="float" nodename="ND_constant_float_105" />
</add>
<constant name="ND_constant_float_107" type="float">
<input name="value" type="float" value="1.055" />
</constant>
<divide name="ND_divide_color3FA_108" type="color3">
<input name="in1" type="color3" nodename="ND_add_color3FA_106" />
<input name="in2" type="float" nodename="ND_constant_float_107" />
</divide>
<power name="ND_power_color3FA_109" type="color3">
<input name="in1" type="color3" nodename="ND_divide_color3FA_108" />
<input name="in2" type="float" value="2.4" />
</power>
<swizzle name="ND_swizzle_color3_float_110" type="float">
<input name="in" type="color3" interfacename="in" />
<input name="channels" type="string" value="r" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_111" type="float">
<input name="in" type="color3" interfacename="in" />
<input name="channels" type="string" value="g" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_112" type="float">
<input name="in" type="color3" interfacename="in" />
<input name="channels" type="string" value="b" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_113" type="float">
<input name="in" type="color3" nodename="ND_divide_color3FA_104" />
<input name="channels" type="string" value="r" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_114" type="float">
<input name="in" type="color3" nodename="ND_divide_color3FA_104" />
<input name="channels" type="string" value="g" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_115" type="float">
<input name="in" type="color3" nodename="ND_divide_color3FA_104" />
<input name="channels" type="string" value="b" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_116" type="float">
<input name="in" type="color3" nodename="ND_power_color3FA_109" />
<input name="channels" type="string" value="r" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_117" type="float">
<input name="in" type="color3" nodename="ND_power_color3FA_109" />
<input name="channels" type="string" value="g" />
</swizzle>
<swizzle name="ND_swizzle_color3_float_118" type="float">
<input name="in" type="color3" nodename="ND_power_color3FA_109" />
<input name="channels" type="string" value="b" />
</swizzle>
<ifgreater name="ND_ifgreater_float_119" type="float">
<input name="value1" type="float" nodename="ND_swizzle_color3_float_110" />
<input name="value2" type="float" value="0.045045" />
<input name="in1" type="float" nodename="ND_swizzle_color3_float_116" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_113" />
</ifgreater>
<ifgreater name="ND_ifgreater_float_120" type="float">
<input name="value1" type="float" nodename="ND_swizzle_color3_float_111" />
<input name="value2" type="float" value="0.045045" />
<input name="in1" type="float" nodename="ND_swizzle_color3_float_117" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_114" />
</ifgreater>
<ifgreater name="ND_ifgreater_float_121" type="float">
<input name="value1" type="float" nodename="ND_swizzle_color3_float_112" />
<input name="value2" type="float" value="0.045045" />
<input name="in1" type="float" nodename="ND_swizzle_color3_float_118" />
<input name="in2" type="float" nodename="ND_swizzle_color3_float_115" />
</ifgreater>
<combine3 name="ND_combine3_color3_122" type="color3">
<input name="in1" type="float" nodename="ND_ifgreater_float_119" />
<input name="in2" type="float" nodename="ND_ifgreater_float_120" />
<input name="in3" type="float" nodename="ND_ifgreater_float_121" />
</combine3>
<output name="out" type="color3" nodename="ND_combine3_color3_122" />
</nodegraph>
</materialx>

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709">
<nodedef name="ND_disney_brdf_2012_surface" node="disney_brdf_2012">
<input name="baseColor" type="color3" value="0.16, 0.16, 0.16" />
<input name="metallic" type="float" value="0" />
<input name="subsurface" type="float" value="0" />
<input name="specular" type="float" value="0.5" />
<input name="roughness" type="float" value="0.5" />
<input name="specularTint" type="float" value="0" />
<input name="anisotropic" type="float" value="0" />
<input name="sheen" type="float" value="0" />
<input name="sheenTint" type="float" value="0.5" />
<input name="clearcoat" type="float" value="0" />
<input name="clearcoatGloss" type="float" value="1" />
<output name="out" type="surfaceshader" />
</nodedef>
<implementation name="IM_disney_brdf_2012_surface_brdf_explorer" nodedef="ND_disney_brdf_2012_surface" target="brdf_explorer" file="https://github.com/wdas/brdf/blob/master/src/brdfs/disney.brdf" />
</materialx>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709">
<nodedef name="ND_disney_bsdf_2015_surface" node="disney_bsdf_2015">
<input name="baseColor" type="color3" value="0.16, 0.16, 0.16" />
<input name="metallic" type="float" value="0" />
<input name="roughness" type="float" value="0.5" />
<input name="anisotropic" type="float" value="0" />
<input name="specularTint" type="float" value="0" />
<input name="sheen" type="float" value="0" />
<input name="sheenTint" type="float" value="0.5" />
<input name="clearcoat" type="float" value="0" />
<input name="clearcoatGloss" type="float" value="1" />
<input name="specTrans" type="float" value="0" />
<input name="ior" type="float" value="1.5" />
<input name="scatterDistance" type="vector3" value="0, 0, 0" />
<input name="flatness" type="float" value="0" />
<input name="diffTrans" type="float" value="0" />
<input name="thin" type="boolean" value="false" uniform="true" />
<output name="out" type="surfaceshader" />
</nodedef>
<implementation name="IM_disney_bsdf_2015_surface_pbrt" nodedef="ND_disney_bsdf_2015_surface" target="pbrt" file="https://github.com/mmp/pbrt-v3/blob/master/src/materials/disney.cpp" function="DisneyMaterial::DisneyMaterial">
<input name="baseColor" type="color3" implname="color" />
<input name="ior" type="float" implname="eta" />
</implementation>
</materialx>

View File

@ -0,0 +1,327 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Autodesk Standard Surface node definition.
-->
<nodedef name="ND_standard_surface_surfaceshader" node="standard_surface" nodegroup="pbr" doc="Autodesk standard surface shader" version="1.0.1" isdefaultversion="true">
<input name="base" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Base" uifolder="Base" doc="Multiplier on the intensity of the diffuse reflection." />
<input name="base_color" type="color3" value="0.8, 0.8, 0.8" uimin="0,0,0" uimax="1,1,1" uiname="Base Color" uifolder="Base" doc="Color of the diffuse reflection." />
<input name="diffuse_roughness" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Diffuse Roughness" uifolder="Base" uiadvanced="true" doc="Roughness of the diffuse reflection. Higher values cause the surface to appear flatter and darker." />
<input name="metalness" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Metalness" uifolder="Base" doc="Specifies how metallic the material appears. At its maximum, the surface behaves like a metal, using fully specular reflection and complex fresnel." />
<input name="specular" type="float" value="1" uimin="0.0" uimax="1.0" uiname="Specular" uifolder="Specular" doc="Multiplier on the intensity of the specular reflection." />
<input name="specular_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Specular Color" uifolder="Specular" doc="Color tint on the specular reflection." />
<input name="specular_roughness" type="float" value="0.2" uimin="0.0" uimax="1.0" uiname="Specular Roughness" uifolder="Specular" doc="The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections." />
<input name="specular_IOR" type="float" value="1.5" uimin="0.0" uisoftmax="3.0" uiname="Index of Refraction" uifolder="Specular" doc="Index of refraction for specular reflection." />
<input name="specular_anisotropy" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Anisotropy" uifolder="Specular" uiadvanced="true" doc="The directional bias of reflected and transmitted light resulting in materials appearing rougher or glossier in certain directions." />
<input name="specular_rotation" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Rotation" uifolder="Specular" uiadvanced="true" doc="Rotation of the axis of specular anisotropy around the surface normal." />
<input name="transmission" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Transmission" uifolder="Transmission" uiadvanced="true" doc="Transmission of light through the surface for materials such as glass or water. The greater the value the more transparent the material." />
<input name="transmission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Color" uifolder="Transmission" uiadvanced="true" doc="Color tint on the transmitted light." />
<input name="transmission_depth" type="float" value="0" uimin="0.0" uisoftmax="100.0" uiname="Transmission Depth" uifolder="Transmission" uiadvanced="true" doc="Specifies the distance light travels inside the material before its becomes exactly the transmission color according to Beer's law." />
<input name="transmission_scatter" type="color3" value="0, 0, 0" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Scatter" uifolder="Transmission" uiadvanced="true" doc="Scattering coefficient of the interior medium. Suitable for a large body of liquid or one that is fairly thick, such as an ocean, honey, ice, or frosted glass." />
<input name="transmission_scatter_anisotropy" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Transmission Anisotropy" uifolder="Transmission" uiadvanced="true" doc="The amount of directional bias, or anisotropy, of the scattering." />
<input name="transmission_dispersion" type="float" value="0" uimin="0.0" uisoftmax="100.0" uiname="Transmission Dispersion" uifolder="Transmission" uiadvanced="true" doc="Dispersion amount, describing how much the index of refraction varies across wavelengths." />
<input name="transmission_extra_roughness" type="float" value="0" uimin="-1.0" uisoftmin="0.0" uimax="1.0" uiname="Transmission Roughness" uifolder="Transmission" uiadvanced="true" doc="Additional roughness on top of specular roughness. Positive values blur refractions more than reflections, and negative values blur refractions less." />
<input name="subsurface" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Subsurface" uifolder="Subsurface" uiadvanced="true" doc="The blend between diffuse reflection and subsurface scattering. A value of 1.0 indicates full subsurface scattering and a value 0 for diffuse reflection only." />
<input name="subsurface_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Color" uifolder="Subsurface" uiadvanced="true" doc="The color of the subsurface scattering effect." />
<input name="subsurface_radius" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Radius" uifolder="Subsurface" uiadvanced="true" doc="The mean free path. The distance which light can travel before being scattered inside the surface." />
<input name="subsurface_scale" type="float" value="1" uimin="0.0" uisoftmax="10.0" uiname="Subsurface Scale" uifolder="Subsurface" uiadvanced="true" doc="Scalar weight for the subsurface radius value." />
<input name="subsurface_anisotropy" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Subsurface Anisotropy" uifolder="Subsurface" uiadvanced="true" doc="The direction of subsurface scattering. 0 scatters light evenly, positive values scatter forward and negative values scatter backward." />
<input name="sheen" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Sheen" uifolder="Sheen" uiadvanced="true" doc="The weight of a sheen layer that can be used to approximate microfibers or fabrics such as velvet and satin." />
<input name="sheen_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Sheen Color" uifolder="Sheen" uiadvanced="true" doc="The color of the sheen layer." />
<input name="sheen_roughness" type="float" value="0.3" uimin="0.0" uimax="1.0" uiname="Sheen Roughness" uifolder="Sheen" uiadvanced="true" doc="The roughness of the sheen layer." />
<input name="coat" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Coat" uifolder="Coat" doc="The weight of a reflective clear-coat layer on top of the material. Use for materials such as car paint or an oily layer." />
<input name="coat_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Coat Color" uifolder="Coat" doc="The color of the clear-coat layer's transparency." />
<input name="coat_roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Coat Roughness" uifolder="Coat" doc="The roughness of the clear-coat reflections. The lower the value, the sharper the reflection." />
<input name="coat_anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Anisotropy" uifolder="Coat" uiadvanced="true" doc="The amount of directional bias, or anisotropy, of the clear-coat layer." />
<input name="coat_rotation" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Rotation" uifolder="Coat" uiadvanced="true" doc="The rotation of the anisotropic effect of the clear-coat layer." />
<input name="coat_IOR" type="float" value="1.5" uimin="0.0" uisoftmax="3.0" uiname="Coat Index of Refraction" uifolder="Coat" doc="The index of refraction of the clear-coat layer." />
<input name="coat_normal" type="vector3" defaultgeomprop="Nworld" uiname="Coat normal" uifolder="Coat" doc="Input normal for clear-coat layer" />
<input name="coat_affect_color" type="float" value="0" uimin="0" uimax="1" uiname="Coat Affect Color" uifolder="Coat" uiadvanced="true" doc="Controls the saturation of diffuse reflection and subsurface scattering below the clear-coat." />
<input name="coat_affect_roughness" type="float" value="0" uimin="0" uimax="1" uiname="Coat Affect Roughness" uifolder="Coat" uiadvanced="true" doc="Controls the roughness of the specular reflection in the layers below the clear-coat." />
<input name="thin_film_thickness" type="float" value="0" uimin="0.0" uisoftmax="2000.0" uiname="Thin Film Thickness" uifolder="Thin Film" uiadvanced="true" doc="The thickness of the thin film layer on a surface. Use for materials such as multitone car paint or soap bubbles." />
<input name="thin_film_IOR" type="float" value="1.5" uimin="0.0" uisoftmax="3.0" uiname="Thin Film Index of Refraction" uifolder="Thin Film" uiadvanced="true" doc="The index of refraction of the medium surrounding the material." />
<input name="emission" type="float" value="0" uimin="0.0" uisoftmax="1.0" uiname="Emission" uifolder="Emission" doc="The amount of emitted incandescent light." />
<input name="emission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Emission Color" uifolder="Emission" doc="The color of the emitted light." />
<input name="opacity" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Opacity" uifolder="Geometry" doc="The opacity of the entire material." />
<input name="thin_walled" type="boolean" value="false" uiname="Thin Walled" uifolder="Geometry" uiadvanced="true" doc="If true the surface is double-sided and represents an infinitely thin shell. Suiteable for thin objects such as tree leafs or paper" />
<input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Geometry" doc="Input geometric normal" />
<input name="tangent" type="vector3" defaultgeomprop="Tworld" uiname="Tangent Input" uifolder="Geometry" doc="Input geometric tangent" />
<output name="out" type="surfaceshader" />
</nodedef>
<!--
Autodesk Standard Surface nodegraph implementation.
-->
<nodegraph name="IMPL_standard_surface_surfaceshader" nodedef="ND_standard_surface_surfaceshader">
<!-- Roughness influence by coat-->
<multiply name="coat_affect_roughness_multiply1" type="float">
<input name="in1" type="float" interfacename="coat_affect_roughness" />
<input name="in2" type="float" interfacename="coat" />
</multiply>
<multiply name="coat_affect_roughness_multiply2" type="float">
<input name="in1" type="float" nodename="coat_affect_roughness_multiply1" />
<input name="in2" type="float" interfacename="coat_roughness" />
</multiply>
<mix name="coat_affected_roughness" type="float">
<input name="fg" type="float" value="1.0" />
<input name="bg" type="float" interfacename="specular_roughness" />
<input name="mix" type="float" nodename="coat_affect_roughness_multiply2" />
</mix>
<roughness_anisotropy name="main_roughness" type="vector2">
<input name="roughness" type="float" nodename="coat_affected_roughness" />
<input name="anisotropy" type="float" interfacename="specular_anisotropy" />
</roughness_anisotropy>
<!-- Tangent rotation -->
<multiply name="tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="specular_rotation" />
<input name="in2" type="float" value="360" />
</multiply>
<rotate3d name="tangent_rotate" type="vector3">
<input name="in" type="vector3" interfacename="tangent" />
<input name="amount" type="float" nodename="tangent_rotate_degree" />
<input name="axis" type="vector3" interfacename="normal" />
</rotate3d>
<normalize name="tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="tangent_rotate" />
</normalize>
<ifgreater name="main_tangent" type="vector3">
<input name="value1" type="float" interfacename="specular_anisotropy" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="vector3" nodename="tangent_rotate_normalize" />
<input name="in2" type="vector3" interfacename="tangent" />
</ifgreater>
<!-- Coat tangent rotation -->
<multiply name="coat_tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="coat_rotation" />
<input name="in2" type="float" value="360" />
</multiply>
<rotate3d name="coat_tangent_rotate" type="vector3">
<input name="in" type="vector3" interfacename="tangent" />
<input name="amount" type="float" nodename="coat_tangent_rotate_degree" />
<input name="axis" type="vector3" interfacename="coat_normal" />
</rotate3d>
<normalize name="coat_tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="coat_tangent_rotate" />
</normalize>
<ifgreater name="coat_tangent" type="vector3">
<input name="value1" type="float" interfacename="coat_anisotropy" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="vector3" nodename="coat_tangent_rotate_normalize" />
<input name="in2" type="vector3" interfacename="tangent" />
</ifgreater>
<!-- Colors influenced by coat ("coat gamma") -->
<clamp name="coat_clamped" type="float">
<input name="in" type="float" interfacename="coat" />
</clamp>
<multiply name="coat_gamma_multiply" type="float">
<input name="in1" type="float" nodename="coat_clamped" />
<input name="in2" type="float" interfacename="coat_affect_color" />
</multiply>
<add name="coat_gamma" type="float">
<input name="in1" type="float" nodename="coat_gamma_multiply" />
<input name="in2" type="float" value="1.0" />
</add>
<power name="coat_affected_diffuse_color" type="color3">
<input name="in1" type="color3" interfacename="base_color" />
<input name="in2" type="float" nodename="coat_gamma" />
</power>
<power name="coat_affected_subsurface_color" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color" />
<input name="in2" type="float" nodename="coat_gamma" />
</power>
<!-- Diffuse/Subsurface Layer -->
<oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="base" />
<input name="color" type="color3" nodename="coat_affected_diffuse_color" />
<input name="roughness" type="float" interfacename="diffuse_roughness" />
<input name="normal" type="vector3" interfacename="normal" />
</oren_nayar_diffuse_bsdf>
<translucent_bsdf name="translucent_bsdf" type="BSDF">
<input name="weight" type="float" value="1.0" />
<input name="color" type="color3" nodename="coat_affected_subsurface_color" />
<input name="normal" type="vector3" interfacename="normal" />
</translucent_bsdf>
<convert name="subsurface_radius_vector" type="vector3">
<input name="in" type="color3" interfacename="subsurface_radius" />
</convert>
<multiply name="subsurface_radius_scaled" type="vector3">
<input name="in1" type="vector3" nodename="subsurface_radius_vector" />
<input name="in2" type="float" interfacename="subsurface_scale" />
</multiply>
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="weight" type="float" value="1.0" />
<input name="color" type="color3" nodename="coat_affected_subsurface_color" />
<input name="radius" type="vector3" nodename="subsurface_radius_scaled" />
<input name="anisotropy" type="float" interfacename="subsurface_anisotropy" />
<input name="normal" type="vector3" interfacename="normal" />
</subsurface_bsdf>
<convert name="subsurface_selector" type="float">
<input name="in" type="boolean" interfacename="thin_walled" />
</convert>
<mix name="selected_subsurface_bsdf" type="BSDF">
<input name="fg" type="BSDF" nodename="translucent_bsdf" />
<input name="bg" type="BSDF" nodename="subsurface_bsdf" />
<input name="mix" type="float" nodename="subsurface_selector" />
</mix>
<mix name="subsurface_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="selected_subsurface_bsdf" />
<input name="bg" type="BSDF" nodename="diffuse_bsdf" />
<input name="mix" type="float" interfacename="subsurface" />
</mix>
<!-- Sheen Layer -->
<sheen_bsdf name="sheen_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="sheen" />
<input name="color" type="color3" interfacename="sheen_color" />
<input name="roughness" type="float" interfacename="sheen_roughness" />
<input name="normal" type="vector3" interfacename="normal" />
</sheen_bsdf>
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf" />
<input name="base" type="BSDF" nodename="subsurface_mix" />
</layer>
<!-- Transmission Layer -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" value="1.0" />
<input name="tint" type="color3" interfacename="transmission_color" />
<input name="ior" type="float" interfacename="specular_IOR" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="main_tangent" />
<input name="distribution" type="string" value="ggx" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="transmission_bsdf" />
<input name="bg" type="BSDF" nodename="sheen_layer" />
<input name="mix" type="float" interfacename="transmission" />
</mix>
<!-- Thin-film -->
<thin_film_bsdf name="thin_film_bsdf" type="BSDF">
<input name="thickness" type="float" interfacename="thin_film_thickness" />
<input name="ior" type="float" interfacename="thin_film_IOR" />
</thin_film_bsdf>
<!-- Specular Layer -->
<dielectric_bsdf name="specular_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="specular" />
<input name="tint" type="color3" interfacename="specular_color" />
<input name="ior" type="float" interfacename="specular_IOR" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="main_tangent" />
<input name="distribution" type="string" value="ggx" />
<input name="scatter_mode" type="string" value="R" />
</dielectric_bsdf>
<layer name="specular_layer" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>
<layer name="specular_layer_with_thin_film" type="BSDF">
<input name="top" type="BSDF" nodename="thin_film_bsdf" />
<input name="base" type="BSDF" nodename="specular_layer" />
</layer>
<!-- Metal Layer -->
<multiply name="metal_reflectivity" type="color3">
<input name="in1" type="color3" interfacename="base_color" />
<input name="in2" type="float" interfacename="base" />
</multiply>
<multiply name="metal_edgecolor" type="color3">
<input name="in1" type="color3" interfacename="specular_color" />
<input name="in2" type="float" interfacename="specular" />
</multiply>
<artistic_ior name="artistic_ior" type="multioutput">
<input name="reflectivity" type="color3" nodename="metal_reflectivity" />
<input name="edge_color" type="color3" nodename="metal_edgecolor" />
</artistic_ior>
<conductor_bsdf name="metal_bsdf" type="BSDF">
<input name="weight" type="float" value="1.0" />
<input name="ior" type="color3" nodename="artistic_ior" output="ior" />
<input name="extinction" type="color3" nodename="artistic_ior" output="extinction" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="main_tangent" />
<input name="distribution" type="string" value="ggx" />
</conductor_bsdf>
<mix name="metalness_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="metal_bsdf" />
<input name="bg" type="BSDF" nodename="specular_layer_with_thin_film" />
<input name="mix" type="float" interfacename="metalness" />
</mix>
<!-- Coat Layer -->
<mix name="coat_attenuation" type="color3">
<input name="fg" type="color3" interfacename="coat_color" />
<input name="bg" type="color3" value="1.0, 1.0, 1.0" />
<input name="mix" type="float" interfacename="coat" />
</mix>
<multiply name="metalness_mix_attenuated" type="BSDF">
<input name="in1" type="BSDF" nodename="metalness_mix" />
<input name="in2" type="color3" nodename="coat_attenuation" />
</multiply>
<roughness_anisotropy name="coat_roughness_vector" type="vector2">
<input name="roughness" type="float" interfacename="coat_roughness" />
<input name="anisotropy" type="float" interfacename="coat_anisotropy" />
</roughness_anisotropy>
<dielectric_bsdf name="coat_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="coat" />
<input name="tint" type="color3" value="1.0, 1.0, 1.0" />
<input name="ior" type="float" interfacename="coat_IOR" />
<input name="roughness" type="vector2" nodename="coat_roughness_vector" />
<input name="normal" type="vector3" interfacename="coat_normal" />
<input name="tangent" type="vector3" nodename="coat_tangent" />
<input name="distribution" type="string" value="ggx" />
<input name="scatter_mode" type="string" value="R" />
</dielectric_bsdf>
<layer name="coat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="coat_bsdf" />
<input name="base" type="BSDF" nodename="metalness_mix_attenuated" />
</layer>
<!-- Emission Layer -->
<multiply name="emission_weight" type="color3">
<input name="in1" type="color3" interfacename="emission_color" />
<input name="in2" type="float" interfacename="emission" />
</multiply>
<mix name="coat_emission_attenuation" type="color3">
<input name="fg" type="color3" interfacename="coat_color" />
<input name="bg" type="color3" value="1.0, 1.0, 1.0" />
<input name="mix" type="float" interfacename="coat" />
</mix>
<multiply name="emission_weight_attenuated" type="color3">
<input name="in1" type="color3" nodename="emission_weight" />
<input name="in2" type="color3" nodename="coat_emission_attenuation" />
</multiply>
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" nodename="emission_weight_attenuated" />
</uniform_edf>
<!-- Surface construction with opacity -->
<!-- Node <surface> only supports monochromatic opacity so use the luminance of input opacity color -->
<luminance name="opacity_luminance" type="color3">
<input name="in" type="color3" interfacename="opacity" />
</luminance>
<swizzle name="opacity_luminance_r" type="float">
<input name="in" type="color3" nodename="opacity_luminance" />
<param name="channels" type="string" value="r" />
</swizzle>
<surface name="shader_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_layer" />
<input name="edf" type="EDF" nodename="emission_edf" />
<input name="opacity" type="float" nodename="opacity_luminance_r" />
</surface>
<!-- Output -->
<output name="out" type="surfaceshader" nodename="shader_constructor" />
</nodegraph>
</materialx>

View File

@ -0,0 +1,335 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!-- ======================================================================== -->
<!-- USD Preview Surface node definitions -->
<!-- ======================================================================== -->
<!-- Node: UsdPreviewSurface -->
<nodedef name="ND_UsdPreviewSurface_surfaceshader" node="UsdPreviewSurface" nodegroup="pbr" doc="USD preview surface shader" version="2.3" isdefaultversion="true">
<input name="diffuseColor" type="color3" value="0.18, 0.18, 0.18" />
<input name="emissiveColor" type="color3" value="0, 0, 0" />
<input name="useSpecularWorkflow" type="integer" value="0" />
<input name="specularColor" type="color3" value="0, 0, 0" />
<input name="metallic" type="float" value="0" />
<input name="roughness" type="float" value="0.01" />
<input name="clearcoat" type="float" value="0" />
<input name="clearcoatRoughness" type="float" value="0.01" />
<input name="opacity" type="float" value="1" />
<input name="opacityThreshold" type="float" value="0" />
<input name="ior" type="float" value="1.5" />
<input name="normal" type="vector3" value="0, 0, 1" />
<input name="displacement" type="float" value="0" />
<input name="occlusion" type="float" value="1" />
<output name="out" type="surfaceshader" />
</nodedef>
<!-- Node: UsdUVTexture -->
<nodedef name="ND_UsdUVTexture" node="UsdUVTexture">
<input name="file" type="filename" uniform="true" />
<input name="st" type="vector2" defaultgeomprop="UV0" />
<input name="wrapS" type="string" value="periodic" enum="black,clamp,periodic" uniform="true" />
<input name="wrapT" type="string" value="periodic" enum="black,clamp,periodic" uniform="true" />
<input name="fallback" type="color4" value="0, 0, 0, 1" />
<input name="scale" type="color4" value="1, 1, 1, 1" uniform="true" />
<input name="bias" type="color4" value="0, 0, 0, 0" uniform="true" />
<output name="r" type="float" />
<output name="g" type="float" />
<output name="b" type="float" />
<output name="a" type="float" />
<output name="rgb" type="color3" />
<output name="rgba" type="color4" />
</nodedef>
<!-- Node: UsdPrimvarReader -->
<nodedef name="ND_UsdPrimvarReader_integer" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="integer" value="0" />
<output name="out" type="integer" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_boolean" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="boolean" value="false" />
<output name="out" type="boolean" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_string" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="string" value="" />
<output name="out" type="string" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_float" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="float" value="0" />
<output name="out" type="float" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_vector2" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="vector2" value="0, 0" />
<output name="out" type="vector2" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_vector3" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="vector3" value="0, 0, 0" />
<output name="out" type="vector3" />
</nodedef>
<nodedef name="ND_UsdPrimvarReader_vector4" node="UsdPrimvarReader">
<input name="varname" type="string" uniform="true" />
<input name="fallback" type="vector4" value="0, 0, 0, 0" />
<output name="out" type="vector4" />
</nodedef>
<!-- TODO: Getting primvar of matrix type is not supported in MaterialX standard library.
<nodedef name="ND_UsdPrimvarReader_matrix44" node="UsdPrimvarReader">
<input name="varname" type="string" />
<input name="fallback" type="matrix44" value="1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1" />
<output name="out" type="matrix44" />
</nodedef>
-->
<!-- Node: UsdTransform2d -->
<nodedef name="ND_UsdTransform2d" node="UsdTransform2d">
<input name="in" type="vector2" />
<input name="rotation" type="float" value="0" />
<input name="scale" type="vector2" value="1, 1" />
<input name="translation" type="vector2" value="0, 0" />
<output name="out" type="vector2" />
</nodedef>
<!-- ======================================================================== -->
<!-- USD Preview Surface nodegraph implementations -->
<!-- ======================================================================== -->
<!-- Node: UsdPreviewSurface -->
<nodegraph name="IMP_UsdPreviewSurface_surfaceshader" nodedef="ND_UsdPreviewSurface_surfaceshader">
<!-- Compute the per-pixel surface normal -->
<multiply name="scale_normal" type="vector3">
<input name="in1" type="vector3" interfacename="normal" />
<input name="in2" type="float" value="0.5" />
</multiply>
<add name="bias_normal" type="vector3">
<input name="in1" type="vector3" nodename="scale_normal" />
<input name="in2" type="float" value="0.5" />
</add>
<normalmap name="surface_normal" type="vector3">
<input name="in" type="vector3" nodename="bias_normal" />
</normalmap>
<!-- Diffuse Layer -->
<oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="color" type="color3" interfacename="diffuseColor" />
<input name="roughness" type="float" value="0" />
<input name="normal" type="vector3" nodename="surface_normal" />
</oren_nayar_diffuse_bsdf>
<!-- Transmission Layer -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="tint" type="color3" value="1, 1, 1" />
<input name="ior" type="float" interfacename="ior" />
<input name="normal" type="vector3" nodename="surface_normal" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="diffuse_bsdf" />
<input name="bg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" interfacename="opacity" />
</mix>
<!-- Specular Workflow -->
<roughness_anisotropy name="specular_roughness" type="vector2">
<input name="roughness" type="float" interfacename="roughness" />
<input name="anisotropy" type="float" value="0" />
</roughness_anisotropy>
<generalized_schlick_bsdf name="specular_bsdf1" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="color0" type="color3" interfacename="specularColor" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</generalized_schlick_bsdf>
<layer name="specular_workflow_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf1" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>
<!-- Metalness Workflow -->
<subtract name="one_minus_ior" type="float">
<input name="in1" type="float" value="1" />
<input name="in2" type="float" interfacename="ior" />
</subtract>
<add name="one_plus_ior" type="float">
<input name="in1" type="float" value="1" />
<input name="in2" type="float" interfacename="ior" />
</add>
<divide name="div_ior" type="float">
<input name="in1" type="float" nodename="one_minus_ior" />
<input name="in2" type="float" nodename="one_plus_ior" />
</divide>
<multiply name="F0" type="float">
<input name="in1" type="float" nodename="div_ior" />
<input name="in2" type="float" nodename="div_ior" />
</multiply>
<generalized_schlick_bsdf name="specular_bsdf2" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="color0" type="color3" nodename="F0" channels="rrr" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</generalized_schlick_bsdf>
<layer name="metalness_specular_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf2" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>
<artistic_ior name="artistic_ior" type="multioutput">
<input name="reflectivity" type="color3" interfacename="diffuseColor" />
<input name="edge_color" type="color3" interfacename="diffuseColor" />
</artistic_ior>
<conductor_bsdf name="metalness_metal_bsdf" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="ior" type="color3" nodename="artistic_ior" output="ior" />
<input name="extinction" type="color3" nodename="artistic_ior" output="extinction" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</conductor_bsdf>
<mix name="metalness_workflow_bsdf" type="BSDF">
<input name="fg" type="BSDF" nodename="metalness_metal_bsdf" />
<input name="bg" type="BSDF" nodename="metalness_specular_bsdf" />
<input name="mix" type="float" interfacename="metallic" />
</mix>
<!-- Select Specular/Metalness workflow -->
<convert name="use_specular_workflow_float" type="float">
<input name="in" type="integer" interfacename="useSpecularWorkflow" />
</convert>
<mix name="workflow_selector_bsdf" type="BSDF">
<input name="fg" type="BSDF" nodename="specular_workflow_bsdf" />
<input name="bg" type="BSDF" nodename="metalness_workflow_bsdf" />
<input name="mix" type="float" nodename="use_specular_workflow_float" />
</mix>
<!-- Clearcoat Layer -->
<roughness_anisotropy name="coat_roughness" type="vector2">
<input name="roughness" type="float" interfacename="clearcoatRoughness" />
<input name="anisotropy" type="float" value="0" />
</roughness_anisotropy>
<dielectric_bsdf name="coat_dielectric_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="clearcoat" />
<input name="tint" type="color3" value="1, 1, 1" />
<input name="ior" type="float" value="1.5" />
<input name="roughness" type="vector2" nodename="coat_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</dielectric_bsdf>
<layer name="coat_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="coat_dielectric_bsdf" />
<input name="base" type="BSDF" nodename="workflow_selector_bsdf" />
</layer>
<!-- Emission Layer -->
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" interfacename="emissiveColor" />
</uniform_edf>
<!-- Surface Shader Constructor -->
<clamp name="opacity_clamped" type="float">
<input name="in" type="float" interfacename="opacity" />
<input name="low" type="float" value="0.00001" />
<input name="high" type="float" value="1.0" />
</clamp>
<ifgreater name="cutout_opacity" type="float">
<input name="value1" type="float" nodename="opacity_clamped" />
<input name="value2" type="float" interfacename="opacityThreshold" />
<input name="in1" type="float" value="1" />
<input name="in2" type="float" value="0" />
</ifgreater>
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_bsdf" />
<input name="edf" type="EDF" nodename="emission_edf" />
<input name="opacity" type="float" nodename="cutout_opacity" />
</surface>
<!-- Output -->
<output name="out" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>
<!-- Node: UsdUVTexture -->
<nodegraph name="IMP_UsdUVTexture" nodedef="ND_UsdUVTexture">
<image name="image_reader" type="color4">
<input name="file" type="filename" interfacename="file" />
<input name="default" type="color4" interfacename="fallback" />
<input name="texcoord" type="vector2" interfacename="st" />
<input name="uaddressmode" type="string" interfacename="wrapS" />
<input name="vaddressmode" type="string" interfacename="wrapT" />
</image>
<multiply name="image_scale" type="color4">
<input name="in1" type="color4" nodename="image_reader" />
<input name="in2" type="color4" interfacename="scale" />
</multiply>
<add name="image_bias" type="color4">
<input name="in1" type="color4" nodename="image_scale" />
<input name="in2" type="color4" interfacename="bias" />
</add>
<output name="r" type="float" nodename="image_bias" channels="r" />
<output name="g" type="float" nodename="image_bias" channels="g" />
<output name="b" type="float" nodename="image_bias" channels="b" />
<output name="a" type="float" nodename="image_bias" channels="a" />
<output name="rgb" type="color3" nodename="image_bias" channels="rgb" />
<output name="rgba" type="color4" nodename="image_bias" />
</nodegraph>
<!-- Node: UsdPrimvarReader -->
<nodegraph name="IMP_UsdPrimvarReader_integer" nodedef="ND_UsdPrimvarReader_integer">
<geompropvalue name="primvar" type="integer">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="integer" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_boolean" nodedef="ND_UsdPrimvarReader_boolean">
<geompropvalue name="primvar" type="boolean">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="boolean" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_string" nodedef="ND_UsdPrimvarReader_string">
<geompropvalue name="primvar" type="string">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="string" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_float" nodedef="ND_UsdPrimvarReader_float">
<geompropvalue name="primvar" type="float">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="float" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_vector2" nodedef="ND_UsdPrimvarReader_vector2">
<geompropvalue name="primvar" type="vector2">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="vector2" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_vector3" nodedef="ND_UsdPrimvarReader_vector3">
<geompropvalue name="primvar" type="vector3">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="vector3" nodename="primvar" />
</nodegraph>
<nodegraph name="IMP_UsdPrimvarReader_vector4" nodedef="ND_UsdPrimvarReader_vector4">
<geompropvalue name="primvar" type="vector4">
<input name="geomprop" type="string" interfacename="varname" />
</geompropvalue>
<output name="out" type="vector4" nodename="primvar" />
</nodegraph>
<!-- Node: UsdTransform2d -->
<nodegraph name="IMP_UsdTransform2d" nodedef="ND_UsdTransform2d">
<place2d name="placement" type="vector2">
<input name="texcoord" type="vector2" interfacename="in" />
<input name="scale" type="vector2" interfacename="scale" />
<input name="rotate" type="float" interfacename="rotation" />
<input name="offset" type="vector2" interfacename="translation" />
</place2d>
<output name="out" type="vector2" nodename="placement" />
</nodegraph>
</materialx>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<materialx version="1.37">
<!-- <point_light> -->
<implementation name="IM_point_light_genglsl" nodedef="ND_point_light" file="lights/genglsl/mx_point_light.glsl" function="mx_point_light" target="genglsl"/>
<!-- <directional_light> -->
<implementation name="IM_directional_light_genglsl" nodedef="ND_directional_light" file="lights/genglsl/mx_directional_light.glsl" function="mx_directional_light" target="genglsl"/>
<!-- <spot_light> -->
<implementation name="IM_spot_light_genglsl" nodedef="ND_spot_light" file="lights/genglsl/mx_spot_light.glsl" function="mx_spot_light" target="genglsl"/>
</materialx>

View File

@ -0,0 +1,5 @@
void mx_directional_light(LightData light, vec3 position, out lightshader result)
{
result.direction = -light.direction;
result.intensity = light.color * light.intensity;
}

View File

@ -0,0 +1,8 @@
void mx_point_light(LightData light, vec3 position, out lightshader result)
{
result.direction = light.position - position;
float distance = length(result.direction) + M_FLOAT_EPS;
float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
result.intensity = light.color * light.intensity / attenuation;
result.direction /= distance;
}

View File

@ -0,0 +1,13 @@
void mx_spot_light(LightData light, vec3 position, out lightshader result)
{
result.direction = light.position - position;
float distance = length(result.direction) + M_FLOAT_EPS;
float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
result.intensity = light.color * light.intensity / attenuation;
result.direction /= distance;
float low = min(light.inner_angle, light.outer_angle);
float high = light.inner_angle;
float cosDir = dot(result.direction, -light.direction);
float spotAttenuation = smoothstep(low, high, cosDir);
result.intensity *= spotAttenuation;
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
TM & (c) 2019 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
All rights reserved. See LICENSE.txt for license.
Declarations of example light shader nodes.
DISCLAIMER: These nodes are only to serve as examples of light shader nodes.
They are not standardized members of MaterialX's standard libraries, and they
may change in future revisions.
-->
<materialx version="1.37">
<!-- ======================================================================== -->
<!-- Light shader nodes -->
<!-- ======================================================================== -->
<!--
Node: <point_light>
-->
<nodedef name="ND_point_light" node="point_light" nodegroup="light"
doc="A light shader node of 'point' type.">
<input name="position" type="vector3" doc="Light source position."/>
<input name="color" type="color3" doc="Light color."/>
<input name="intensity" type="float" doc="Light intensity."/>
<input name="decay_rate" type="float" value="2.0" doc="Light decay exponent. Defaults to 2 for quadratic decay."/>
<output name="out" type="lightshader"/>
</nodedef>
<!--
Node: <directional_light>
-->
<nodedef name="ND_directional_light" node="directional_light" nodegroup="light"
doc="A light shader node of 'directional' type.">
<input name="direction" type="vector3" doc="Light source direction."/>
<input name="color" type="color3" doc="Light color."/>
<input name="intensity" type="float" doc="Light intensity."/>
<output name="out" type="lightshader"/>
</nodedef>
<!--
Node: <spot_light>
-->
<nodedef name="ND_spot_light" node="spot_light" nodegroup="light"
doc="A light shader node of 'spot' type.">
<input name="position" type="vector3" doc="Light source position."/>
<input name="direction" type="vector3" doc="Light source direction."/>
<input name="color" type="color3" doc="Light color."/>
<input name="intensity" type="float" doc="Light intensity."/>
<input name="decay_rate" type="float" value="2.0" doc="Light decay exponent. Defaults to 2 for quadratic decay."/>
<input name="inner_angle" type="float" doc="Inner cone angle."/>
<input name="outer_angle" type="float" doc="Outer cone angle."/>
<output name="out" type="lightshader"/>
</nodedef>
</materialx>

View File

@ -0,0 +1,4 @@
#define M_PI 3.1415926535897932384626433832795
#define M_PI_INV 1.0/3.1415926535897932384626433832795
#define M_GOLDEN_RATIO 1.6180339887498948482045868343656
#define M_FLOAT_EPS 1e-8

View File

@ -0,0 +1,72 @@
#include "pbrlib/genglsl/lib/mx_microfacet_specular.glsl"
int numRadianceSamples()
{
return min($envRadianceSamples, MAX_ENV_RADIANCE_SAMPLES);
}
// 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(envSamples * pdf * distortion), 0.0);
}
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 roughness, int distribution, FresnelData fd)
{
vec3 Y = normalize(cross(N, X));
X = cross(Y, N);
// Compute shared dot products.
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
// 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 = numRadianceSamples();
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_NDF(Xi, X, Y, N, roughness.x, roughness.y);
vec3 L = -reflect(V, H);
// Compute dot products for this sample.
float NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
float LdotH = VdotH;
// Sample the environment light from the given direction.
float pdf = mx_ggx_PDF(X, Y, H, NdotH, LdotH, roughness.x, roughness.y);
float lod = mx_latlong_compute_lod(L, pdf, $envRadianceMips - 1, envRadianceSamples);
vec3 sampleColor = mx_latlong_map_lookup(L, $envMatrix, lod, $envRadiance);
// Compute the Fresnel term.
vec3 F = mx_compute_fresnel(VdotH, fd);
// Compute the geometric term.
float G = mx_ggx_smith_G(NdotL, NdotV, mx_average_roughness(roughness));
// Add the radiance contribution of this sample.
// From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
// incidentLight = sampleColor * NdotL
// microfacetSpecular = D * F * G / (4 * NdotL * NdotV)
// pdf = D * NdotH / (4 * VdotH)
// radiance = incidentLight * microfacetSpecular / pdf
radiance += sampleColor * F * G * VdotH / (NdotV * NdotH);
}
// Normalize and return the final radiance.
radiance /= float(envRadianceSamples);
return radiance;
}
vec3 mx_environment_irradiance(vec3 N)
{
return mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
}

View File

@ -0,0 +1,11 @@
#include "pbrlib/genglsl/lib/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);
}

View File

@ -0,0 +1,29 @@
#include "pbrlib/genglsl/lib/mx_microfacet_specular.glsl"
float mx_latlong_compute_lod(float roughness)
{
// Select a mip level based on input roughness.
float lodBias = roughness < 0.25 ? sqrt(roughness) : 0.5*roughness + 0.375;
return lodBias * $envRadianceMips;
}
vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 roughness, int distribution, FresnelData fd)
{
N = mx_forward_facing_normal(N, V);
vec3 L = reflect(-V, N);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float avgRoughness = mx_average_roughness(roughness);
vec3 F = mx_compute_fresnel(NdotV, fd);
float G = mx_ggx_smith_G(NdotV, NdotV, avgRoughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_compute_lod(avgRoughness), $envRadiance);
return Li * F * G * comp;
}
vec3 mx_environment_irradiance(vec3 N)
{
return mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
}

View File

@ -0,0 +1,83 @@
float mx_square(float x)
{
return x*x;
}
vec2 mx_square(vec2 x)
{
return x*x;
}
vec3 mx_square(vec3 x)
{
return x*x;
}
vec4 mx_square(vec4 x)
{
return x*x;
}
float mx_pow5(float x)
{
return mx_square(mx_square(x)) * x;
}
float mx_max_component(vec2 v)
{
return max(v.x, v.y);
}
float mx_max_component(vec3 v)
{
return max(max(v.x, v.y), v.z);
}
float mx_max_component(vec4 v)
{
return max(max(max(v.x, v.y), v.z), v.w);
}
bool mx_is_tiny(float v)
{
return abs(v) < M_FLOAT_EPS;
}
bool mx_is_tiny(vec3 v)
{
return all(lessThan(abs(v), vec3(M_FLOAT_EPS)));
}
float mx_mix(float v00, float v01, float v10, float v11,
float x, float y)
{
float v0_ = mix(v00, v01, x);
float v1_ = mix(v10, v11, x);
return mix(v0_, v1_, y);
}
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 sampler)
{
vec3 envDir = normalize((transform * vec4(dir,0.0)).xyz);
vec2 uv = mx_latlong_projection(envDir);
return textureLod(sampler, uv, lod).rgb;
}
vec3 mx_forward_facing_normal(vec3 N, vec3 V)
{
if (dot(N, V) < 0.0)
{
return -N;
}
else
{
return N;
}
}

View File

@ -0,0 +1,57 @@
// 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));
}
// Compute the average of an anisotropic roughness pair
float mx_average_roughness(vec2 roughness)
{
return sqrt(roughness.x * roughness.y);
}
// https://www.graphics.rwth-aachen.de/publication/2/jgt.pdf
float mx_golden_ratio_sequence(int i)
{
return fract((float(i) + 1.0) * M_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));
}

View File

@ -0,0 +1,84 @@
#include "pbrlib/genglsl/lib/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://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.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_directional_albedo(float NdotV, float roughness)
{
float x = NdotV;
float fit0 = 0.97619 - 0.488095 * mx_pow5(1 - 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) / SAMPLE_COUNT;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float x = -M_PI + (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);
}

View File

@ -0,0 +1,52 @@
#include "pbrlib/genglsl/lib/mx_microfacet.glsl"
// http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
// Equation 2
float mx_imageworks_sheen_NDF(float cosTheta, float roughness)
{
float invRoughness = 1.0 / max(roughness, 0.0001);
float cos2 = cosTheta * cosTheta;
float sin2 = 1.0 - cos2;
return (2.0 + invRoughness) * pow(sin2, invRoughness * 0.5) / (2.0 * M_PI);
}
// LUT for sheen directional albedo.
// A 2D table parameterized with 'cosTheta' (cosine of angle to normal) on x-axis and 'roughness' on y-axis.
#define SHEEN_ALBEDO_TABLE_SIZE 16
const float u_sheenAlbedo[SHEEN_ALBEDO_TABLE_SIZE*SHEEN_ALBEDO_TABLE_SIZE] = float[](
1.6177, 0.978927, 0.618938, 0.391714, 0.245177, 0.150234, 0.0893475, 0.0511377, 0.0280191, 0.0144204, 0.00687674, 0.00295935, 0.00111049, 0.000336768, 7.07119e-05, 6.22646e-06,
1.1084, 0.813928, 0.621389, 0.479304, 0.370299, 0.284835, 0.21724, 0.163558, 0.121254, 0.0878921, 0.0619052, 0.0419894, 0.0270556, 0.0161443, 0.00848212, 0.00342323,
0.930468, 0.725652, 0.586532, 0.479542, 0.393596, 0.322736, 0.26353, 0.213565, 0.171456, 0.135718, 0.105481, 0.0800472, 0.0588117, 0.0412172, 0.0268329, 0.0152799,
0.833791, 0.671201, 0.558957, 0.471006, 0.398823, 0.337883, 0.285615, 0.240206, 0.200696, 0.16597, 0.135422, 0.10859, 0.0850611, 0.0644477, 0.0464763, 0.0308878,
0.771692, 0.633819, 0.537877, 0.461939, 0.398865, 0.344892, 0.297895, 0.256371, 0.219562, 0.186548, 0.156842, 0.130095, 0.10598, 0.0841919, 0.0645311, 0.04679,
0.727979, 0.606373, 0.52141, 0.453769, 0.397174, 0.348337, 0.305403, 0.267056, 0.232655, 0.201398, 0.17286, 0.146756, 0.122808, 0.100751, 0.0804254, 0.0616485,
0.695353, 0.585281, 0.508227, 0.44667, 0.394925, 0.350027, 0.310302, 0.274561, 0.242236, 0.212604, 0.185281, 0.16002, 0.13657, 0.114693, 0.0942543, 0.0750799,
0.669981, 0.568519, 0.497442, 0.440542, 0.392567, 0.350786, 0.313656, 0.280075, 0.249533, 0.221359, 0.195196, 0.170824, 0.148012, 0.126537, 0.106279, 0.0870713,
0.649644, 0.554855, 0.488453, 0.435237, 0.390279, 0.351028, 0.316036, 0.284274, 0.255266, 0.228387, 0.203297, 0.179796, 0.157665, 0.136695, 0.116774, 0.0977403,
0.632951, 0.543489, 0.480849, 0.430619, 0.388132, 0.350974, 0.317777, 0.287562, 0.259885, 0.234153, 0.210041, 0.187365, 0.165914, 0.145488, 0.125983, 0.10724,
0.61899, 0.533877, 0.47433, 0.426573, 0.386145, 0.35075, 0.319078, 0.290197, 0.263681, 0.238971, 0.215746, 0.193838, 0.173043, 0.153167, 0.134113, 0.115722,
0.607131, 0.52564, 0.468678, 0.423001, 0.38432, 0.35043, 0.320072, 0.292349, 0.266856, 0.243055, 0.220636, 0.199438, 0.179264, 0.159926, 0.141332, 0.123323,
0.596927, 0.518497, 0.463731, 0.419829, 0.382647, 0.350056, 0.320842, 0.294137, 0.269549, 0.246564, 0.224875, 0.204331, 0.18474, 0.165919, 0.147778, 0.130162,
0.588052, 0.512241, 0.459365, 0.416996, 0.381114, 0.349657, 0.321448, 0.295641, 0.271862, 0.24961, 0.228584, 0.208643, 0.189596, 0.171266, 0.153566, 0.136341,
0.580257, 0.506717, 0.455481, 0.41445, 0.379708, 0.34925, 0.321929, 0.296923, 0.273869, 0.252279, 0.231859, 0.212472, 0.193933, 0.176066, 0.158788, 0.141945,
0.573355, 0.5018, 0.452005, 0.412151, 0.378416, 0.348844, 0.322316, 0.298028, 0.275627, 0.254638, 0.234772, 0.215896, 0.197828, 0.180398, 0.163522, 0.147049
);
float mx_imageworks_sheen_directional_albedo(float cosTheta, float roughness)
{
float x = cosTheta * (SHEEN_ALBEDO_TABLE_SIZE - 1);
float y = roughness * (SHEEN_ALBEDO_TABLE_SIZE - 1);
int ix = int(x);
int iy = int(y);
int ix2 = clamp(ix + 1, 0, SHEEN_ALBEDO_TABLE_SIZE - 1);
int iy2 = clamp(iy + 1, 0, SHEEN_ALBEDO_TABLE_SIZE - 1);
float fx = x - ix;
float fy = y - iy;
// Bi-linear interpolation of the LUT values
float v1 = mix(u_sheenAlbedo[iy * SHEEN_ALBEDO_TABLE_SIZE + ix], u_sheenAlbedo[iy * SHEEN_ALBEDO_TABLE_SIZE + ix2], fx);
float v2 = mix(u_sheenAlbedo[iy2 * SHEEN_ALBEDO_TABLE_SIZE + ix], u_sheenAlbedo[iy2 * SHEEN_ALBEDO_TABLE_SIZE + ix2], fx);
float albedo = mix(v1, v2, fy);
return clamp(albedo, 0.0, 1.0);
}

View File

@ -0,0 +1,386 @@
#include "pbrlib/genglsl/lib/mx_microfacet.glsl"
// https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
// Appendix B.2 Equation 13
float mx_ggx_NDF(vec3 X, vec3 Y, vec3 H, float NdotH, float alphaX, float alphaY)
{
float XdotH = dot(X, H);
float YdotH = dot(Y, H);
float denom = mx_square(XdotH / alphaX) + mx_square(YdotH / alphaY) + mx_square(NdotH);
return 1.0 / (M_PI * alphaX * alphaY * mx_square(denom));
}
// https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
// Appendix B.1 Equation 3
float mx_ggx_PDF(vec3 X, vec3 Y, vec3 H, float NdotH, float LdotH, float alphaX, float alphaY)
{
return mx_ggx_NDF(X, Y, H, NdotH, alphaX, alphaY) * NdotH / (4.0 * LdotH);
}
// https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
// Appendix B.2 Equation 15
vec3 mx_ggx_importance_sample_NDF(vec2 Xi, vec3 X, vec3 Y, vec3 N, float alphaX, float alphaY)
{
float phi = 2.0 * M_PI * Xi.x;
float tanTheta = sqrt(Xi.y / (1.0 - Xi.y));
vec3 H = X * (tanTheta * alphaX * cos(phi)) +
Y * (tanTheta * alphaY * sin(phi)) +
N;
return normalize(H);
}
// http://jcgt.org/published/0003/02/03/paper.pdf
// Equations 72 and 99
float mx_ggx_smith_G(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);
}
// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
vec3 mx_ggx_directional_albedo_curve_fit(float NdotV, float roughness, vec3 F0, vec3 F90)
{
const vec4 c0 = vec4(-1, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4( 1, 0.0425, 1.04, -0.04 );
vec4 r = roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x + r.y;
vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
return F0 * AB.x + F90 * AB.y;
}
vec3 mx_ggx_directional_albedo_table_lookup(float NdotV, float roughness, vec3 F0, vec3 F90)
{
#if DIRECTIONAL_ALBEDO_METHOD == 1
vec2 res = textureSize($albedoTable, 0);
if (res.x > 1)
{
vec2 AB = texture($albedoTable, vec2(NdotV, roughness)).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_directional_albedo_importance_sample(float NdotV, float roughness, vec3 F0, vec3 F90)
{
NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
vec3 V = vec3(sqrt(1.0f - 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_NDF(Xi, vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), roughness, roughness);
vec3 L = -reflect(V, H);
// 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);
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 geometric visibility term.
float Gvis = mx_ggx_smith_G(NdotL, NdotV, roughness) * VdotH / (NdotH * NdotV);
// Add the contribution of this sample.
AB += vec2(Gvis * (1 - Fc), Gvis * Fc);
}
// Normalize integrated terms.
AB /= SAMPLE_COUNT;
// Return the final directional albedo.
return F0 * AB.x + F90 * AB.y;
}
vec3 mx_ggx_directional_albedo(float NdotV, float roughness, vec3 F0, vec3 F90)
{
#if DIRECTIONAL_ALBEDO_METHOD == 0
return mx_ggx_directional_albedo_curve_fit(NdotV, roughness, F0, F90);
#elif DIRECTIONAL_ALBEDO_METHOD == 1
return mx_ggx_directional_albedo_table_lookup(NdotV, roughness, F0, F90);
#else
return mx_ggx_directional_albedo_importance_sample(NdotV, roughness, F0, F90);
#endif
}
float mx_ggx_directional_albedo(float NdotV, float roughness, float F0, float F90)
{
return mx_ggx_directional_albedo(NdotV, roughness, 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 roughness, vec3 Fss)
{
float Ess = mx_ggx_directional_albedo(NdotV, roughness, 1.0, 1.0);
return 1.0 + Fss * (1.0 - Ess) / Ess;
}
float mx_ggx_energy_compensation(float NdotV, float roughness, float Fss)
{
return mx_ggx_energy_compensation(NdotV, roughness, vec3(Fss)).x;
}
// 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));
}
// 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);
}
vec3 mx_fresnel_conductor(float cosTheta, vec3 n, vec3 k)
{
float c2 = cosTheta*cosTheta;
vec3 n2_k2 = n*n + k*k;
vec3 nc2 = 2.0 * n * cosTheta;
vec3 rs_a = n2_k2 + c2;
vec3 rp_a = n2_k2 * c2 + 1.0;
vec3 rs = (rs_a - nc2) / (rs_a + nc2);
vec3 rp = (rp_a - nc2) / (rp_a + nc2);
return 0.5 * (rs + rp);
}
// Fresnel for dielectric/dielectric interface and polarized light.
void mx_fresnel_dielectric_polarized(float cosTheta, float n1, float n2, out vec2 F, out vec2 phi)
{
float eta2 = mx_square(n1 / n2);
float st2 = 1.0 - cosTheta*cosTheta;
// Check for total internal reflection
if(eta2*st2 > 1.0)
{
F = vec2(1.0);
float s = sqrt(st2 - 1.0/eta2) / cosTheta;
phi = 2.0 * atan(vec2(-eta2 * s, -s));
return;
}
float cosTheta_t = sqrt(1 - eta2 * st2);
vec2 r = vec2((n2*cosTheta - n1*cosTheta_t) / (n2*cosTheta + n1*cosTheta_t),
(n1*cosTheta - n2*cosTheta_t) / (n1*cosTheta + n2*cosTheta_t));
F = mx_square(r);
phi.x = (r.x < 0.0) ? M_PI : 0.0;
phi.y = (r.y < 0.0) ? M_PI : 0.0;
}
// Fresnel for dielectric/conductor interface and polarized light.
// TODO: Optimize this functions and support wavelength dependent complex refraction index.
void mx_fresnel_conductor_polarized(float cosTheta, float n1, float n2, float k, out vec2 F, out vec2 phi)
{
if (k == 0)
{
// Use dielectric formula to avoid numerical issues
mx_fresnel_dielectric_polarized(cosTheta, n1, n2, F, phi);
return;
}
float A = mx_square(n2) * (1.0 - mx_square(k)) - mx_square(n1) * (1.0 - mx_square(cosTheta));
float B = sqrt(mx_square(A) + mx_square(2.0 * mx_square(n2) * k));
float U = sqrt((A+B) / 2.0);
float V = sqrt((B-A) / 2.0);
F.y = (mx_square(n1*cosTheta - U) + mx_square(V)) / (mx_square(n1*cosTheta + U) + mx_square(V));
phi.y = atan(2.0*n1 * V*cosTheta, mx_square(U) + mx_square(V) - mx_square(n1*cosTheta)) + M_PI;
F.x = (mx_square(mx_square(n2) * (1.0 - mx_square(k)) * cosTheta - n1*U) + mx_square(2.0 * mx_square(n2) * k * cosTheta - n1*V)) /
(mx_square(mx_square(n2) * (1.0 - mx_square(k)) * cosTheta + n1*U) + mx_square(2.0 * mx_square(n2) * k * cosTheta + n1*V));
phi.x = atan(2.0 * n1 * mx_square(n2) * cosTheta * (2*k*U - (1.0 - mx_square(k)) * V), mx_square(mx_square(n2) * (1.0 + mx_square(k)) * cosTheta) - mx_square(n1) * (mx_square(U) + mx_square(V)));
}
// 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);
// Depolarization functions for natural light
float mx_depolarize(vec2 v)
{
return 0.5 * (v.x + v.y);
}
vec3 mx_depolarize(vec3 s, vec3 p)
{
return 0.5 * (s + p);
}
// Evaluation XYZ sensitivity curves in Fourier space
vec3 mx_eval_sensitivity(float opd, float shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
float phase = 2*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*M_PI * var) * cos(pos * phase + shift) * exp(- var * phase*phase);
xyz.x += 9.7470e-14 * sqrt(2*M_PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * 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/2017/05/01/brdf-thin-film.html
vec3 mx_fresnel_airy(float cosTheta, vec3 ior, vec3 extinction, float tf_thickness, float tf_ior)
{
// Convert nm -> m
float d = tf_thickness * 1.0e-9;
// Assume vacuum on the outside
float eta1 = 1.0;
float eta2 = tf_ior;
// Optical path difference
float cosTheta2 = sqrt(1.0 - mx_square(eta1/eta2) * (1.0 - mx_square(cosTheta)));
float D = 2.0 * eta2 * d * cosTheta2;
// First interface
vec2 R12, phi12;
mx_fresnel_dielectric_polarized(cosTheta, eta1, eta2, R12, phi12);
vec2 R21 = R12;
vec2 T121 = vec2(1.0) - R12;
vec2 phi21 = vec2(M_PI) - phi12;
// Second interface
vec2 R23, phi23;
mx_fresnel_conductor_polarized(cosTheta2, eta2, ior.x, extinction.x, R23, phi23);
// Phase shift
vec2 phi2 = phi21 + phi23;
// Compound terms
vec3 R = vec3(0.0);
vec2 R123 = R12*R23;
vec2 r123 = sqrt(R123);
vec2 Rs = mx_square(T121)*R23 / (1-R123);
// Reflectance term for m=0 (DC term amplitude)
vec2 C0 = R12 + Rs;
vec3 S0 = mx_eval_sensitivity(0.0, 0.0);
R += mx_depolarize(C0) * S0;
// Reflectance term for m>0 (pairs of diracs)
vec2 Cm = Rs - T121;
for (int m=1; m<=3; ++m)
{
Cm *= r123;
vec3 SmS = 2.0 * mx_eval_sensitivity(m*D, m*phi2.x);
vec3 SmP = 2.0 * mx_eval_sensitivity(m*D, m*phi2.y);
R += mx_depolarize(Cm.x*SmS, Cm.y*SmP);
}
// Convert back to RGB reflectance
R = clamp(XYZ_TO_RGB * R, vec3(0.0), vec3(1.0));
return R;
}
// Parameters for Fresnel calculations.
struct FresnelData
{
vec3 ior; // In Schlick Fresnel mode these two
vec3 extinction; // hold F0 and F90 reflectance values
float exponent;
float tf_thickness;
float tf_ior;
int model;
};
FresnelData mx_init_fresnel_dielectric(float ior)
{
FresnelData fd = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 0;
fd.ior = vec3(ior);
fd.tf_thickness = 0.0f;
return fd;
}
FresnelData mx_init_fresnel_conductor(vec3 ior, vec3 extinction)
{
FresnelData fd = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 1;
fd.ior = ior;
fd.extinction = extinction;
fd.tf_thickness = 0.0f;
return fd;
}
FresnelData mx_init_fresnel_schlick(vec3 F0)
{
FresnelData fd = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 2;
fd.ior = F0;
fd.extinction = vec3(1.0);
fd.exponent = 5.0f;
fd.tf_thickness = 0.0f;
return fd;
}
FresnelData mx_init_fresnel_schlick(vec3 F0, vec3 F90, float exponent)
{
FresnelData fd = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 2;
fd.ior = F0;
fd.extinction = F90;
fd.exponent = exponent;
fd.tf_thickness = 0.0f;
return fd;
}
FresnelData mx_init_fresnel_dielectric_airy(float ior, float tf_thickness, float tf_ior)
{
FresnelData fd = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 3;
fd.ior = vec3(ior);
fd.extinction = vec3(0.0);
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 = FresnelData(vec3(0), vec3(0), 0, 0, 0, -1);
fd.model = 3;
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 == 0)
return vec3(mx_fresnel_dielectric(cosTheta, fd.ior.x));
else if (fd.model == 1)
return mx_fresnel_conductor(cosTheta, fd.ior, fd.extinction);
else if (fd.model == 2)
// ior & extinction holds F0 & F90
return mx_fresnel_schlick(cosTheta, fd.ior, fd.extinction, fd.exponent);
else
return mx_fresnel_airy(cosTheta, fd.ior, fd.extinction, fd.tf_thickness, fd.tf_ior);
}

View File

@ -0,0 +1,31 @@
// "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
// http://jcgt.org/published/0003/04/03/paper.pdf
void mx_complex_to_artistic_ior(vec3 ior, vec3 extinction, out vec3 reflectivity, out vec3 edge_color)
{
vec3 nm1 = ior - 1.0;
vec3 np1 = ior + 1.0;
vec3 k2 = extinction * extinction;
vec3 r = (nm1*nm1 + k2) / (np1*np1 + k2);
reflectivity = r;
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);
edge_color = (n_max - ior) / (n_max - n_min);
}
void mx_artistic_to_complex_ior(vec3 reflectivity, vec3 edge_color, out vec3 ior, out vec3 extinction)
{
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);
}

View File

@ -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));
}

View File

@ -0,0 +1,7 @@
#include "pbrlib/genglsl/lib/mx_microfacet_specular.glsl"
vec2 mx_ggx_directional_albedo_generate_table()
{
vec2 uv = gl_FragCoord.xy / $albedoTableSize;
return mx_ggx_directional_albedo_importance_sample(uv.x, uv.y, vec3(1, 0, 0), vec3(0, 1, 0)).xy;
}

View File

@ -0,0 +1,14 @@
void mx_add_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, BSDF in1, BSDF in2, out BSDF result)
{
result = in1 + in2;
}
void mx_add_bsdf_transmission(vec3 V, BSDF in1, BSDF in2, out BSDF result)
{
result = in1 + in2;
}
void mx_add_bsdf_indirect(vec3 V, vec3 in1, vec3 in2, out vec3 result)
{
result = in1 + in2;
}

View File

@ -0,0 +1,4 @@
void mx_add_edf(vec3 N, vec3 L, EDF in1, EDF in2, out EDF result)
{
result = in1 + in2;
}

View File

@ -0,0 +1,6 @@
#include "pbrlib/genglsl/lib/mx_refraction_index.glsl"
void mx_artistic_ior(vec3 reflectivity, vec3 edge_color, out vec3 ior, out vec3 extinction)
{
mx_artistic_to_complex_ior(reflectivity, edge_color, ior, extinction);
}

View File

@ -0,0 +1,35 @@
#include "pbrlib/genglsl/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, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
normal = mx_forward_facing_normal(normal, V);
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
result = color * occlusion * weight * NdotL * M_PI_INV;
result *= mx_burley_diffuse(L, V, normal, NdotL, roughness);
return;
}
void mx_burley_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
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_directional_albedo(NdotV, roughness);
result = Li * color * weight;
}

View File

@ -0,0 +1,55 @@
#include "pbrlib/genglsl/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, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
N = mx_forward_facing_normal(N, V);
vec3 Y = normalize(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 NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
FresnelData fd = tf.thickness > 0.0 ? mx_init_fresnel_conductor_airy(ior_n, ior_k, tf.thickness, tf.ior) : mx_init_fresnel_conductor(ior_n, ior_k);
vec3 F = mx_compute_fresnel(VdotH, fd);
float avgRoughness = mx_average_roughness(roughness);
float D = mx_ggx_NDF(X, Y, H, NdotH, roughness.x, roughness.y);
float G = mx_ggx_smith_G(NdotL, NdotV, avgRoughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
// Note: NdotL is cancelled out
result = D * F * G * comp * occlusion * weight / (4 * NdotV);
}
void mx_conductor_bsdf_indirect(vec3 V, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, vec3 N, vec3 X, int distribution, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd = tf.thickness > 0.0 ? mx_init_fresnel_conductor_airy(ior_n, ior_k, tf.thickness, tf.ior) : mx_init_fresnel_conductor(ior_n, ior_k);
vec3 F = mx_compute_fresnel(NdotV, fd);
vec3 Li = mx_environment_radiance(N, V, X, roughness, distribution, fd);
float avgRoughness = mx_average_roughness(roughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
result = Li * comp * weight;
}

View File

@ -0,0 +1,96 @@
#include "pbrlib/genglsl/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, BSDF base, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
vec3 Y = normalize(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 NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
float avgRoughness = mx_average_roughness(roughness);
FresnelData fd = tf.thickness > 0.0 ? mx_init_fresnel_dielectric_airy(ior, tf.thickness, tf.ior) : mx_init_fresnel_dielectric(ior);
vec3 F = mx_compute_fresnel(VdotH, fd);
float D = mx_ggx_NDF(X, Y, H, NdotH, roughness.x, roughness.y);
float G = mx_ggx_smith_G(NdotL, NdotV, avgRoughness);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, F0, 1.0) * comp;
// Note: NdotL is cancelled out
result = D * F * G * comp * tint * occlusion * weight / (4 * NdotV) // Top layer reflection
+ base * (1.0 - dirAlbedo * weight); // Base layer reflection attenuated by top layer
}
void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, BSDF base, thinfilm tf, out BSDF result)
{
if (scatter_mode == 1)
{
result = tint * weight;
return;
}
if (scatter_mode == 2)
{
// No external layering in RT mode,
// the base is always T in this case.
base = tint * weight;
}
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd = tf.thickness > 0.0 ? mx_init_fresnel_dielectric_airy(ior, tf.thickness, tf.ior) : mx_init_fresnel_dielectric(ior);
vec3 F = mx_compute_fresnel(NdotV, fd);
float avgRoughness = mx_average_roughness(roughness);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, F0, 1.0) * comp;
result = base * (1.0 - dirAlbedo * weight); // Transmission attenuated by reflection amount
}
void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, BSDF base, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd = tf.thickness > 0.0 ? mx_init_fresnel_dielectric_airy(ior, tf.thickness, tf.ior) : mx_init_fresnel_dielectric(ior);
vec3 F = mx_compute_fresnel(NdotV, fd);
float avgRoughness = mx_average_roughness(roughness);
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, F0, 1.0) * comp;
vec3 Li = mx_environment_radiance(N, V, X, roughness, distribution, fd);
result = Li * tint * comp * weight // Top layer reflection
+ base * (1.0 - dirAlbedo * weight); // Base layer reflection attenuated by top layer
}

View File

@ -0,0 +1,86 @@
#include "pbrlib/genglsl/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, BSDF base, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
vec3 Y = normalize(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 NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
float avgRoughness = mx_average_roughness(roughness);
FresnelData fd = mx_init_fresnel_schlick(color0, color90, exponent);
vec3 F = mx_compute_fresnel(VdotH, fd);
float D = mx_ggx_NDF(X, Y, H, NdotH, roughness.x, roughness.y);
float G = mx_ggx_smith_G(NdotL, NdotV, avgRoughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, color0, color90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
// Note: NdotL is cancelled out
result = D * F * G * comp * occlusion * weight / (4 * NdotV) // Top layer reflection
+ base * (1.0 - avgDirAlbedo * weight); // Base layer reflection attenuated by top layer
}
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, BSDF base, thinfilm tf, out BSDF result)
{
//
// TODO: We need handling of transmission for generalized schlick
//
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd = mx_init_fresnel_schlick(color0, color90, exponent);
vec3 F = mx_compute_fresnel(NdotV, fd);
float avgRoughness = mx_average_roughness(roughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, color0, color90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
result = base * (1.0 - avgDirAlbedo * weight); // Transmission attenuated by top layer
}
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, BSDF base, thinfilm tf, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd = mx_init_fresnel_schlick(color0, color90, exponent);
vec3 F = mx_compute_fresnel(NdotV, fd);
float avgRoughness = mx_average_roughness(roughness);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
vec3 dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, color0, color90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
vec3 Li = mx_environment_radiance(N, V, X, roughness, distribution, fd);
result = Li * comp * weight // Top layer reflection
+ base * (1.0 - avgDirAlbedo * weight); // Base layer reflection attenuated by top layer
}

View File

@ -0,0 +1,14 @@
void mx_mix_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, BSDF fg, BSDF bg, float w, out BSDF result)
{
result = mix(bg, fg, clamp(w, 0.0, 1.0));
}
void mx_mix_bsdf_transmission(vec3 V, BSDF fg, BSDF bg, float w, out BSDF result)
{
result = mix(bg, fg, clamp(w, 0.0, 1.0));
}
void mx_mix_bsdf_indirect(vec3 V, vec3 fg, vec3 bg, float w, out vec3 result)
{
result = mix(bg, fg, clamp(w, 0.0, 1.0));
}

View File

@ -0,0 +1,4 @@
void mx_mix_edf(vec3 N, vec3 L, EDF fg, EDF bg, float w, out EDF result)
{
result = mix(bg, fg, clamp(w, 0.0, 1.0));
}

View File

@ -0,0 +1,14 @@
void mx_multiply_bsdf_color_reflection(vec3 L, vec3 V, vec3 P, float occlusion, BSDF in1, vec3 in2, out BSDF result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}
void mx_multiply_bsdf_color_transmission(vec3 V, BSDF in1, vec3 in2, out BSDF result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}
void mx_multiply_bsdf_color_indirect(vec3 V, vec3 in1, vec3 in2, out vec3 result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}

View File

@ -0,0 +1,14 @@
void mx_multiply_bsdf_float_reflection(vec3 L, vec3 V, vec3 P, float occlusion, BSDF in1, float in2, out BSDF result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}
void mx_multiply_bsdf_float_transmission(vec3 V, BSDF in1, float in2, out BSDF result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}
void mx_multiply_bsdf_float_indirect(vec3 V, vec3 in1, float in2, out vec3 result)
{
result = in1 * clamp(in2, 0.0, 1.0);
}

View File

@ -0,0 +1,4 @@
void mx_multiply_edf_color(vec3 N, vec3 L, EDF in1, vec3 in2, out EDF result)
{
result = in1 * in2;
}

View File

@ -0,0 +1,4 @@
void mx_multiply_edf_float(vec3 N, vec3 L, EDF in1, float in2, out EDF result)
{
result = in1 * in2;
}

View File

@ -0,0 +1,34 @@
#include "pbrlib/genglsl/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, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
normal = mx_forward_facing_normal(normal, V);
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
result = color * occlusion * weight * NdotL * M_PI_INV;
if (roughness > 0.0)
{
result *= 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, out vec3 result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
normal = mx_forward_facing_normal(normal, V);
vec3 Li = mx_environment_irradiance(normal);
result = Li * color * weight;
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -0,0 +1,50 @@
#include "pbrlib/genglsl/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, BSDF base, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = base;
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);
float D = mx_imageworks_sheen_NDF(NdotH, roughness);
// Geometry term is skipped and we use a smoother denominator, as in:
// https://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
vec3 fr = D * color / (4.0 * (NdotL + NdotV - NdotL*NdotV));
float dirAlbedo = mx_imageworks_sheen_directional_albedo(NdotV, roughness);
// We need to include NdotL from the light integral here
// as in this case it's not cancelled out by the BRDF denominator.
result = fr * NdotL * occlusion * weight // Top layer reflection
+ base * (1.0 - dirAlbedo * weight); // Base layer reflection attenuated by top layer
}
void mx_sheen_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 N, BSDF base, out vec3 result)
{
if (weight <= 0.0)
{
result = base;
return;
}
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
float dirAlbedo = mx_imageworks_sheen_directional_albedo(NdotV, roughness);
vec3 Li = mx_environment_irradiance(N);
result = Li * color * dirAlbedo * weight // Top layer reflection
+ base * (1.0 - dirAlbedo * weight); // Base layer reflection attenuated by top layer
}

View File

@ -0,0 +1,32 @@
#include "pbrlib/genglsl/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, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
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);
result = sss * visibleOcclusion * weight;
}
void mx_subsurface_bsdf_indirect(vec3 V, float weight, vec3 color, vec3 radius, float anisotropy, vec3 normal, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
normal = mx_forward_facing_normal(normal, V);
// For now, we render indirect subsurface as simple indirect diffuse.
vec3 Li = mx_environment_irradiance(normal);
result = Li * color * weight;
}

View File

@ -0,0 +1,27 @@
// 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, out BSDF result)
{
// Invert normal since we're transmitting light from the other side
float NdotL = dot(L, -normal);
if (NdotL <= 0.0 || weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
result = color * weight * NdotL * M_PI_INV;
}
void mx_translucent_bsdf_indirect(vec3 V, float weight, vec3 color, vec3 normal, out BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = BSDF(0.0);
return;
}
// Invert normal since we're transmitting light from the other side
vec3 Li = mx_environment_irradiance(-normal);
result = Li * color * weight;
}

View File

@ -0,0 +1,4 @@
void mx_uniform_edf(vec3 N, vec3 L, vec3 color, out EDF result)
{
result = color;
}

View File

@ -0,0 +1,66 @@
<?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="pbrlib/genglsl/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="pbrlib/genglsl/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="pbrlib/genglsl/mx_translucent_bsdf.glsl" function="mx_translucent_bsdf" target="genglsl" />
<!-- <dielectric_bsdf> -->
<implementation name="IM_dielectric_bsdf_genglsl" nodedef="ND_dielectric_bsdf" file="pbrlib/genglsl/mx_dielectric_bsdf.glsl" function="mx_dielectric_bsdf" target="genglsl" />
<!-- <conductor_bsdf> -->
<implementation name="IM_conductor_bsdf_genglsl" nodedef="ND_conductor_bsdf" file="pbrlib/genglsl/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="pbrlib/genglsl/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="pbrlib/genglsl/mx_subsurface_bsdf.glsl" function="mx_subsurface_bsdf" target="genglsl" />
<!-- <sheen_bsdf> -->
<implementation name="IM_sheen_bsdf_genglsl" nodedef="ND_sheen_bsdf" file="pbrlib/genglsl/mx_sheen_bsdf.glsl" function="mx_sheen_bsdf" 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" />
<!-- <mix> -->
<implementation name="IM_mix_bsdf_genglsl" nodedef="ND_mix_bsdf" file="pbrlib/genglsl/mx_mix_bsdf.glsl" function="mx_mix_bsdf" target="genglsl" />
<implementation name="IM_mix_edf_genglsl" nodedef="ND_mix_edf" file="pbrlib/genglsl/mx_mix_edf.glsl" function="mx_mix_edf" target="genglsl" />
<!-- <add> -->
<implementation name="IM_add_bsdf_genglsl" nodedef="ND_add_bsdf" file="pbrlib/genglsl/mx_add_bsdf.glsl" function="mx_add_bsdf" target="genglsl" />
<implementation name="IM_add_edf_genglsl" nodedef="ND_add_edf" file="pbrlib/genglsl/mx_add_edf.glsl" function="mx_add_edf" target="genglsl" />
<!-- <multiply> -->
<implementation name="IM_multiply_bsdfC_genglsl" nodedef="ND_multiply_bsdfC" file="pbrlib/genglsl/mx_multiply_bsdf_color.glsl" function="mx_multiply_bsdf_color" target="genglsl" />
<implementation name="IM_multiply_bsdfF_genglsl" nodedef="ND_multiply_bsdfF" file="pbrlib/genglsl/mx_multiply_bsdf_float.glsl" function="mx_multiply_bsdf_float" target="genglsl" />
<implementation name="IM_multiply_edfC_genglsl" nodedef="ND_multiply_edfC" file="pbrlib/genglsl/mx_multiply_edf_color.glsl" function="mx_multiply_edf_color" target="genglsl" />
<implementation name="IM_multiply_edfF_genglsl" nodedef="ND_multiply_edfF" file="pbrlib/genglsl/mx_multiply_edf_float.glsl" function="mx_multiply_edf_float" target="genglsl" />
<!-- <uniform_edf> -->
<implementation name="IM_uniform_edf_genglsl" nodedef="ND_uniform_edf" file="pbrlib/genglsl/mx_uniform_edf.glsl" function="mx_uniform_edf" target="genglsl" />
<!-- <surface> -->
<implementation name="IM_surface_genglsl" nodedef="ND_surface" 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="pbrlib/genglsl/mx_roughness_anisotropy.glsl" function="mx_roughness_anisotropy" target="genglsl" />
<!-- <roughness_dual> -->
<implementation name="IM_roughness_dual_genglsl" nodedef="ND_roughness_dual" file="pbrlib/genglsl/mx_roughness_dual.glsl" function="mx_roughness_dual" target="genglsl" />
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genglsl" nodedef="ND_artistic_ior" file="pbrlib/genglsl/mx_artistic_ior.glsl" function="mx_artistic_ior" target="genglsl" />
</materialx>

View File

@ -0,0 +1,92 @@
<?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="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::mx_dielectric_bsdf(mxp_weight:{{weight}}, mxp_tint:{{tint}}, mxp_ior:{{ior}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}})" target="genmdl" />
<!-- <conductor_bsdf> -->
<implementation name="IM_conductor_bsdf_genmdl" nodedef="ND_conductor_bsdf" sourcecode="mx::pbrlib::mx_conductor_bsdf(mxp_weight:{{weight}}, mxp_ior:{{ior}}, mxp_extinction:{{extinction}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}})" target="genmdl" />
<!-- <generalized_schlick_bsdf> -->
<implementation name="IM_generalized_schlick_bsdf_genmdl" nodedef="ND_generalized_schlick_bsdf" sourcecode="mx::pbrlib::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_scatter_mode:{{scatter_mode}}, mxp_base:{{base}})" target="genmdl" />
<!-- <subsurface_bsdf> -->
<implementation name="IM_subsurface_bsdf_genmdl" nodedef="ND_subsurface_bsdf" sourcecode="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::mx_uniform_edf(mxp_color:{{color}})" target="genmdl" />
<!-- <conical_edf> -->
<implementation name="IM_conical_edf_genmdl" nodedef="ND_conical_edf" sourcecode="mx::pbrlib::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="mx::pbrlib::mx_measured_edf(mxp_color:{{color}}, mxp_normal:{{normal}}, mxp_file:{{file}}" target="genmdl" />
<!-- <absorption_vdf> -->
<implementation name="IM_absorption_vdf_genmdl" nodedef="ND_absorption_vdf" sourcecode="mx::pbrlib::mx_absorption_vdf(mxp_absorption:{{absorption}})" target="genmdl" />
<!-- <anisotropic_vdf> -->
<implementation name="IM_anisotropic_vdf_genmdl" nodedef="ND_anisotropic_vdf" sourcecode="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::mx_volume(mxp_vdf:{{vdf}}, mxp_edf:{{edf}})" target="genmdl" />
<!-- <light> -->
<implementation name="IM_light_genmdl" nodedef="ND_light" sourcecode="mx::pbrlib::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="mx::pbrlib::mx_displacement_float(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />
<implementation name="IM_displacement_vector3_genmdl" nodedef="ND_displacement_vector3" sourcecode="mx::pbrlib::mx_displacement_vector3(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />
<!-- <layer> -->
<implementation name="IM_layer_bsdf_genmdl" nodedef="ND_layer_bsdf" target="genmdl" />
<!-- <mix> -->
<implementation name="IM_mix_bsdf_genmdl" nodedef="ND_mix_bsdf" sourcecode="mx::pbrlib::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="mx::pbrlib::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="mx::pbrlib::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="{{in1}}" target="genmdl" /> <!-- TODO: Implement properly -->
<implementation name="IM_add_edf_genmdl" nodedef="ND_add_edf" sourcecode="{{in2}}" target="genmdl" /> <!-- TODO: Implement properly -->
<!-- <multiply> -->
<implementation name="IM_multiply_bsdfC_genmdl" nodedef="ND_multiply_bsdfC" sourcecode="mx::pbrlib::mx_multiply_bsdf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
<implementation name="IM_multiply_bsdfF_genmdl" nodedef="ND_multiply_bsdfF" sourcecode="mx::pbrlib::mx_multiply_bsdf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
<implementation name="IM_multiply_edfC_genmdl" nodedef="ND_multiply_edfC" sourcecode="{{in1}}" target="genmdl" /> <!-- TODO: Implement properly -->
<implementation name="IM_multiply_edfF_genmdl" nodedef="ND_multiply_edfF" sourcecode="{{in1}}" target="genmdl" /> <!-- TODO: Implement properly -->
<!-- <roughness_anisotropy> -->
<implementation name="IM_roughness_anisotropy_genmdl" nodedef="ND_roughness_anisotropy" sourcecode="mx::pbrlib::mx_roughness_anisotropy(mxp_roughness:{{roughness}}, mxp_anisotropy:{{anisotropy}})" target="genmdl" />
<!-- <roughness_dual> -->
<implementation name="IM_roughness_dual_genmdl" nodedef="ND_roughness_dual" sourcecode="mx::pbrlib::mx_roughness_dual(mxp_roughness:{{roughness}})" target="genmdl" />
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genmdl" nodedef="ND_artistic_ior" sourcecode="mx::pbrlib::mx_artistic_ior(mxp_reflectivity:{{reflectivity}}, mxp_edge_color:{{edge_color}})" target="genmdl" />
<!-- <blackbody> -->
<implementation name="IM_blackbody_genmdl" nodedef="ND_blackbody" sourcecode="mx::pbrlib::mx_blackbody(mxp_temperature:{{temperature}})" target="genmdl" />
</materialx>

View File

@ -0,0 +1,125 @@
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;
}
float mx_fract(float x)
{
return x - floor(x);
}
float mx_average_roughness(vector2 roughness)
{
return sqrt(roughness.x * roughness.y);
}
// https://www.graphics.rwth-aachen.de/publication/2/jgt.pdf
float mx_golden_ratio_sequence(int i)
{
return mx_fract((float(i) + 1.0) * M_GOLDEN_RATIO);
}
// https://people.irisa.fr/Ricardo.Marques/articles/2013/SF_CGF.pdf
vector2 mx_spherical_fibonacci(int i, int numSamples)
{
return vector2((float(i) + 0.5) / float(numSamples), mx_golden_ratio_sequence(i));
}
// 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));
}
// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
float mx_fresnel_dielectric(float cosTheta, float ior)
{
if (cosTheta < 0.0 || ior == 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);
}
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));
}

View File

@ -0,0 +1,116 @@
#include "pbrlib/genosl/lib/mx_microfacet.osl"
// https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
// Appendix B.2 Equation 15
vector mx_ggx_importance_sample_NDF(vector2 Xi, vector X, vector Y, vector N, float alphaX, float alphaY)
{
float phi = 2.0 * M_PI * Xi.x;
float tanTheta = sqrt(Xi.y / (1.0 - Xi.y));
vector H = X * (tanTheta * alphaX * cos(phi)) +
Y * (tanTheta * alphaY * sin(phi)) +
N;
return normalize(H);
}
// http://jcgt.org/published/0003/02/03/paper.pdf
// Equations 72 and 99
float mx_ggx_smith_G(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);
}
// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
color mx_ggx_directional_albedo_curve_fit(float NdotV, float roughness, color F0, color F90)
{
vector4 c0 = vector4(-1, -0.0275, -0.572, 0.022);
vector4 c1 = vector4( 1, 0.0425, 1.04, -0.04 );
vector4 r = roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x + r.y;
vector2 AB = vector2(-1.04, 1.04) * a004 + vector2(r.z, r.w);
return F0 * AB.x + F90 * AB.y;
}
color mx_ggx_directional_albedo_table_lookup(float NdotV, float roughness, color F0, color F90)
{
vector2 st = vector2(NdotV, roughness);
vector AB = texture(GGX_DIRECTIONAL_ALBEDO_TABLE, st.x, st.y);
return F0 * AB[0] + F90 * AB[1];
}
// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
color mx_ggx_directional_albedo_importance_sample(float _NdotV, float roughness, color F0, color F90)
{
float NdotV = clamp(_NdotV, M_FLOAT_EPS, 1.0);
vector V = vector(sqrt(1.0 - mx_square(NdotV)), 0.0, NdotV);
vector2 AB = vector2(0.0, 0.0);
int SAMPLE_COUNT = 64;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
vector2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);
// Compute the half vector and incoming light direction.
vector H = mx_ggx_importance_sample_NDF(Xi, vector(1, 0, 0), vector(0, 1, 0), vector(0, 0, 1), roughness, roughness);
vector L = -reflect(V, H);
// Compute dot products for this sample.
float NdotL = clamp(L[2], M_FLOAT_EPS, 1.0);
float NdotH = clamp(H[2], 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 geometric visibility term.
float Gvis = mx_ggx_smith_G(NdotL, NdotV, roughness) * VdotH / (NdotH * NdotV);
// Add the contribution of this sample.
AB += vector2(Gvis * (1 - Fc), Gvis * Fc);
}
// Normalize integrated terms.
AB /= SAMPLE_COUNT;
// Return the final directional albedo.
return F0 * AB.x + F90 * AB.y;
}
color mx_ggx_directional_albedo(float NdotV, float roughness, color F0, color F90)
{
#if GGX_DIRECTIONAL_ALBEDO_METHOD == 0
return mx_ggx_directional_albedo_curve_fit(NdotV, roughness, F0, F90);
#elif GGX_DIRECTIONAL_ALBEDO_METHOD == 1
return mx_ggx_directional_albedo_table_lookup(NdotV, roughness, F0, F90);
#else
return mx_ggx_directional_albedo_importance_sample(NdotV, roughness, F0, F90);
#endif
}
float mx_ggx_directional_albedo(float NdotV, float roughness, float F0, float F90)
{
color result = mx_ggx_directional_albedo(NdotV, roughness, color(F0), color(F90));
return result[0];
}
float mx_ggx_directional_albedo(float NdotV, float roughness, float ior)
{
color result = mx_ggx_directional_albedo(NdotV, roughness, 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 roughness, color Fss)
{
float Ess = mx_ggx_directional_albedo(NdotV, roughness, 1.0, 1.0);
return 1.0 + Fss * (1.0 - Ess) / Ess;
}
float mx_ggx_energy_compensation(float NdotV, float roughness, float Fss)
{
color result = mx_ggx_energy_compensation(NdotV, roughness, color(Fss));
return result[0];
}

View File

@ -0,0 +1,31 @@
// "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
// http://jcgt.org/published/0003/04/03/paper.pdf
void mx_complex_to_artistic_ior(vector ior, vector extinction, output color reflectivity, output color edge_color)
{
vector nm1 = ior - 1.0;
vector np1 = ior + 1.0;
vector k2 = extinction * extinction;
vector r = (nm1*nm1 + k2) / (np1*np1 + k2);
reflectivity = r;
vector r_sqrt = sqrt(r);
vector n_min = (1.0 - r) / (1.0 + r);
vector n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt);
edge_color = (n_max - ior) / (n_max - n_min);
}
void mx_artistic_to_complex_ior(color reflectivity, color edge_color, output vector ior, output vector extinction)
{
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);
}

View File

@ -0,0 +1 @@
mx_add({{in1}}, {{in2}})

View File

@ -0,0 +1,6 @@
#include "pbrlib/genosl/lib/mx_refraction_index.osl"
void mx_artistic_ior(color reflectivity, color edge_color, output vector ior, output vector extinction)
{
mx_artistic_to_complex_ior(reflectivity, edge_color, ior, extinction);
}

View File

@ -0,0 +1,5 @@
void mx_burley_diffuse_bsdf(float weight, color reflectance, float roughness, normal N, output BSDF result)
{
// TODO: Implement properly.
result = reflectance * weight * oren_nayar(N, roughness);
}

View File

@ -0,0 +1,29 @@
#include "pbrlib/genosl/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, thinfilm tf, output BSDF result)
{
if (weight < M_FLOAT_EPS)
{
result = 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.
float avgRoughness = mx_average_roughness(roughness);
color comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
// Set ior to 0.0 to disable the internal dielectric fresnel
result = F * comp * weight * microfacet(distribution, N, U, roughness.x, roughness.y, 0.0, false);
}

View File

@ -0,0 +1,35 @@
#include "pbrlib/genosl/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, BSDF base, thinfilm tf, output BSDF result)
{
if (scatter_mode == "T")
{
result = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1);
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.
float avgRoughness = mx_average_roughness(roughness);
float comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
if (scatter_mode == "R")
{
// Calculate directional albedo since we need
// to attenuate the base layer according to this.
float dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, ior) * comp;
result = tint * weight * comp * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 0)
+ base * (1.0 - dirAlbedo * weight);
}
else
{
result = tint * weight * comp * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 2);
}
}

View File

@ -0,0 +1,4 @@
void mx_displacement_float(float displacement, float scale, output displacementshader result)
{
result = vector(displacement * scale);
}

View File

@ -0,0 +1,4 @@
void mx_displacement_vector3(vector displacement, float scale, output displacementshader result)
{
result = displacement * scale;
}

View File

@ -0,0 +1,32 @@
#include "pbrlib/genosl/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, BSDF base, thinfilm tf, output BSDF result)
{
//
// TODO: We need handling of transmission for generalized schlick
//
if (weight < M_FLOAT_EPS || scatter_mode == "T")
{
result = base;
return;
}
float NdotV = fabs(dot(N,-I));
color F = mx_fresnel_schlick(NdotV, color0, color90, exponent);
float avgRoughness = mx_average_roughness(roughness);
// 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.
color comp = mx_ggx_energy_compensation(NdotV, avgRoughness, F);
// Calculate directional albedo since we need
// to attenuate the base layer according to this.
color dirAlbedo = mx_ggx_directional_albedo(NdotV, avgRoughness, color0, color90) * comp;
float avgDirAlbedo = dot(dirAlbedo, color(1.0 / 3.0));
// Set ior to 0.0 to disable the internal dielectric fresnel
result = F * comp * weight * microfacet(distribution, N, U, roughness.x, roughness.y, 0.0, 0)
+ base * (1.0 - avgDirAlbedo * weight);
}

View File

@ -0,0 +1 @@
mix({{bg}}, {{fg}}, {{mix}})

View File

@ -0,0 +1 @@
{{in1}} * clamp({{in2}}, 0.0, 1.0)

View File

@ -0,0 +1 @@
{{in1}} * {{in2}}

View File

@ -0,0 +1 @@
{{color}} * {{weight}} * oren_nayar({{normal}}, {{roughness}})

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,61 @@
float mx_imageworks_sheen_directional_albedo(float cosTheta, float roughness)
{
// LUT for sheen directional albedo.
// A 2D table parameterized with 'cosTheta' (cosine of angle to normal) on x-axis and 'roughness' on y-axis.
int SHEEN_ALBEDO_TABLE_SIZE = 16;
float _sheenAlbedo[256] = {
1.6177, 0.978927, 0.618938, 0.391714, 0.245177, 0.150234, 0.0893475, 0.0511377, 0.0280191, 0.0144204, 0.00687674, 0.00295935, 0.00111049, 0.000336768, 7.07119e-05, 6.22646e-06,
1.1084, 0.813928, 0.621389, 0.479304, 0.370299, 0.284835, 0.21724, 0.163558, 0.121254, 0.0878921, 0.0619052, 0.0419894, 0.0270556, 0.0161443, 0.00848212, 0.00342323,
0.930468, 0.725652, 0.586532, 0.479542, 0.393596, 0.322736, 0.26353, 0.213565, 0.171456, 0.135718, 0.105481, 0.0800472, 0.0588117, 0.0412172, 0.0268329, 0.0152799,
0.833791, 0.671201, 0.558957, 0.471006, 0.398823, 0.337883, 0.285615, 0.240206, 0.200696, 0.16597, 0.135422, 0.10859, 0.0850611, 0.0644477, 0.0464763, 0.0308878,
0.771692, 0.633819, 0.537877, 0.461939, 0.398865, 0.344892, 0.297895, 0.256371, 0.219562, 0.186548, 0.156842, 0.130095, 0.10598, 0.0841919, 0.0645311, 0.04679,
0.727979, 0.606373, 0.52141, 0.453769, 0.397174, 0.348337, 0.305403, 0.267056, 0.232655, 0.201398, 0.17286, 0.146756, 0.122808, 0.100751, 0.0804254, 0.0616485,
0.695353, 0.585281, 0.508227, 0.44667, 0.394925, 0.350027, 0.310302, 0.274561, 0.242236, 0.212604, 0.185281, 0.16002, 0.13657, 0.114693, 0.0942543, 0.0750799,
0.669981, 0.568519, 0.497442, 0.440542, 0.392567, 0.350786, 0.313656, 0.280075, 0.249533, 0.221359, 0.195196, 0.170824, 0.148012, 0.126537, 0.106279, 0.0870713,
0.649644, 0.554855, 0.488453, 0.435237, 0.390279, 0.351028, 0.316036, 0.284274, 0.255266, 0.228387, 0.203297, 0.179796, 0.157665, 0.136695, 0.116774, 0.0977403,
0.632951, 0.543489, 0.480849, 0.430619, 0.388132, 0.350974, 0.317777, 0.287562, 0.259885, 0.234153, 0.210041, 0.187365, 0.165914, 0.145488, 0.125983, 0.10724,
0.61899, 0.533877, 0.47433, 0.426573, 0.386145, 0.35075, 0.319078, 0.290197, 0.263681, 0.238971, 0.215746, 0.193838, 0.173043, 0.153167, 0.134113, 0.115722,
0.607131, 0.52564, 0.468678, 0.423001, 0.38432, 0.35043, 0.320072, 0.292349, 0.266856, 0.243055, 0.220636, 0.199438, 0.179264, 0.159926, 0.141332, 0.123323,
0.596927, 0.518497, 0.463731, 0.419829, 0.382647, 0.350056, 0.320842, 0.294137, 0.269549, 0.246564, 0.224875, 0.204331, 0.18474, 0.165919, 0.147778, 0.130162,
0.588052, 0.512241, 0.459365, 0.416996, 0.381114, 0.349657, 0.321448, 0.295641, 0.271862, 0.24961, 0.228584, 0.208643, 0.189596, 0.171266, 0.153566, 0.136341,
0.580257, 0.506717, 0.455481, 0.41445, 0.379708, 0.34925, 0.321929, 0.296923, 0.273869, 0.252279, 0.231859, 0.212472, 0.193933, 0.176066, 0.158788, 0.141945,
0.573355, 0.5018, 0.452005, 0.412151, 0.378416, 0.348844, 0.322316, 0.298028, 0.275627, 0.254638, 0.234772, 0.215896, 0.197828, 0.180398, 0.163522, 0.147049
};
float x = cosTheta * (SHEEN_ALBEDO_TABLE_SIZE - 1);
float y = roughness * (SHEEN_ALBEDO_TABLE_SIZE - 1);
int ix = int(x);
int iy = int(y);
int ix2 = clamp(ix + 1, 0, SHEEN_ALBEDO_TABLE_SIZE - 1);
int iy2 = clamp(iy + 1, 0, SHEEN_ALBEDO_TABLE_SIZE - 1);
float fx = x - ix;
float fy = y - iy;
float v1 = mix(_sheenAlbedo[iy * SHEEN_ALBEDO_TABLE_SIZE + ix], _sheenAlbedo[iy * SHEEN_ALBEDO_TABLE_SIZE + ix2], fx);
float v2 = mix(_sheenAlbedo[iy2 * SHEEN_ALBEDO_TABLE_SIZE + ix], _sheenAlbedo[iy2 * SHEEN_ALBEDO_TABLE_SIZE + ix2], fx);
float albedo = mix(v1, v2, fy);
return clamp(albedo, 0.0, 1.0);
}
// 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, BSDF base, output BSDF result)
{
if (weight > M_FLOAT_EPS)
{
// 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_directional_albedo(NdotV, alpha);
result = albedo * Ks * diffuse(N) + (1.0 - albedo) * base;
}
else
{
result = base;
}
}

View File

@ -0,0 +1,5 @@
void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, vector _normal, output BSDF result)
{
// TODO: Subsurface closure is not supported by vanilla OSL.
result = _color * weight * translucent(_normal);
}

View File

@ -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 + edf) * opacity_weight + transparent() * (1.0 - opacity_weight);
}

View File

@ -0,0 +1 @@
{{color}} * {{weight}} * translucent({{normal}})

View File

@ -0,0 +1 @@
{{color}} * emission()

View File

@ -0,0 +1,67 @@
<?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="pbrlib/genosl/mx_oren_nayar_diffuse_bsdf.inline" target="genosl" />
<!-- <burley_diffuse_bsdf> -->
<implementation name="IM_burley_diffuse_bsdf_genosl" nodedef="ND_burley_diffuse_bsdf" file="pbrlib/genosl/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="pbrlib/genosl/mx_translucent_bsdf.inline" target="genosl" />
<!-- <dielectric_bsdf> -->
<implementation name="IM_dielectric_bsdf_genosl" nodedef="ND_dielectric_bsdf" file="pbrlib/genosl/mx_dielectric_bsdf.osl" function="mx_dielectric_bsdf" target="genosl" />
<!-- <conductor_bsdf> -->
<implementation name="IM_conductor_bsdf_genosl" nodedef="ND_conductor_bsdf" file="pbrlib/genosl/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="pbrlib/genosl/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="pbrlib/genosl/mx_subsurface_bsdf.osl" function="mx_subsurface_bsdf" target="genosl" />
<!-- <sheen_bsdf> -->
<implementation name="IM_sheen_bsdf_genosl" nodedef="ND_sheen_bsdf" file="pbrlib/genosl/mx_sheen_bsdf.osl" function="mx_sheen_bsdf" 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" file="pbrlib/genosl/mx_uniform_edf.inline" target="genosl" />
<!-- <layer> -->
<implementation name="IM_layer_bsdf_genosl" nodedef="ND_layer_bsdf" target="genosl" />
<!-- <mix> -->
<implementation name="IM_mix_bsdf_genosl" nodedef="ND_mix_bsdf" file="pbrlib/genosl/mx_mix.inline" target="genosl" />
<implementation name="IM_mix_edf_genosl" nodedef="ND_mix_edf" file="pbrlib/genosl/mx_mix.inline" target="genosl" />
<!-- <add> -->
<implementation name="IM_add_bsdf_genosl" nodedef="ND_add_bsdf" file="pbrlib/genosl/mx_add.inline" target="genosl" />
<implementation name="IM_add_edf_genosl" nodedef="ND_add_edf" file="pbrlib/genosl/mx_add.inline" target="genosl" />
<!-- <multiply> -->
<implementation name="IM_multiply_bsdfC_genosl" nodedef="ND_multiply_bsdfC" file="pbrlib/genosl/mx_multiply_bsdf.inline" target="genosl" />
<implementation name="IM_multiply_bsdfF_genosl" nodedef="ND_multiply_bsdfF" file="pbrlib/genosl/mx_multiply_bsdf.inline" target="genosl" />
<implementation name="IM_multiply_edfC_genosl" nodedef="ND_multiply_edfC" file="pbrlib/genosl/mx_multiply_edf.inline" target="genosl" />
<implementation name="IM_multiply_edfF_genosl" nodedef="ND_multiply_edfF" file="pbrlib/genosl/mx_multiply_edf.inline" target="genosl" />
<!-- <surface> -->
<implementation name="IM_surface_genosl" nodedef="ND_surface" file="pbrlib/genosl/mx_surface.osl" function="mx_surface" target="genosl" />
<!-- <displacement> -->
<implementation name="IM_displacement_float_genosl" nodedef="ND_displacement_float" file="pbrlib/genosl/mx_displacement_float.osl" function="mx_displacement_float" target="genosl" />
<implementation name="IM_displacement_vector3_genosl" nodedef="ND_displacement_vector3" file="pbrlib/genosl/mx_displacement_vector3.osl" function="mx_displacement_vector3" target="genosl" />
<!-- <roughness_anisotropy> -->
<implementation name="IM_roughness_anisotropy_genosl" nodedef="ND_roughness_anisotropy" file="pbrlib/genosl/mx_roughness_anisotropy.osl" function="mx_roughness_anisotropy" target="genosl" />
<!-- <roughness_dual> -->
<implementation name="IM_roughness_dual_genosl" nodedef="ND_roughness_dual" file="pbrlib/genosl/mx_roughness_dual.osl" function="mx_roughness_dual" target="genosl" />
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="pbrlib/genosl/mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />
</materialx>

View File

@ -0,0 +1,397 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
TM & (c) 2018 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
All rights reserved. See LICENSE.txt for license.
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.271, 0.677, 1.316" colorspace="none" />
<input name="extinction" type="color3" value="3.609, 2.625, 2.292" 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>
<!-- ======================================================================== -->
<!-- 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>
<!--
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="1.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="1.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="1.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>
<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="float" />
</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>

View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
TM & (c) 2018 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
All rights reserved. See LICENSE.txt for license.
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>

View File

@ -0,0 +1,91 @@
/*
Color transform functions.
These funcions are modified versions of the color operators found in Open Shading Language:
github.com/imageworks/OpenShadingLanguage/blob/master/src/liboslexec/opcolor.cpp
It contains the subset of color operators needed to implement the MaterialX
standard library. The modifications are for conversions from C++ to GLSL.
Original copyright notice:
------------------------------------------------------------------------
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------
*/
vec3 mx_hsvtorgb(vec3 hsv)
{
// Reference for this technique: Foley & van Dam
float h = hsv.x; float s = hsv.y; float v = hsv.z;
if (s < 0.0001f) {
return vec3 (v, v, v);
} else {
h = 6.0f * (h - floor(h)); // expand to [0..6)
int hi = int(trunc(h));
float f = h - float(hi);
float p = v * (1.0f-s);
float q = v * (1.0f-s*f);
float t = v * (1.0f-s*(1.0f-f));
if (hi == 0)
return vec3 (v, t, p);
else if (hi == 1)
return vec3 (q, v, p);
else if (hi == 2)
return vec3 (p, v, t);
else if (hi == 3)
return vec3 (p, q, v);
else if (hi == 4)
return vec3 (t, p, v);
return vec3 (v, p, q);
}
}
vec3 mx_rgbtohsv(vec3 c)
{
// See Foley & van Dam
float r = c.x; float g = c.y; float b = c.z;
float mincomp = min (r, min(g, b));
float maxcomp = max (r, max(g, b));
float delta = maxcomp - mincomp; // chroma
float h, s, v;
v = maxcomp;
if (maxcomp > 0.0f)
s = delta / maxcomp;
else s = 0.0f;
if (s <= 0.0f)
h = 0.0f;
else {
if (r >= maxcomp) h = (g-b) / delta;
else if (g >= maxcomp) h = 2.0f + (b-r) / delta;
else h = 4.0f + (r-g) / delta;
h *= (1.0f/6.0f);
if (h < 0.0f)
h += 1.0f;
}
return vec3(h, s, v);
}

View File

@ -0,0 +1,321 @@
/*
Noise Library.
This library is a modified version of the noise library found in
Open Shading Language:
github.com/imageworks/OpenShadingLanguage/blob/master/src/include/OSL/oslnoise.h
It contains the subset of noise types needed to implement the MaterialX
standard library. The modifications are mainly conversions from C++ to GLSL.
Produced results should be identical to the OSL noise functions.
Original copyright notice:
------------------------------------------------------------------------
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------
*/
float mx_select(bool b, float t, float f)
{
return b ? t : f;
}
float mx_negate_if(float val, bool b)
{
return b ? -val : val;
}
int mx_floor(float x)
{
// return the greatest integer <= x
return x < 0.0 ? int(x) - 1 : int(x);
}
// return mx_floor as well as the fractional remainder
float mx_floorfrac(float x, out int i)
{
i = mx_floor(x);
return x - i;
}
float mx_bilerp(float v0, float v1, float v2, float v3, float s, float t)
{
float s1 = 1.0 - s;
return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s);
}
vec3 mx_bilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, float s, float t)
{
float s1 = 1.0 - s;
return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s);
}
float mx_trilerp(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float s, float t, float r)
{
float s1 = 1.0 - s;
float t1 = 1.0 - t;
float r1 = 1.0 - r;
return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) +
r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s)));
}
vec3 mx_trilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, vec3 v4, vec3 v5, vec3 v6, vec3 v7, float s, float t, float r)
{
float s1 = 1.0 - s;
float t1 = 1.0 - t;
float r1 = 1.0 - r;
return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) +
r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s)));
}
// 2 and 3 dimensional gradient functions - perform a dot product against a
// randomly chosen vector. Note that the gradient vector is not normalized, but
// this only affects the overal "scale" of the result, so we simply account for
// the scale by multiplying in the corresponding "perlin" function.
float mx_gradient_float(uint hash, float x, float y)
{
// 8 possible directions (+-1,+-2) and (+-2,+-1)
uint h = hash & 7u;
float u = mx_select(h<4u, x, y);
float v = 2.0 * mx_select(h<4u, y, x);
// compute the dot product with (x,y).
return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u));
}
float mx_gradient_float(uint hash, float x, float y, float z)
{
// use vectors pointing to the edges of the cube
uint h = hash & 15u;
float u = mx_select(h<8u, x, y);
float v = mx_select(h<4u, y, mx_select((h==12u)||(h==14u), x, z));
return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u));
}
vec3 mx_gradient_vec3(uvec3 hash, float x, float y)
{
return vec3(mx_gradient_float(hash.x, x, y), mx_gradient_float(hash.y, x, y), mx_gradient_float(hash.z, x, y));
}
vec3 mx_gradient_vec3(uvec3 hash, float x, float y, float z)
{
return vec3(mx_gradient_float(hash.x, x, y, z), mx_gradient_float(hash.y, x, y, z), mx_gradient_float(hash.z, x, y, z));
}
// Scaling factors to normalize the result of gradients above.
// These factors were experimentally calculated to be:
// 2D: 0.6616
// 3D: 0.9820
float mx_gradient_scale2d(float v) { return 0.6616 * v; }
float mx_gradient_scale3d(float v) { return 0.9820 * v; }
vec3 mx_gradient_scale2d(vec3 v) { return 0.6616 * v; }
vec3 mx_gradient_scale3d(vec3 v) { return 0.9820 * v; }
/// Bitwise circular rotation left by k bits (for 32 bit unsigned integers)
uint mx_rotl32(uint x, int k)
{
return (x<<k) | (x>>(32-k));
}
// Mix up and combine the bits of a, b, and c (doesn't change them, but
// returns a hash of those three original values).
uint mx_bjfinal(uint a, uint b, uint c)
{
c ^= b; c -= mx_rotl32(b,14);
a ^= c; a -= mx_rotl32(c,11);
b ^= a; b -= mx_rotl32(a,25);
c ^= b; c -= mx_rotl32(b,16);
a ^= c; a -= mx_rotl32(c,4);
b ^= a; b -= mx_rotl32(a,14);
c ^= b; c -= mx_rotl32(b,24);
return c;
}
// Convert a 32 bit integer into a floating point number in [0,1]
float mx_bits_to_01(uint bits)
{
return float(bits) / float(uint(0xffffffff));
}
float mx_fade(float t)
{
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
}
uint mx_hash_int(int x, int y)
{
uint len = 2u;
uint a, b, c;
a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
a += uint(x);
b += uint(y);
return mx_bjfinal(a, b, c);
}
uint mx_hash_int(int x, int y, int z)
{
uint len = 3u;
uint a, b, c;
a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
a += uint(x);
b += uint(y);
c += uint(z);
return mx_bjfinal(a, b, c);
}
uvec3 mx_hash_vec3(int x, int y)
{
uint h = mx_hash_int(x, y);
// we only need the low-order bits to be random, so split out
// the 32 bit result into 3 parts for each channel
uvec3 result;
result.x = (h ) & 0xFFu;
result.y = (h >> 8 ) & 0xFFu;
result.z = (h >> 16) & 0xFFu;
return result;
}
uvec3 mx_hash_vec3(int x, int y, int z)
{
uint h = mx_hash_int(x, y, z);
// we only need the low-order bits to be random, so split out
// the 32 bit result into 3 parts for each channel
uvec3 result;
result.x = (h ) & 0xFFu;
result.y = (h >> 8 ) & 0xFFu;
result.z = (h >> 16) & 0xFFu;
return result;
}
float mx_perlin_noise_float(vec2 p)
{
int X, Y;
float fx = mx_floorfrac(p.x, X);
float fy = mx_floorfrac(p.y, Y);
float u = mx_fade(fx);
float v = mx_fade(fy);
float result = mx_bilerp(
mx_gradient_float(mx_hash_int(X , Y ), fx , fy ),
mx_gradient_float(mx_hash_int(X+1, Y ), fx-1.0, fy ),
mx_gradient_float(mx_hash_int(X , Y+1), fx , fy-1.0),
mx_gradient_float(mx_hash_int(X+1, Y+1), fx-1.0, fy-1.0),
u, v);
return mx_gradient_scale2d(result);
}
float mx_perlin_noise_float(vec3 p)
{
int X, Y, Z;
float fx = mx_floorfrac(p.x, X);
float fy = mx_floorfrac(p.y, Y);
float fz = mx_floorfrac(p.z, Z);
float u = mx_fade(fx);
float v = mx_fade(fy);
float w = mx_fade(fz);
float result = mx_trilerp(
mx_gradient_float(mx_hash_int(X , Y , Z ), fx , fy , fz ),
mx_gradient_float(mx_hash_int(X+1, Y , Z ), fx-1.0, fy , fz ),
mx_gradient_float(mx_hash_int(X , Y+1, Z ), fx , fy-1.0, fz ),
mx_gradient_float(mx_hash_int(X+1, Y+1, Z ), fx-1.0, fy-1.0, fz ),
mx_gradient_float(mx_hash_int(X , Y , Z+1), fx , fy , fz-1.0),
mx_gradient_float(mx_hash_int(X+1, Y , Z+1), fx-1.0, fy , fz-1.0),
mx_gradient_float(mx_hash_int(X , Y+1, Z+1), fx , fy-1.0, fz-1.0),
mx_gradient_float(mx_hash_int(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0),
u, v, w);
return mx_gradient_scale3d(result);
}
vec3 mx_perlin_noise_vec3(vec2 p)
{
int X, Y;
float fx = mx_floorfrac(p.x, X);
float fy = mx_floorfrac(p.y, Y);
float u = mx_fade(fx);
float v = mx_fade(fy);
vec3 result = mx_bilerp(
mx_gradient_vec3(mx_hash_vec3(X , Y ), fx , fy ),
mx_gradient_vec3(mx_hash_vec3(X+1, Y ), fx-1.0, fy ),
mx_gradient_vec3(mx_hash_vec3(X , Y+1), fx , fy-1.0),
mx_gradient_vec3(mx_hash_vec3(X+1, Y+1), fx-1.0, fy-1.0),
u, v);
return mx_gradient_scale2d(result);
}
vec3 mx_perlin_noise_vec3(vec3 p)
{
int X, Y, Z;
float fx = mx_floorfrac(p.x, X);
float fy = mx_floorfrac(p.y, Y);
float fz = mx_floorfrac(p.z, Z);
float u = mx_fade(fx);
float v = mx_fade(fy);
float w = mx_fade(fz);
vec3 result = mx_trilerp(
mx_gradient_vec3(mx_hash_vec3(X , Y , Z ), fx , fy , fz ),
mx_gradient_vec3(mx_hash_vec3(X+1, Y , Z ), fx-1.0, fy , fz ),
mx_gradient_vec3(mx_hash_vec3(X , Y+1, Z ), fx , fy-1.0, fz ),
mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z ), fx-1.0, fy-1.0, fz ),
mx_gradient_vec3(mx_hash_vec3(X , Y , Z+1), fx , fy , fz-1.0),
mx_gradient_vec3(mx_hash_vec3(X+1, Y , Z+1), fx-1.0, fy , fz-1.0),
mx_gradient_vec3(mx_hash_vec3(X , Y+1, Z+1), fx , fy-1.0, fz-1.0),
mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0),
u, v, w);
return mx_gradient_scale3d(result);
}
float mx_cell_noise_float(vec2 p)
{
int ix = mx_floor(p.x);
int iy = mx_floor(p.y);
return mx_bits_to_01(mx_hash_int(ix, iy));
}
float mx_cell_noise_float(vec3 p)
{
int ix = mx_floor(p.x);
int iy = mx_floor(p.y);
int iz = mx_floor(p.z);
return mx_bits_to_01(mx_hash_int(ix, iy, iz));
}
float mx_fractal_noise_float(vec3 p, int octaves, float lacunarity, float diminish)
{
float result = 0.0;
float amplitude = 1.0;
for (int i = 0; i < octaves; ++i)
{
result += amplitude * mx_perlin_noise_float(p);
amplitude *= diminish;
p *= lacunarity;
}
return result;
}
vec3 mx_fractal_noise_vec3(vec3 p, int octaves, float lacunarity, float diminish)
{
vec3 result = vec3(0.0);
float amplitude = 1.0;
for (int i = 0; i < octaves; ++i)
{
result += amplitude * mx_perlin_noise_vec3(p);
amplitude *= diminish;
p *= lacunarity;
}
return result;
}

View File

@ -0,0 +1,91 @@
// Restrict to 7x7 kernel size for performance reasons
#define MX_MAX_SAMPLE_COUNT 49
// Size of all weights for all levels (including level 1)
#define MX_WEIGHT_ARRAY_SIZE 84
//
// Function to compute the sample size relative to a texture coordinate
//
vec2 mx_compute_sample_size_uv(vec2 uv, float filterSize, float filterOffset)
{
vec2 derivUVx = dFdx(uv) * 0.5f;
vec2 derivUVy = dFdy(uv) * 0.5f;
float derivX = abs(derivUVx.x) + abs(derivUVy.x);
float derivY = abs(derivUVx.y) + abs(derivUVy.y);
float sampleSizeU = 2.0f * filterSize * derivX + filterOffset;
if (sampleSizeU < 1.0E-05f)
sampleSizeU = 1.0E-05f;
float sampleSizeV = 2.0f * filterSize * derivY + filterOffset;
if (sampleSizeV < 1.0E-05f)
sampleSizeV = 1.0E-05f;
return vec2(sampleSizeU, sampleSizeV);
}
//
// Compute a normal mapped to 0..1 space based on a set of input
// samples using a Sobel filter.
//
vec3 mx_normal_from_samples_sobel(float S[9], float _scale)
{
float nx = S[0] - S[2] + (2.0*S[3]) - (2.0*S[5]) + S[6] - S[8];
float ny = S[0] + (2.0*S[1]) + S[2] - S[6] - (2.0*S[7]) - S[8];
float nz = max(_scale, M_FLOAT_EPS) * sqrt(max(1.0 - nx * nx - ny * ny, M_FLOAT_EPS));
vec3 norm = normalize(vec3(nx, ny, nz));
return (norm + 1.0) * 0.5;
}
//
// Apply filter for float samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
float mx_convolution_float(float S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
float result = 0.0;
for (int i = 0; i < sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vec2 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec2 mx_convolution_vec2(vec2 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vec2 result = vec2(0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vec3 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec3 mx_convolution_vec3(vec3 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vec3 result = vec3(0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vec4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
vec4 mx_convolution_vec4(vec4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vec4 result = vec4(0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}

View File

@ -0,0 +1,5 @@
vec2 mx_transform_uv(vec2 uv, vec2 uv_scale, vec2 uv_offset)
{
uv = uv * uv_scale + uv_offset;
return uv;
}

View File

@ -0,0 +1,5 @@
vec2 mx_transform_uv(vec2 uv, vec2 uv_scale, vec2 uv_offset)
{
uv = uv * uv_scale + uv_offset;
return vec2(uv.x, 1.0 - uv.y);
}

View File

@ -0,0 +1,5 @@
float mx_aastep(float threshold, float value)
{
float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
return smoothstep(threshold-afwidth, threshold+afwidth, value);
}

View File

@ -0,0 +1 @@
abs({{in}})

View File

@ -0,0 +1,5 @@
void mx_acescg_to_linear_color3(vec3 _in, out vec3 result)
{
vec4 outColor = vec4(_in, 0.);
result = (mat4(1.705079555511475, -0.1297005265951157, -0.02416634373366833, 0., -0.6242334842681885, 1.138468623161316, -0.1246141716837883, 0., -0.0808461606502533, -0.008768022060394287, 1.148780584335327, 0., 0., 0., 0., 1.) * outColor).rgb;
}

View File

@ -0,0 +1,5 @@
void mx_acescg_to_linear_color4(vec4 _in, out vec4 result)
{
vec4 outColor = vec4(_in.rgb, 0.);
result = vec4((mat4(1.705079555511475, -0.1297005265951157, -0.02416634373366833, 0., -0.6242334842681885, 1.138468623161316, -0.1246141716837883, 0., -0.0808461606502533, -0.008768022060394287, 1.148780584335327, 0., 0., 0., 0., 1.) * outColor).rgb, _in.a);
}

View File

@ -0,0 +1 @@
acos({{in}})

View File

@ -0,0 +1 @@
{{in1}} + {{in2}}

View File

@ -0,0 +1,5 @@
void mx_add_surfaceshader(surfaceshader shader1, surfaceshader shader2, out surfaceshader returnshader)
{
returnshader.color = shader1.color + shader2.color;
returnshader.transparency = shader1.transparency + shader2.transparency;
}

View File

@ -0,0 +1 @@
asin({{in}})

View File

@ -0,0 +1 @@
atan({{in1}}, {{in2}})

View File

@ -0,0 +1,8 @@
#include "stdlib/genglsl/mx_burn_float.glsl"
void mx_burn_color3(vec3 fg, vec3 bg, float mixval, out vec3 result)
{
mx_burn_float(fg.x, bg.x, mixval, result.x);
mx_burn_float(fg.y, bg.y, mixval, result.y);
mx_burn_float(fg.z, bg.z, mixval, result.z);
}

View File

@ -0,0 +1,9 @@
#include "stdlib/genglsl/mx_burn_float.glsl"
void mx_burn_color4(vec4 fg, vec4 bg, float mixval, out vec4 result)
{
mx_burn_float(fg.x, bg.x, mixval, result.x);
mx_burn_float(fg.y, bg.y, mixval, result.y);
mx_burn_float(fg.z, bg.z, mixval, result.z);
mx_burn_float(fg.w, bg.w, mixval, result.w);
}

View File

@ -0,0 +1,9 @@
void mx_burn_float(float fg, float bg, float mixval, out float result)
{
if (abs(fg) < M_FLOAT_EPS)
{
result = 0.0;
return;
}
result = mixval*(1.0 - ((1.0 - bg) / fg)) + ((1.0-mixval)*bg);
}

View File

@ -0,0 +1 @@
ceil({{in}})

View File

@ -0,0 +1,6 @@
#include "stdlib/genglsl/lib/mx_noise.glsl"
void mx_cellnoise2d_float(vec2 texcoord, out float result)
{
result = mx_cell_noise_float(texcoord);
}

View File

@ -0,0 +1,6 @@
#include "stdlib/genglsl/lib/mx_noise.glsl"
void mx_cellnoise3d_float(vec3 position, out float result)
{
result = mx_cell_noise_float(position);
}

View File

@ -0,0 +1 @@
clamp({{in}}, {{low}}, {{high}})

View File

@ -0,0 +1 @@
{{value}}

View File

@ -0,0 +1 @@
cos({{in}})

View File

@ -0,0 +1 @@
cross({{in1}}, {{in2}})

View File

@ -0,0 +1 @@
determinant({{in}})

View File

@ -0,0 +1 @@
({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})

View File

@ -0,0 +1,25 @@
void mx_disjointover_color4(vec4 fg, vec4 bg, float mixval, out vec4 result)
{
float summedAlpha = fg.w + bg.w;
if (summedAlpha <= 1)
{
result.xyz = fg.xyz + bg.xyz;
}
else
{
if (abs(bg.w) < M_FLOAT_EPS)
{
result.xyz = vec3(0.0);
}
else
{
float x = (1 - fg.w) / bg.w;
result.xyz = fg.xyz + bg.xyz * x;
}
}
result.w = min(summedAlpha, 1.0);
result.xyz = result.xyz * mixval + (1.0 - mixval) * bg.xyz;
result.w = result.w * mixval + (1.0 - mixval) * bg.w;
}

View File

@ -0,0 +1 @@
{{in1}} / {{in2}}

Some files were not shown because too many files have changed in this diff Show More