Skip to content

Commit 5d7b907

Browse files
authored
Merge branch 'main' into fix_resource_install
2 parents ef4a215 + 5679f07 commit 5d7b907

File tree

15 files changed

+226
-157
lines changed

15 files changed

+226
-157
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
void mx_set_ci (
2+
int output_type,
3+
4+
// the per-type inputs must be named with "input_<typename>"
5+
// the of these inputs defines their corresponding output_type value.
6+
// this is dynamically derived in the shader generation code by
7+
// inspecting the order of the inputs in the node definition
8+
surfaceshader input_surfaceshader,
9+
MATERIAL input_material,
10+
BSDF input_BSDF,
11+
EDF input_EDF,
12+
float input_float,
13+
color input_color3,
14+
color4 input_color4,
15+
vector2 input_vector2,
16+
vector input_vector3,
17+
vector4 input_vector4,
18+
int input_integer,
19+
int input_boolean,
20+
matrix input_matrix33,
21+
matrix input_matrix44,
22+
displacementshader input_displacementshader,
23+
24+
output closure color out_ci
25+
)
26+
{
27+
color c = 0;
28+
float a = 1;
29+
30+
if (output_type == 0) {
31+
float opacity_weight = clamp(input_surfaceshader.opacity, 0.0, 1.0);
32+
out_ci = (input_surfaceshader.bsdf + input_surfaceshader.edf) * opacity_weight + transparent() * (1.0 - opacity_weight);
33+
} else if (output_type == 1) {
34+
out_ci = input_material;
35+
} else if (output_type == 2) {
36+
out_ci = input_BSDF;
37+
} else if (output_type == 3) {
38+
out_ci = input_EDF;
39+
} else {
40+
if (output_type == 4) {
41+
c = input_float;
42+
} else if (output_type == 5) {
43+
c = input_color3;
44+
} else if (output_type == 6) {
45+
c = input_color4.rgb;
46+
a = input_color4.a;
47+
} else if (output_type == 7) {
48+
c = color(input_vector2.x, input_vector2.y, 0);
49+
} else if (output_type == 8) {
50+
c = color(input_vector3);
51+
} else if (output_type == 9) {
52+
c = color(input_vector4.x, input_vector4.y, input_vector4.z);
53+
a = input_vector4.w;
54+
} else if (output_type == 10) {
55+
c = color(input_integer);
56+
} else if (output_type == 11) {
57+
c = color(input_boolean);
58+
} else if (output_type == 12) {
59+
c = color(input_matrix33[0][0], input_matrix33[1][1], input_matrix33[2][2]);
60+
} else if (output_type == 13) {
61+
c = color(input_matrix44[0][0], input_matrix44[1][1], input_matrix44[2][2]);
62+
a = input_matrix44[4][4];
63+
} else if (output_type == 14) {
64+
c = color(input_displacementshader);
65+
}
66+
out_ci = c * a * emission() + (1-a) * transparent();
67+
}
68+
69+
Ci = out_ci;
70+
}

libraries/stdlib/genosl/stdlib_genosl_impl.mtlx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,32 @@
77
Declarations for OSL implementations of standard nodes included in the MaterialX specification.
88
-->
99

