Skip to content

Commit

Permalink
Add support for recursive structs, with example.
Browse files Browse the repository at this point in the history
Add "_struct" suffix to struct type name to avoid potential name clashes with variable names.
Add AggregateValue to centralize struct string parsing. Add support for recursive structs in places - may not be complete yet - centralized syntax parsing - and unit tests pass currently.
refactor struct experiment to not unfold the structs, but instead maintain them in the shaders
  • Loading branch information
ld-kerley committed May 31, 2024
1 parent 58a4a04 commit b04f9ca
Show file tree
Hide file tree
Showing 47 changed files with 1,305 additions and 249 deletions.
35 changes: 35 additions & 0 deletions libraries/experimental/experimental_defs.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
Declarations of experimental data types and nodes
-->

<!-- name clashes with variable names will hopefully be resolved by
recommending struct type names be suffixed with `_struct` -->

<typedef name="texcoord_struct">
<member name="ss" type="float" value="0.5"/>
<member name="tt" type="float" value="0.5"/>
</typedef>

<typedef name="texcoordGroup_struct">
<member name="st_0" type="texcoord_struct" value="{0.1;0.1}"/>
<member name="st_1" type="texcoord_struct" value="{0.5;0.5}"/>
<member name="st_2" type="texcoord_struct" value="{0.9;0.9}"/>
</typedef>

<nodedef name="ND_extract_s_texcoord" node="extracts" nodegroup="shader" >
<input name="in" type="texcoord_struct" value="{0.1;0.1}" />
<output name="out" type="float" value="0.0" />
</nodedef>

<nodedef name="ND_extract_s_texcoordGroup" node="extractsgroup" nodegroup="shader" >
<input name="in" type="texcoordGroup_struct" value="{{0.1;0.2};{0.3;0.4};{0.5;0.6}}"/>
<input name="index" type="integer" value="0"/>
<output name="out" type="float" value="0.0" />
</nodedef>

</materialx>
10 changes: 10 additions & 0 deletions libraries/experimental/experimental_ng.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
Nodegraph Implementations of experimental nodes
-->

</materialx>
15 changes: 15 additions & 0 deletions libraries/experimental/genglsl/experimental_genglsl_impl.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
GLSL Implementations of experimental nodes
-->

<implementation name="IM_extract_s_texcoord_genglsl" nodedef="ND_extract_s_texcoord" target="genglsl" sourcecode="{{in}}.ss" />
<implementation name="IM_extract_s_texcoordGroup_genglsl" nodedef="ND_extract_s_texcoordGroup" file="./mx_extractgroup.glsl" function="mx_extractGroup" target="genglsl">
<input name="in" type="texcoordGroup_struct" implname="data" />
</implementation>

</materialx>
10 changes: 10 additions & 0 deletions libraries/experimental/genglsl/mx_extractgroup.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

void mx_extractGroup(texcoordGroup_struct data, int index, out float result)
{
result = data.st_0.ss;

if (index == 1)
result = data.st_1.ss;
else if (index == 2)
result = data.st_2.ss;
}
14 changes: 14 additions & 0 deletions libraries/experimental/genmdl/experimental_genmdl_impl.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
GLSL Implementations of experimental nodes
-->

<implementation name="IM_extract_s_texcoord_genmdl" nodedef="ND_extract_s_texcoord" target="genmdl" sourcecode="{{in}}.ss" />

<implementation name="IM_extract_s_texcoordGroup_genmdl" nodedef="ND_extract_s_texcoordGroup" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extractGroup({{in}}, {{index}})" target="genmdl" />

</materialx>
15 changes: 15 additions & 0 deletions libraries/experimental/genmsl/experimental_genmsl_impl.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
MSL Implementations of experimental nodes
-->

<implementation name="IM_extract_s_texcoord_genmsl" nodedef="ND_extract_s_texcoord" target="genmsl" sourcecode="{{in}}.ss" />

<implementation name="IM_extract_s_texcoordGroup_genmsl" nodedef="ND_extract_s_texcoordGroup" file="../genglsl/mx_extractgroup.glsl" function="mx_extractGroup" target="genmsl">
<input name="in" type="texcoordGroup_struct" implname="data" />
</implementation>
</materialx>
16 changes: 16 additions & 0 deletions libraries/experimental/genosl/experimental_genosl_impl.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<materialx version="1.38">
<!--
Copyright Contributors to the MaterialX Project
SPDX-License-Identifier: Apache-2.0
GLSL Implementations of experimental nodes
-->

<implementation name="IM_extract_s_texcoord_genosl" nodedef="ND_extract_s_texcoord" target="genosl" sourcecode="{{in}}.ss" />

<implementation name="IM_extract_s_texcoordGroup_genosl" nodedef="ND_extract_s_texcoordGroup" file="./mx_extractgroup.osl" function="mx_extractGroup" target="genosl">
<input name="in" type="texcoordGroup_struct" implname="data" />
</implementation>

