Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
- Update links to pre-built binaries in README.md.
- Update link to ASWF Open Source Days in README.md.
- Update MaterialX Overview in MainPage.md.
- Update code and data syntax in ShaderGeneration.md.
- Update documentation for the ImageHandler::acquireImage method.
  • Loading branch information
jstone-lucasfilm committed Sep 15, 2023
1 parent 46a5b50 commit 1a39d99
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 77 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ The Open Chess Set is an open reference asset, consisting of a [MaterialX file](

The following packages contain pre-built binaries for the latest release, including the MaterialX viewer, Python libraries, and example assets:

- [Microsoft Windows (Visual Studio 2022, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Windows_VS2022_x64_Python39.zip)
- [MacOS (Xcode 13, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_MacOS_Xcode_13_Python39.zip)
- [Linux (GCC 11, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Linux_GCC_11_Python39.zip)
- [Microsoft Windows (Visual Studio 2022, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Windows_VS2022_x64_Python311.zip)
- [MacOS (Xcode 14, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_MacOS_Xcode_14_Python311.zip)
- [Linux (GCC 12, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Linux_GCC_12_Python311.zip)

### Additional Resources

- The [Developer Guide](http://www.materialx.org/docs/api/index.html) contains a developer-oriented overview of MaterialX with API documentation.
- The [Python Scripts](python/Scripts) folder contains standalone examples of MaterialX Python code.
- The [JavaScript](javascript) folder contains details on building JavaScript bindings for MaterialX.
- Presentations at [ASWF Open Source Days](http://www.materialx.org/assets/ASWF_OSD2022_MaterialX_OSL_Final.pdf) and the [SIGGRAPH Physically Based Shading Course](https://blog.selfshadow.com/publications/s2020-shading-course/#materialx) provide details on the roadmap for MaterialX development.
- Presentations at [ASWF Open Source Days](https://materialx.org/assets/ASWF_OSD2023_MaterialX_Final.pdf) and the [SIGGRAPH Physically Based Shading Course](https://blog.selfshadow.com/publications/s2020-shading-course/#materialx) provide details on the roadmap for MaterialX development.
2 changes: 1 addition & 1 deletion documents/DeveloperGuide/MainPage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MaterialX Overview

MaterialX is an open standard for transfer of rich material and look-development content between applications and renderers. Originated at Lucasfilm in 2012, MaterialX has been used by Industrial Light & Magic (ILM) in feature films such as _Star Wars: The Force Awakens_ and real-time experiences such as _Trials on Tatooine_, and it remains the central material format for new ILM productions.
MaterialX is an open standard for representing rich material and look-development content in computer graphics, enabling its platform-independent description and exchange across applications and renderers. Launched at [Industrial Light & Magic](https://www.ilm.com/) in 2012, MaterialX has been a key technology in their feature films and real-time experiences since _Star Wars: The Force Awakens_ and _Millennium Falcon: Smugglers Run_. The project was released as open source in 2017, with companies including Sony Pictures Imageworks, Pixar, Autodesk, Adobe, and SideFX contributing to its ongoing development. In 2021, MaterialX became the seventh hosted project of the [Academy Software Foundation](https://www.aswf.io/).

### Quick Start for Developers

Expand Down
135 changes: 63 additions & 72 deletions documents/DeveloperGuide/ShaderGeneration.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,41 @@ Figure 2. The first option is to keep inline code in a file. The file extension

```xml
// Nodedef elements for node <add>
<nodedef name="ND_add_float" node="add" type="float" defaultinput="in1">
<input name="in1" type="float"/>
<input name="in2" type="float"/>
<nodedef name="ND_add_float" node="add">
<input name="in1" type="float" />
<input name="in2" type="float" />
<output name="out" type="float" defaultinput="in1" />
</nodedef>
<nodedef name="ND_add_color3" node="add" type="color3" defaultinput="in1">
<input name="in1" type="color3"/>
<input name="in2" type="color3"/>
<nodedef name="ND_add_color3" node="add" type="color3">
<input name="in1" type="color3" />
<input name="in2" type="color3" />
<output name="out" type="color3" defaultinput="in1" />
</nodedef>
<... more types ...>

// Implementation elements for node <add>
<implementation name="IM_add_float" nodedef="ND_add_float" file="mx_add.inline"/>
<implementation name="IM_add_color3" nodedef="ND_add_color3" file="mx_add.inline"/>
<implementation name="IM_add_float" nodedef="ND_add_float" file="mx_add.inline" />
<implementation name="IM_add_color3" nodedef="ND_add_color3" file="mx_add.inline" />
<... more types ...>

// Nodedef elements for node <mix>
<nodedef name="ND_mix_float" node="mix" type="float" defaultinput="bg">
<input name="fg" type="float"/>
<input name="bg" type="float"/>
<input name="mix" type="float"/>
<nodedef name="ND_mix_float" node="mix">
<input name="fg" type="float" />
<input name="bg" type="float" />
<input name="mix" type="float" />
<output name="out" type="float" defaultinput="bg" />
</nodedef>
<nodedef name="ND_mix_color3" node="mix" type="color3" defaultinput="bg">
<input name="fg" type="color3"/>
<input name="bg" type="color3"/>
<input name="mix" type="float"/>
<nodedef name="ND_mix_color3" node="mix">
<input name="fg" type="color3" />
<input name="bg" type="color3" />
<input name="mix" type="color3" />
<output name="out" type="color3" defaultinput="bg" />
</nodedef>
<... more types ...>

// Implementation elements for node <mix>
<implementation name="IM_mix_float" nodedef="ND_mix_float" sourcecode="mix({{bg}}, {{fg}}, {{mix}})"/>
<implementation name="IM_mix_color3" nodedef="ND_mix_color3" sourcecode="mix({{bg}}, {{fg}}, {{mix}})"/>
<implementation name="IM_mix_float" nodedef="ND_mix_float" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
<implementation name="IM_mix_color3" nodedef="ND_mix_color3" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
<... more types ...>
```
```c++
Expand All @@ -79,30 +83,29 @@ For nodes that can’t be implemented by inline expressions a function definitio
```xml
// Nodedef element
<nodedef name="ND_image_color3" node="image" type="color3" default="0.0, 0.0, 0.0">
<parameter name="file" type="filename"/>
<parameter name="layer" type="string" value=""/>
<parameter name="default" type="color3" value="0.0, 0.0, 0.0"/>
<input name="texcoord" type="vector2" defaultgeomprop="texcoord"/>
<parameter name="filtertype" type="string" value="linear"/>
<parameter name="uaddressmode" type="string" value="periodic"/>
<parameter name="vaddressmode" type="string" value="periodic"/>
<parameter name="framerange" type="string" value=""/>
<parameter name="frameoffset" type="integer" value="0"/>
<parameter name="frameendaction" type="string" value="black"/>
<nodedef name="ND_image_color3" node="image">
<input name="file" type="filename" value="" uniform="true" />
<input name="layer" type="string" value="" uniform="true" />
<input name="default" type="color3" value="0.0, 0.0, 0.0" />
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<input name="uaddressmode" type="string" value="periodic" uniform="true" />
<input name="vaddressmode" type="string" value="periodic" uniform="true" />
<input name="filtertype" type="string" value="linear" uniform="true" />
<input name="framerange" type="string" value="" uniform="true" />
<input name="frameoffset" type="integer" value="0" uniform="true" />
<input name="frameendaction" type="string" value="constant" uniform="true" />
<output name="out" type="color3" default="0.0, 0.0, 0.0" />
</nodedef>
// Implementation element
<implementation name="IM_image_color3_osl" nodedef="ND_image_color3"
file="mx_image_color3.osl" language="osl"/>
<implementation name="IM_image_color3_osl" nodedef="ND_image_color3" file="mx_image_color3.osl" target="genosl" />
```
```c++
// File 'mx_image_color3.osl' contains:
void mx_image_color3(string file, string layer, color defaultvalue,
vector2 texcoord, string filtertype,
string uaddressmode, string vaddressmode,
string framerange, int frameoffset,
string frameendaction, output color out)
vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype,
string framerange, int frameoffset, string frameendaction,
output color out)
{
// Sample the texture
out = texture(file, texcoord.x, texcoord.y,
Expand All @@ -120,51 +123,38 @@ As an alternative to defining source code, there is also an option to reference
This is useful for creating a compound for a set of nodes performing some common operation. It can then be referenced as a node inside other nodegraphs. It is also useful for creating compatibility graphs for unknown nodes. If a node is created by some third party, and its implementation is unknown or proprietary, a compatibility graph can be created using known nodes and be referenced as a stand-in implementation. Linking a nodegraph to a nodedef is done by simply setting a nodedef attribute on the nodegraph definition. See Figure 4 for an example.
```xml
<nodedef name="ND_checker_float" node="checker" type="float">
<input name="scale" type="vector2" value="8.0, 8.0"/>
<nodedef name="ND_checker_float" node="checker">
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<input name="uvtiling" type="vector2" value="8.0, 8.0" />
<output name="out" type="float" />
</nodedef>
<nodegraph name="IM_checker_float" nodedef="ND_checker_float">
<texcoord name="texcoord1" type="vector2">
<parameter name="index" type="integer" value="0"/>
</texcoord>
<multiply name="mult1" type="vector2">
<input name="in1" type="vector2" nodename="texcoord1"/>
<input name="in2" type="vector2" interfacename="scale"/>
<input name="in1" type="vector2" interfacename="texcoord" />
<input name="in2" type="vector2" interfacename="uvtiling" />
</multiply>
<swizzle name="swizz_x" type="float">
<input name="in" type="vector2" nodename="mult1"/>
<parameter name="channels" type="string" value="x"/>
</swizzle>
<swizzle name="swizz_y" type="float">
<input name="in" type="vector2" nodename="mult1"/>
<parameter name="channels" type="string" value="y"/>
</swizzle>
<floor name="floor1" type="float">
<input name="in" type="float" nodename="swizz_x"/>
<floor name="floor1" type="vector2">
<input name="in" type="vector2" nodename="mult1" />
</floor>
<floor name="floor2" type="float">
<input name="in" type="float" nodename="swizz_y"/>
</floor>
<add name="add1" type="float">
<input name="in1" type="float" nodename="floor1"/>
<input name="in2" type="float" nodename="floor2"/>
</add>
<modulo name="mod1" type="float">
<input name="in1" type="float" nodename="add1"/>
<input name="in2" type="float" value="2.0"/>
<dotproduct name="dotproduct1" type="float">
<input name="in1" type="vector2" nodename="floor1" />
<input name="in2" type="vector2" value="1, 1" />
</dotproduct>
<modulo name="modulo1" type="float">
<input name="in1" type="float" nodename="dotproduct1" />
<input name="in2" type="float" value="2" />
</modulo>
<output name="out" type="float" nodename="mod1"/>
<output name="out" type="float" nodename="modulo1" />
</nodegraph>
```
**Figure 4**: Checker node implementation using a nodegraph.

### 1.3.4 Dynamic Code Generation
In some situations static source code is not enough to implement a node. The code might need to be customized depending on parameters set on the node. Or for a hardware render target vertex streams or uniform inputs might need to be created in order to supply the data needed for the node implementation.

In this case, a C++ class can be added to handle the implementation of the node. The class should be derived from the base class `ShaderNodeImpl`. It should specify what language and target it is for by overriding `getLanguage()` and `getTarget()`. It can also be specified to support all languages or all targets by setting the identifier to an empty string, as done for the target identifier in the example below. It then needs to be registered for a `ShaderGenerator` by calling `ShaderGenerator::registerImplementation()`. See Figure 5 for an example.
In this case, a C++ class can be added to handle the implementation of the node. The class should be derived from the base class `ShaderNodeImpl`. It should specify what target it is for by overriding `getTarget()`. It then needs to be registered for a `ShaderGenerator` by calling `ShaderGenerator::registerImplementation()`. See Figure 5 for an example.

When a `ShaderNodeImpl` class is used for a nodedef the corresponding `<implementation>`
element doesn’t need a file attribute, since no static source code is used. The `<implementation>` element will then act only as a declaration that there exists an implementation for the nodedef for a particular language and target.
When a `ShaderNodeImpl` class is used for a nodedef the corresponding `<implementation>` element doesn’t need a file attribute, since no static source code is used. The `<implementation>` element will then act only as a declaration that there exists an implementation for the nodedef for a particular target.

Note that by using a `ShaderNodeImpl` class for your node's implementation it is no longer data driven, as in the other three methods above. So it's recommended to use this only when inline expressions or static source code functions are not enough to handle the implementation of a node.

Expand All @@ -175,8 +165,7 @@ class FooOsl : public ShaderNodeImpl
public:
static ShaderNodeImplPtr create() { return std::make_shared<FooOsl>(); }

const string& getLanguage() const override { return LANGUAGE_OSL; }
const string& getTarget() const override { return EMPTY_STRING; }
const string& getTarget() const override { return OslShaderGenerator::TARGET; }

void emitFunctionDefinition(const ShaderNode& node, GenContext& context,
ShaderStage& stage) const override
Expand Down Expand Up @@ -291,7 +280,8 @@ class TexCoordGlsl : public ShaderNodeImpl
const string index = indexInput ? indexInput->getValue()->getValueString() : "0";
const string variable = "texcoord_" + index;

BEGIN_SHADER_STAGE(stage, Stage::VERTEX)
DEFINE_SHADER_STAGE(stage, Stage::VERTEX)
{
VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA);
const string prefix = vertexData.getInstance() + ".";
ShaderPort* texcoord = vertexData[variable];
Expand All @@ -300,17 +290,18 @@ class TexCoordGlsl : public ShaderNodeImpl
shadergen.emitLine(prefix + texcoord->getVariable() + " = i_" + variable, stage);
texcoord->setEmitted();
}
END_SHADER_STAGE(shader, Stage::VERTEX)
}

BEGIN_SHADER_STAGE(stage, Stage::PIXEL)
DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
{
VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA);
const string prefix = vertexData.getInstance() + ".";
ShaderPort* texcoord = vertexData[variable];
shadergen.emitLineBegin(stage);
shadergen.emitOutput(node.getOutput(), true, false, context, stage);
shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage);
shadergen.emitLineEnd(stage);
END_SHADER_STAGE(shader, Stage::PIXEL)
}
}
};
```
Expand Down
3 changes: 3 additions & 0 deletions source/MaterialXRender/ImageHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ class MX_RENDER_API ImageHandler

/// Acquire an image from the cache or file system. If the image is not
/// found in the cache, then each image loader will be applied in turn.
/// If the image cannot be found by any loader, then a uniform image of the
/// given default color will be returned.
/// @param filePath File path of the image.
/// @param defaultColor Default color to use as a fallback for missing images.
/// @return On success, a shared pointer to the acquired image.
ImagePtr acquireImage(const FilePath& filePath, const Color4& defaultColor = Color4(0.0f));

Expand Down

0 comments on commit 1a39d99

Please sign in to comment.