10+
<!-- This nodedef is an implementation detail of the OSL shader generators, and does not
11+
represent a node in the MaterialX specification.
12+
This node is used to ensure that the final output from an OSL shader, either direct
13+
shader source, or generated shader group, is renderable by encoding conversions
14+
for all necessary types to a `closure color -->
15+
<nodedef name="ND_osl_set_ci" node="osl_set_ci">
16+
<input name="output_mode" type="integer" default="0"/>
17+
<input name="input_surfaceshader" type="surfaceshader" default=""/>
18+
<input name="input_material" type="material" default=""/>
19+
<input name="input_BSDF" type="BSDF" default=""/>
20+
<input name="input_EDF" type="EDF" default=""/>
21+
<input name="input_float" type="float" default=""/>
22+
<input name="input_color3" type="color3" default=""/>
23+
<input name="input_color4" type="color4" default=""/>
24+
<input name="input_vector2" type="vector2" default=""/>
25+
<input name="input_vector3" type="vector3" default=""/>
26+
<input name="input_vector4" type="vector4" default=""/>
27+
<input name="input_integer" type="integer" default=""/>
28+
<input name="input_boolean" type="boolean" default=""/>
29+
<input name="input_matrix33" type="matrix33" default=""/>
30+
<input name="input_matrix44" type="matrix44" default=""/>
31+
<input name="input_displacementshader" type="displacementshader" default=""/>
32+
<output name="out_ci" type="material"/>
33+
</nodedef>
34+
<implementation name="IM_osl_set_ci_genosl" nodedef="ND_osl_set_ci" file="mx_set_ci.osl" function="mx_set_ci" target="genosl"/>
35+
1036
<!-- ======================================================================== -->
1137
<!-- Shader nodes -->
1238
<!-- ======================================================================== -->

source/MaterialXGenGlsl/GlslShaderGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ void GlslShaderGenerator::toVec4(TypeDesc type, string& variable)
631631
{
632632
variable = "vec4(" + variable + ", 0.0, 1.0)";
633633
}
634-
else if (type == Type::FLOAT || type == Type::INTEGER)
634+
else if (type == Type::FLOAT || type == Type::INTEGER || type == Type::BOOLEAN)
635635
{
636636
variable = "vec4(" + variable + ", " + variable + ", " + variable + ", 1.0)";
637637
}

source/MaterialXGenOsl/LibsToOso.cpp

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -21,77 +21,6 @@
2121

2222
namespace mx = MaterialX;
2323

24-
const std::string setCiOslNetworkSource = R"(
25-
26-
#include "mx_funcs.h"
27-
28-
#define true 1
29-
#define false 0
30-
struct textureresource { string filename; string colorspace; };
31-
#define BSDF closure color
32-
#define EDF closure color
33-
#define VDF closure color
34-
struct surfaceshader { closure color bsdf; closure color edf; float opacity; };
35-
#define volumeshader closure color
36-
#define displacementshader vector
37-
#define lightshader closure color
38-
#define MATERIAL closure color
39-
40-
#define M_FLOAT_EPS 1e-8
41-
closure color null_closure() { closure color null_closure = 0; return null_closure; }
42-
43-
shader setCi (
44-
float float_input = 0,
45-
color color3_input = 0,
46-
color4 color4_input = {0,0},
47-
vector2 vector2_input = {0,0},
48-
vector vector3_input = 0,
49-
vector4 vector4_input = {0,0},
50-
surfaceshader surfaceshader_input = {0,0,0},
51-
BSDF BSDF_input = 0,
52-
EDF EDF_input = 0,
53-
MATERIAL material_input = 0,
54-
55-
output closure color Out_Ci = 0
56-
)
57-
{
58-
color c = 0;
59-
float a = 1;
60-
61-
if (isconnected(surfaceshader_input)) {
62-
63-
float opacity_weight = clamp(surfaceshader_input.opacity, 0.0, 1.0);
64-
Out_Ci = (surfaceshader_input.bsdf + surfaceshader_input.edf) * opacity_weight + transparent() * (1.0 - opacity_weight);
65-
66-
} else if (isconnected(material_input)) {
67-
Out_Ci = material_input;
68-
} else if (isconnected(BSDF_input)) {
69-
Out_Ci = BSDF_input;
70-
} else if (isconnected(EDF_input)) {
71-
Out_Ci = EDF_input;
72-
} else {
73-
if (isconnected(float_input)) {
74-
c = float_input;
75-
} else if (isconnected(color3_input)) {
76-
c = color3_input;
77-
} else if (isconnected(color4_input)) {
78-
c = color4_input.rgb;
79-
a = color4_input.a;
80-
} else if (isconnected(vector2_input)) {
81-
c = color(vector2_input.x, vector2_input.y, 0);
82-
} else if (isconnected(vector3_input)) {
83-
c = color(vector3_input);
84-
} else if (isconnected(vector4_input)) {
85-
c = color(vector4_input.x, vector4_input.y, vector4_input.z);
86-
a = vector4_input.w;
87-
}
88-
Out_Ci = c * a * emission() + (1-a) * transparent();
89-
}
90-
91-
Ci = Out_Ci;
92-
}
93-
)";
94-
9524
const std::string options =
9625
" Options: \n"
9726
" --outputOsoPath [DIRPATH] TODO\n"
@@ -290,44 +219,6 @@ int main(int argc, char* const argv[])
290219

291220
// We'll use this boolean to return an error code is one of the `NodeDef` failed to codegen/compile.
292221
bool hasFailed = false;
293-
try
294-
{
295-
const std::string& oslFilePath = (outputOsoPath / "setCi.osl").asString();
296-
std::ofstream oslFile;
297-
298-
// TODO: Check that we have a valid/opened file descriptor before doing anything with it?
299-
oslFile.open(oslFilePath);
300-
// Dump the content of the codegen'd `NodeDef` to our `.osl` file.
301-
oslFile << setCiOslNetworkSource;
302-
oslFile.close();
303-
304-
// Compile the `.osl` file to a `.oso` file next to it.
305-
oslRenderer->compileOSL(oslFilePath);
306-
}
307-
// Catch any codegen/compilation related exceptions.
308-
catch (mx::ExceptionRenderError& exc)
309-
{
310-
std::cout << "Encountered a codegen/compilation related exception for the "
311-
"following node: "
312-
<< std::endl;
313-
std::cout << exc.what() << std::endl;
314-
315-
// Dump details about the exception in the log file.
316-
for (const std::string& error : exc.errorLog())
317-
{
318-
std::cout << error << std::endl;
319-
}
320-
321-
hasFailed = true;
322-
}
323-
// Catch any other exceptions
324-
catch (mx::Exception& exc)
325-
{
326-
std::cout << "Failed to codegen/compile the following node to OSL: " << std::endl;
327-
std::cout << exc.what() << std::endl;
328-
329-
hasFailed = true;
330-
}
331222

332223
// We create and use a dedicated `NodeGraph` to avoid `NodeDef` names collision.
333224
mx::NodeGraphPtr librariesDocGraph = librariesDoc->addNodeGraph("librariesDocGraph");

source/MaterialXGenOsl/OslNetworkShaderGenerator.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ const string OslNetworkShaderGenerator::TARGET = "genoslnetwork";
2121
//
2222

2323
OslNetworkShaderGenerator::OslNetworkShaderGenerator(TypeSystemPtr typeSystem) :
24-
ShaderGenerator(typeSystem, OslNetworkSyntax::create(typeSystem))
24+
OslShaderGenerator(typeSystem)
2525
{
26+
_syntax = OslNetworkSyntax::create(typeSystem);
2627
}
2728

2829
ShaderNodeImplPtr OslNetworkShaderGenerator::createShaderNodeImplForImplementation(const Implementation& /* implElement */) const
@@ -46,6 +47,11 @@ ShaderPtr OslNetworkShaderGenerator::generate(const string& name, ElementPtr ele
4647
ShaderGraph& graph = shader->getGraph();
4748
ShaderStage& stage = shader->getStage(Stage::PIXEL);
4849

50+
if (context.getOptions().oslConnectCiWrapper)
51+
{
52+
addSetCiTerminalNode(graph, element->getDocument(), context);
53+
}
54+
4955
ConstDocumentPtr document = element->getDocument();
5056

5157
string lastNodeName;
@@ -140,18 +146,6 @@ ShaderPtr OslNetworkShaderGenerator::generate(const string& name, ElementPtr ele
140146
emitLine(connect, stage, false);
141147
}
142148

143-
// During unit tests, wrap a special node that will add the output to Ci.
144-
if (context.getOptions().oslNetworkConnectCiWrapper)
145-
{
146-
emitLine("shader setCi root ;", stage, false);
147-
string connect = connectString(
148-
lastNodeName,
149-
lastOutput->getName(),
150-
"root",
151-
lastOutput->getType().getName() + "_input");
152-
emitLine(connect, stage, false);
153-
}
154-
155149
// From our set of required oso paths, build the path string that oslc will need.
156150
string osoPathStr;
157151
string separator = "";

source/MaterialXGenOsl/OslNetworkShaderGenerator.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#include <MaterialXGenOsl/Export.h>
1313

14-
#include <MaterialXGenShader/ShaderGenerator.h>
14+
#include <MaterialXGenOsl/OslShaderGenerator.h>
1515

1616
MATERIALX_NAMESPACE_BEGIN
1717

@@ -20,7 +20,7 @@ using OslNetworkShaderGeneratorPtr = shared_ptr<class OslNetworkShaderGenerator>
2020
/// @class OslNetworkShaderGenerator
2121
/// OSL (Open Shading Language) Network shader generator.
2222
/// Generates a command string that OSL can use to build a ShaderGroup.
23-
class MX_GENOSL_API OslNetworkShaderGenerator : public ShaderGenerator
23+
class MX_GENOSL_API OslNetworkShaderGenerator : public OslShaderGenerator
2424
{
2525
public:
2626
/// Constructor.
@@ -50,7 +50,7 @@ class MX_GENOSL_API OslNetworkShaderGenerator : public ShaderGenerator
5050

5151
protected:
5252
/// Create and initialize a new OSL shader for shader generation.
53-
virtual ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const;
53+
ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const override;
5454
};
5555

5656
namespace OSLNetwork

source/MaterialXGenOsl/OslShaderGenerator.cpp

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <MaterialXGenShader/ShaderStage.h>
1414
#include <MaterialXGenShader/TypeDesc.h>
1515

16-
1716
MATERIALX_NAMESPACE_BEGIN
1817

1918
const string OslShaderGenerator::TARGET = "genosl";
@@ -35,6 +34,12 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G
3534
ScopedFloatFormatting fmt(Value::FloatFormatFixed);
3635

3736
ShaderGraph& graph = shader->getGraph();
37+
38+
if (context.getOptions().oslConnectCiWrapper)
39+
{
40+
addSetCiTerminalNode(graph, element->getDocument(), context);
41+
}
42+
3843
ShaderStage& stage = shader->getStage(Stage::PIXEL);
3944

4045
emitLibraryIncludes(stage, context);
@@ -224,8 +229,7 @@ ShaderPtr OslShaderGenerator::createShader(const string& name, ElementPtr elemen
224229
const auto& outputSockets = graph->getOutputSockets();
225230
const auto* singleOutput = outputSockets.size() == 1 ? outputSockets[0] : NULL;
226231

227-
const bool isSurfaceShaderOutput = context.getOptions().oslImplicitSurfaceShaderConversion
228-
&& singleOutput && singleOutput->getType() == Type::SURFACESHADER;
232+
const bool isSurfaceShaderOutput = context.getOptions().oslImplicitSurfaceShaderConversion && singleOutput && singleOutput->getType() == Type::SURFACESHADER;
229233

230234
if (isSurfaceShaderOutput)
231235
{
@@ -404,10 +408,10 @@ void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage
404408
{
405409
static const std::unordered_map<TypeDesc, ShaderMetadata, TypeDesc::Hasher> UI_WIDGET_METADATA =
406410
{
407-
{ Type::FLOAT, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("number")) },
408-
{ Type::INTEGER, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("number")) },
409-
{ Type::FILENAME, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("filename")) },
410-
{ Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("checkBox")) }
411+
{ Type::FLOAT, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("number")) },
412+
{ Type::INTEGER, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("number")) },
413+
{ Type::FILENAME, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("filename")) },
414+
{ Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Type::STRING.createValueFromStrings("checkBox")) }
411415
};
412416

413417
static const std::set<TypeDesc> METADATA_TYPE_BLACKLIST =
@@ -466,6 +470,38 @@ void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage
466470
}
467471
}
468472

473+
474+
void OslShaderGenerator::addSetCiTerminalNode(ShaderGraph& graph, ConstDocumentPtr document, GenContext& context) const
475+
{
476+
string setCiNodeDefName = "ND_osl_set_ci";
477+
NodeDefPtr setCiNodeDef = document->getNodeDef(setCiNodeDefName);
478+
479+
std::unordered_map<TypeDesc, ValuePtr, TypeDesc::Hasher> outputModeMap;
480+
int index = 0;
481+
for (auto input : setCiNodeDef->getInputs())
482+
{
483+
string inputName = input->getName();
484+
if (stringStartsWith(inputName, "input_"))
485+
{
486+
TypeDesc inputType = _typeSystem->getType(input->getType());
487+
outputModeMap[inputType] = std::make_shared<TypedValue<int>>(index++);
488+
}
489+
}
490+
491+
for (auto output : graph.getOutputSockets())
492+
{
493+
auto outputType = output->getType();
494+
string typeName = outputType.getName();
495+
auto setCiNode = graph.inlineNodeBeforeOutput(output, "oslSetCi", setCiNodeDefName, "input_" + typeName, "out_ci", context);
496+
auto typeInput = setCiNode->getInput("output_mode");
497+
498+
auto outputModeValue = outputModeMap[outputType];
499+
500+
typeInput->setValue(outputModeValue);
501+
}
502+
}
503+
504+
469505
namespace OSL
470506
{
471507

0 commit comments

Comments
 (0)