</materialx>
9 changes: 9 additions & 0 deletions libraries/experimental/genosl/mx_extractgroup.osl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
void mx_extractGroup(texcoordGroup_struct data, int index, out float result)
{
result = data.st_0.ss;

if (index == 1)
result = data.st_1.ss;
else if (index == 2)
result = data.st_2.ss;
}
7 changes: 7 additions & 0 deletions python/Scripts/generateshader.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ def main():
shadergen.setUnitSystem(unitsystem)
genoptions.targetDistanceUnit = 'meter'

print('- Set up Struct typedefs ...')
shadergen.loadStructTypeDefs(doc)

# Look for renderable nodes
nodes = mx_gen_shader.findRenderableElements(doc)
if not nodes:
Expand All @@ -165,6 +168,8 @@ def main():
if gentarget in ['glsl', 'essl', 'vulkan', 'msl']:
pixelSource = shader.getSourceCode(mx_gen_shader.PIXEL_STAGE)
filename = pathPrefix + "/" + shader.getName() + "." + gentarget + ".frag"
if gentarget == "msl":
filename += ".metal"
print('--- Wrote pixel shader to: ' + filename)
file = open(filename, 'w+')
file.write(pixelSource)
Expand All @@ -173,6 +178,8 @@ def main():

vertexSource = shader.getSourceCode(mx_gen_shader.VERTEX_STAGE)
filename = pathPrefix + "/" + shader.getName() + "." + gentarget + ".vert"
if gentarget == "msl":
filename += ".metal"
print('--- Wrote vertex shader to: ' + filename)
file = open(filename, 'w+')
file.write(vertexSource)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<materialx version="1.38">
<nodegraph name="test_struct_texcoord">

<extracts name="extracts" type="float">
<input name="in" type="texcoord_struct" value="{0.01;0.5}"/>
</extracts>

<convert name="float_to_color3" type="color3">
<input name="in" type="float" nodename="extracts"/>
</convert>
<oren_nayar_diffuse_bsdf name="diffuse_brdf1" type="BSDF">
<input name="color" type="color3" nodename="float_to_color3" />
</oren_nayar_diffuse_bsdf>
<surface name="surface1" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse_brdf1" />
<input name="opacity" type="float" value="1.0" />
</surface>
<output name="out" type="surfaceshader" nodename="surface1" />
</nodegraph>
</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<materialx version="1.38">
<nodegraph name="test_struct_texcoord">

<extractsgroup name="extracts_group" type="float">
<input name="in" type="texcoordGroup_struct" value="{{0.1;0.2};{0.3;0.4};{0.5;0.6}}"/>
<input name="index" type="integer" value="0"/>
</extractsgroup>

<convert name="float_to_color3" type="color3">
<input name="in" type="float" nodename="extracts_group"/>
</convert>
<oren_nayar_diffuse_bsdf name="diffuse_brdf1" type="BSDF">
<input name="color" type="color3" nodename="float_to_color3" />
</oren_nayar_diffuse_bsdf>
<surface name="surface1" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse_brdf1" />
<input name="opacity" type="float" value="1.0" />
</surface>
<output name="out" type="surfaceshader" nodename="surface1" />
</nodegraph>
</materialx>
8 changes: 8 additions & 0 deletions source/MaterialXCore/Definition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,12 @@ vector<UnitDefPtr> UnitTypeDef::getUnitDefs() const
return unitDefs;
}

ValuePtr AttributeDef::getValue() const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getValueString(), getType(), getDocument()->getTypeDef(getType()));
}

MATERIALX_NAMESPACE_END
121 changes: 58 additions & 63 deletions source/MaterialXCore/Definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,61 @@ MATERIALX_NAMESPACE_BEGIN

extern MX_CORE_API const string COLOR_SEMANTIC;
extern MX_CORE_API const string SHADER_SEMANTIC;

class NodeDef;
class Implementation;
class TypeDef;
class TargetDef;
class Member;
class Unit;
class UnitDef;
class UnitTypeDef;
class AttributeDef;

/// A shared pointer to a NodeDef
using NodeDefPtr = shared_ptr<NodeDef>;
/// A shared pointer to a const NodeDef
using ConstNodeDefPtr = shared_ptr<const NodeDef>;

/// A shared pointer to an Implementation
using ImplementationPtr = shared_ptr<Implementation>;
/// A shared pointer to a const Implementation
using ConstImplementationPtr = shared_ptr<const Implementation>;

/// A shared pointer to a TypeDef
using TypeDefPtr = shared_ptr<TypeDef>;
/// A shared pointer to a const TypeDef
using ConstTypeDefPtr = shared_ptr<const TypeDef>;

/// A shared pointer to a TargetDef
using TargetDefPtr = shared_ptr<TargetDef>;
/// A shared pointer to a const TargetDef
using ConstTargetDefPtr = shared_ptr<const TargetDef>;

/// A shared pointer to a Member
using MemberPtr = shared_ptr<Member>;
/// A shared pointer to a const Member
using ConstMemberPtr = shared_ptr<const Member>;

/// A shared pointer to a Unit
using UnitPtr = shared_ptr<Unit>;
/// A shared pointer to a const Unit
using ConstUnitPtr = shared_ptr<const Unit>;

/// A shared pointer to a UnitDef
using UnitDefPtr = shared_ptr<UnitDef>;
/// A shared pointer to a const UnitDef
using ConstUnitDefPtr = shared_ptr<const UnitDef>;

/// A shared pointer to a UnitTypeDef
using UnitTypeDefPtr = shared_ptr<UnitTypeDef>;
/// A shared pointer to a const UnitTypeDef
using ConstUnitTypeDefPtr = shared_ptr<const UnitTypeDef>;

/// A shared pointer to an AttributeDef
using AttributeDefPtr = shared_ptr<AttributeDef>;
/// A shared pointer to a const AttributeDef
using AttributeDefDefPtr = shared_ptr<const AttributeDef>;
//
//class NodeDef;
//class Implementation;
//class TypeDef;
//class TargetDef;
//class Member;
//class Unit;
//class UnitDef;
//class UnitTypeDef;
//class AttributeDef;
//
///// A shared pointer to a NodeDef
//using NodeDefPtr = shared_ptr<NodeDef>;
///// A shared pointer to a const NodeDef
//using ConstNodeDefPtr = shared_ptr<const NodeDef>;
//
///// A shared pointer to an Implementation
//using ImplementationPtr = shared_ptr<Implementation>;
///// A shared pointer to a const Implementation
//using ConstImplementationPtr = shared_ptr<const Implementation>;
//
///// A shared pointer to a TypeDef
//using TypeDefPtr = shared_ptr<TypeDef>;
///// A shared pointer to a const TypeDef
//using ConstTypeDefPtr = shared_ptr<const TypeDef>;
//
///// A shared pointer to a TargetDef
//using TargetDefPtr = shared_ptr<TargetDef>;
///// A shared pointer to a const TargetDef
//using ConstTargetDefPtr = shared_ptr<const TargetDef>;
//
///// A shared pointer to a Member
//using MemberPtr = shared_ptr<Member>;
///// A shared pointer to a const Member
//using ConstMemberPtr = shared_ptr<const Member>;
//
///// A shared pointer to a Unit
//using UnitPtr = shared_ptr<Unit>;
///// A shared pointer to a const Unit
//using ConstUnitPtr = shared_ptr<const Unit>;
//
///// A shared pointer to a UnitDef
//using UnitDefPtr = shared_ptr<UnitDef>;
///// A shared pointer to a const UnitDef
//using ConstUnitDefPtr = shared_ptr<const UnitDef>;
//
///// A shared pointer to a UnitTypeDef
//using UnitTypeDefPtr = shared_ptr<UnitTypeDef>;
///// A shared pointer to a const UnitTypeDef
//using ConstUnitTypeDefPtr = shared_ptr<const UnitTypeDef>;
//
///// A shared pointer to an AttributeDef
//using AttributeDefPtr = shared_ptr<AttributeDef>;
///// A shared pointer to a const AttributeDef
//using AttributeDefDefPtr = shared_ptr<const AttributeDef>;

/// @class NodeDef
/// A node definition element within a Document.
Expand Down Expand Up @@ -416,11 +416,11 @@ class MX_CORE_API TargetDef : public TypedElement

/// @class Member
/// A member element within a TypeDef.
class MX_CORE_API Member : public TypedElement
class MX_CORE_API Member : public ValueElement
{
public:
Member(ElementPtr parent, const string& name) :
TypedElement(parent, CATEGORY, name)
ValueElement(parent, CATEGORY, name)
{
}
virtual ~Member() { }
Expand Down Expand Up @@ -618,12 +618,7 @@ class MX_CORE_API AttributeDef : public TypedElement
///
/// @return A shared pointer to the typed value of this element, or an
/// empty shared pointer if no value is present.
ValuePtr getValue() const
{
if (!hasValue())
return ValuePtr();
return Value::createValueFromStrings(getValueString(), getType());
}
ValuePtr getValue() const;

/// @}
/// @name Elements
Expand Down
16 changes: 16 additions & 0 deletions source/MaterialXCore/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,22 @@ string ValueElement::getResolvedValueString(StringResolverPtr resolver) const
return resolver->resolve(getValueString(), getType());
}

ValuePtr ValueElement::getValue() const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getValueString(), getType(), getDocument()->getTypeDef(getType()));
}

ValuePtr ValueElement::getResolvedValue(StringResolverPtr resolver) const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getResolvedValueString(resolver), getType(), getDocument()->getTypeDef(getType()));
}

ValuePtr ValueElement::getDefaultValue() const
{
ConstElementPtr parent = getParent();
Expand Down
Loading

0 comments on commit b04f9ca

Please sign in to comment.