From 653db65b3eacdff1c9342b258d5de738a7e92104 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 25 Mar 2021 20:06:39 +0300 Subject: [PATCH 01/50] buildmaster: version update to 2.0.28 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 7052024b0..a1f13025a 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "27") +set(HD_RPR_PATCH_VERSION "28") From 95c56292c8d02071dc1970e3e25832c4d3a18db0 Mon Sep 17 00:00:00 2001 From: bsavery Date: Fri, 2 Apr 2021 11:26:17 -0700 Subject: [PATCH 02/50] Update generateRenderSettingFiles.py (#452) --- .../python/generateRenderSettingFiles.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index c930c8952..e08d5cfd8 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -241,7 +241,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'settings': [ { 'name': 'enableDenoising', - 'ui_name': 'Enable Denoising', + 'ui_name': 'Enable AI Denoising', 'defaultValue': False, 'houdini': { 'custom_tags': [ @@ -283,7 +283,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'settings': [ { 'name': 'maxSamples', - 'ui_name': 'Max Pixel Samples', + 'ui_name': 'Max Samples', 'help': 'Maximum number of samples to render for each pixel.', 'defaultValue': 256, 'minValue': 1, @@ -299,7 +299,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'settings': [ { 'name': 'minAdaptiveSamples', - 'ui_name': 'Min Pixel Samples', + 'ui_name': 'Min Samples', 'help': 'Minimum number of samples to render for each pixel. After this, adaptive sampling will stop sampling pixels where noise is less than \'Variance Threshold\'.', 'defaultValue': 64, 'minValue': 1, @@ -307,7 +307,7 @@ def hidewhen_not_tahoe(render_setting_categories): }, { 'name': 'varianceThreshold', - 'ui_name': 'Variance Threshold', + 'ui_name': 'Noise Threshold', 'help': 'Cutoff for adaptive sampling. Once pixels are below this amount of noise, no more samples are added. Set to 0 for no cutoff.', 'defaultValue': 0.0, 'minValue': 0.0, @@ -373,18 +373,18 @@ def hidewhen_not_tahoe(render_setting_categories): 'name': 'raycastEpsilon', 'ui_name': 'Ray Cast Epsilon', 'help': 'Determines an offset used to move light rays away from the geometry for ray-surface intersection calculations.', - 'defaultValue': 2e-5, + 'defaultValue': 2e-3, 'minValue': 1e-6, 'maxValue': 1.0 }, { 'name': 'enableRadianceClamping', - 'ui_name': 'Enable Clamp Radiance', + 'ui_name': 'Clamp Fireflies', 'defaultValue': False, }, { 'name': 'radianceClamping', - 'ui_name': 'Clamp Radiance', + 'ui_name': 'Max Radiance', 'help': 'Limits the intensity, or the maximum brightness, of samples in the scene. Greater clamp radiance values produce more brightness.', 'defaultValue': 0.0, 'minValue': 0.0, @@ -439,7 +439,7 @@ def hidewhen_not_tahoe(render_setting_categories): }, { 'name': 'tonemapExposureTime', - 'ui_name': 'Tone Mapping Exposure Time', + 'ui_name': 'Film Exposure Time (sec)', 'help': 'Film exposure time', 'defaultValue': 0.125, 'minValue': 0.0, @@ -450,7 +450,7 @@ def hidewhen_not_tahoe(render_setting_categories): }, { 'name': 'tonemapSensitivity', - 'ui_name': 'Tone Mapping Sensitivity', + 'ui_name': 'Film Sensitivity', 'help': 'Luminance of the scene (in candela per m^2)', 'defaultValue': 1.0, 'minValue': 0.0, @@ -461,7 +461,7 @@ def hidewhen_not_tahoe(render_setting_categories): }, { 'name': 'tonemapFstop', - 'ui_name': 'Tone Mapping Fstop', + 'ui_name': 'Fstop', 'help': 'Aperture f-number', 'defaultValue': 1.0, 'minValue': 0.0, @@ -498,7 +498,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'settings': [ { 'name': 'enableBeautyMotionBlur', - 'ui_name': 'Enable Beaty Motion Blur', + 'ui_name': 'Enable Beauty Motion Blur', 'defaultValue': True, 'help': 'If disabled, only velocity AOV will store information about movement on the scene. Required for motion blur that is generated in post-processing.', 'houdini': { From f1c77821f4d92e9d3aceda5b7f4b31358bac2762 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Fri, 2 Apr 2021 21:29:37 +0300 Subject: [PATCH 03/50] buildmaster: version update to 2.0.29 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index a1f13025a..6a1d803cf 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "28") +set(HD_RPR_PATCH_VERSION "29") From 48b15684bb66dc780bf45edbe07167d7204cd4d8 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Tue, 6 Apr 2021 02:18:18 +0300 Subject: [PATCH 04/50] Mtlx: support tangent geomprop, improve logging (#454) PURPOSE Resolve https://amdrender.atlassian.net/browse/RPRVIEW-175 EFFECT OF CHANGE Added support of MaterialX tangent geomprop Improved MaterialX loader logging - more granular control over logging verbosity. --- deps/rprMtlxLoader/rprMtlxLoader.cpp | 192 +++++++++++++----------- deps/rprMtlxLoader/rprMtlxLoader.h | 11 +- pxr/imaging/rprUsd/materialRegistry.cpp | 12 +- 3 files changed, 125 insertions(+), 90 deletions(-) diff --git a/deps/rprMtlxLoader/rprMtlxLoader.cpp b/deps/rprMtlxLoader/rprMtlxLoader.cpp index 504bd6ff9..2e7857a4f 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.cpp +++ b/deps/rprMtlxLoader/rprMtlxLoader.cpp @@ -339,11 +339,10 @@ struct LoaderContext { static const int kGlobalLogDepth = -1; int logDepth = kGlobalLogDepth; LogScope logScope = LSGlobal; - bool logEnabled = true; - void Log(const char* fmt, ...); + RPRMtlxLoader::LogLevel logLevel; - void LogError(size_t line, const char* fmt, ...); + void Log(RPRMtlxLoader::LogLevel level, size_t line, const char* fmt, ...); struct ScopeGuard { LoaderContext* ctx; @@ -356,11 +355,16 @@ struct LoaderContext { ScopeGuard EnterScope(LogScope logScope, mx::Element const* scopeElement); std::string ResolveFile(std::string const& filename); - std::string FindFile(std::string const& filename); }; #define LOG_ERROR(ctx, fmt, ...) \ - (ctx)->LogError(__LINE__, fmt, ##__VA_ARGS__) + (ctx)->Log(RPRMtlxLoader::LogLevel::Error, __LINE__, fmt, ##__VA_ARGS__) + +#define LOG_WARNING(ctx, fmt, ...) \ + (ctx)->Log(RPRMtlxLoader::LogLevel::Warning, __LINE__, fmt, ##__VA_ARGS__) + +#define LOG(ctx, fmt, ...) \ + (ctx)->Log(RPRMtlxLoader::LogLevel::Info, __LINE__, fmt, ##__VA_ARGS__) //------------------------------------------------------------------------------ // Node declarations @@ -534,7 +538,7 @@ struct MtlxNodeGraphNode : public Node { for (auto& socket : *_sockets) { auto nodeIt = _nodeGraphNode->subNodes.find(socket.subNode->getName()); if (nodeIt != _nodeGraphNode->subNodes.end()) { - context->Log(" %s:%s\n", nodeIt->first.c_str(), socket.input->getName().c_str()); + LOG(context, " %s:%s", nodeIt->first.c_str(), socket.input->getName().c_str()); f(nodeIt->second.get(), socket.input.get()); } @@ -585,13 +589,13 @@ mx::OutputPtr GetOutput(mx::InterfaceElement const* interfaceElement, mx::PortEl if (interfaceElement->getType() == mx::MULTI_OUTPUT_TYPE_STRING) { auto& targetOutputName = portElement->getOutputString(); if (targetOutputName.empty()) { - LOG_ERROR(context, "invalid port element structure: output should be specified when connecting to multioutput element - port: %s, interface: %s\n", portElement->asString().c_str(), interfaceElement->asString().c_str()); + LOG_ERROR(context, "invalid port element structure: output should be specified when connecting to multioutput element - port: %s, interface: %s", portElement->asString().c_str(), interfaceElement->asString().c_str()); return nullptr; } auto output = interfaceElement->getOutput(targetOutputName); if (!output) { - LOG_ERROR(context, "invalid connection: cannot determine output - %s\n", portElement->asString().c_str()); + LOG_ERROR(context, "invalid connection: cannot determine output - %s", portElement->asString().c_str()); } return output; @@ -609,11 +613,20 @@ size_t GetHash(T const& value) { // Loader context implementation //------------------------------------------------------------------------------ -void LoaderContext::Log(const char* fmt, ...) { - if (!logEnabled) { +const char* const kLogLevelStr[int(RPRMtlxLoader::LogLevel::Info) + 1] = { + "", + "ERROR", + "WARNING", + "INFO", +}; + +void LoaderContext::Log(RPRMtlxLoader::LogLevel level, size_t line, const char* fmt, ...) { + if (level > logLevel) { return; } + printf("[MTLXLOADER %s] ", kLogLevelStr[int(level)]); + if (logScope != LSGlobal) { int padding = 0; if (logDepth > 0) { @@ -631,15 +644,10 @@ void LoaderContext::Log(const char* fmt, ...) { va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); -} - -void LoaderContext::LogError(size_t line, const char* fmt, ...) { - printf("RPRMtlxLoader error (%zu): ", line); - va_list ap; - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); + if (line) { + printf(" (%zu)\n", line); + } } LoaderContext::ScopeGuard::ScopeGuard(LoaderContext* ctx, LogScope logScope, mx::Element const* scopeElement) @@ -711,7 +719,7 @@ bool LoaderContext::ConnectToGlobalOutput(T* input, Node* node) { if (auto nodeGraph = mtlxDocument->getNodeGraph(nodeGraphName)) { if (auto nodeGraphOutput = nodeGraph->getOutput(outputName)) { if (auto freeStandingNodeGraphNode = GetFreeStandingNodeGraph(nodeGraph)) { - Log("Bindinput %s: %s:%s (nodegraph)\n", input->getName().c_str(), nodeGraphName.c_str(), outputName.c_str()); + LOG(this, "Bindinput %s: %s:%s (nodegraph)", input->getName().c_str(), nodeGraphName.c_str(), outputName.c_str()); return freeStandingNodeGraphNode->Connect(nodeGraphOutput->getName(), node, input, this) == RPR_SUCCESS; } @@ -727,7 +735,7 @@ bool LoaderContext::ConnectToGlobalOutput(T* input, Node* node) { if (auto mxtlGlobalNodeDef = mtlxGlobalNode->getNodeDef()) { if (auto mtlxGlobalNodeOutput = GetOutput(mxtlGlobalNodeDef.get(), globalOutput.get(), this)) { if (auto globalNode = GetGlobalNode(mtlxGlobalNode.get())) { - Log("Bindinput %s: %s (output)\n", input->getName().c_str(), outputName.c_str()); + LOG(this, "Bindinput %s: %s (output)", input->getName().c_str(), outputName.c_str()); return globalNode->Connect(mtlxGlobalNodeOutput->getName(), node, input, this) == RPR_SUCCESS; } @@ -749,56 +757,70 @@ Node* LoaderContext::GetGeomNode(mx::GeomPropDef* geomPropDef) { auto& geomProp = geomPropDef->getGeomProp(); auto& type = geomPropDef->getAttribute("type"); if (geomProp.empty() || type.empty()) { - LOG_ERROR(this, "Invalid geomPropDef: %s\n", geomPropDef->asString().c_str()); + LOG_ERROR(this, "Invalid geomPropDef: %s", geomPropDef->asString().c_str()); return nullptr; } - const auto kInvalidLookupValue = static_cast(-1); - rpr_material_node_lookup_value lookupValue = kInvalidLookupValue; + rpr_material_node apiHandle = nullptr; - if (geomProp == "texcoord") { - if (type != "vector2") { - LOG_ERROR(this, "Unexpected type for texcoord geomProp: %s\n", type.c_str()); - } - - auto& index = geomPropDef->getIndex(); - if (index.empty() || index == "0") { - lookupValue = RPR_MATERIAL_NODE_LOOKUP_UV; - } else if (index == "1") { - lookupValue = RPR_MATERIAL_NODE_LOOKUP_UV1; - } - } else if (geomProp == "normal") { - auto& space = geomPropDef->getSpace(); - if (space == "world") { - lookupValue = RPR_MATERIAL_NODE_LOOKUP_N; - } else { - LOG_ERROR(this, "Unsupported normal space: \"%s\"\n", space.c_str()); - } - } else if (geomProp == "position") { + if (geomProp == "tangent") { auto& space = geomPropDef->getSpace(); if (space == "world") { - lookupValue = RPR_MATERIAL_NODE_LOOKUP_P; + auto status = rprMaterialSystemCreateNode(rprMatSys, RPR_MATERIAL_NODE_MATX_TANGENT, &apiHandle); + if (!apiHandle) { + LOG_ERROR(this, "Failed to create matx tangent node: %d", status); + } } else { - lookupValue = RPR_MATERIAL_NODE_LOOKUP_P_LOCAL; + LOG_ERROR(this, "Unsupported tangent space: \"%s\"", space.c_str()); } - } - // TODO: handle tangent, bitangent, geomcolor, geompropvalue (primvar) + } else { + const auto kInvalidLookupValue = static_cast(-1); + rpr_material_node_lookup_value lookupValue = kInvalidLookupValue; - if (lookupValue != kInvalidLookupValue) { - rpr_material_node apiHandle; - auto status = rprMaterialSystemCreateNode(rprMatSys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &apiHandle); - if (apiHandle) { - rprMaterialNodeSetInputUByKey(apiHandle, RPR_MATERIAL_INPUT_VALUE, lookupValue); + if (geomProp == "texcoord") { + if (type != "vector2") { + LOG_ERROR(this, "Unexpected type for texcoord geomProp: %s", type.c_str()); + } - auto geomNodeIt = geomNodes.emplace(geomPropDef->getName(), std::make_unique(apiHandle, true)).first; - return geomNodeIt->second.get(); - } else { - LOG_ERROR(this, "Failed to create RPR_MATERIAL_NODE_INPUT_LOOKUP node: %d\n", status); - return nullptr; + auto& index = geomPropDef->getIndex(); + if (index.empty() || index == "0") { + lookupValue = RPR_MATERIAL_NODE_LOOKUP_UV; + } else if (index == "1") { + lookupValue = RPR_MATERIAL_NODE_LOOKUP_UV1; + } + } else if (geomProp == "normal") { + auto& space = geomPropDef->getSpace(); + if (space == "world") { + lookupValue = RPR_MATERIAL_NODE_LOOKUP_N; + } else { + LOG_ERROR(this, "Unsupported normal space: \"%s\"", space.c_str()); + } + } else if (geomProp == "position") { + auto& space = geomPropDef->getSpace(); + if (space == "world") { + lookupValue = RPR_MATERIAL_NODE_LOOKUP_P; + } else { + lookupValue = RPR_MATERIAL_NODE_LOOKUP_P_LOCAL; + } } + // TODO: handle bitangent, geomcolor, geompropvalue (primvar) + + if (lookupValue != kInvalidLookupValue) { + auto status = rprMaterialSystemCreateNode(rprMatSys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &apiHandle); + if (apiHandle) { + rprMaterialNodeSetInputUByKey(apiHandle, RPR_MATERIAL_INPUT_VALUE, lookupValue); + } else { + LOG_ERROR(this, "Failed to create RPR_MATERIAL_NODE_INPUT_LOOKUP node: %d", status); + } + } + } + + if (apiHandle) { + auto geomNodeIt = geomNodes.emplace(geomPropDef->getName(), std::make_unique(apiHandle, true)).first; + return geomNodeIt->second.get(); } - LOG_ERROR(this, "Unsupported geom node: %s\n", geomPropDef->asString().c_str()); + LOG_ERROR(this, "Unsupported geom node: %s", geomPropDef->asString().c_str()); return nullptr; } @@ -1167,7 +1189,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { rprNode = upstreamRprNode; return RPR_SUCCESS; } else { - context->Log("Unsupported surface input: %s\n", downstreamElement->getName().c_str()); + LOG(context, "Unsupported surface input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_UNSUPPORTED; } } @@ -1186,7 +1208,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { isOwningRprNode = false; return RPR_SUCCESS; } else { - context->Log("Unsupported displacement input: %s\n", downstreamElement->getName().c_str()); + LOG(context, "Unsupported displacement input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_UNSUPPORTED; } } @@ -1210,7 +1232,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { } return status; } else { - context->Log("Unsupported displacement input: %s\n", downstreamElement->getName().c_str()); + LOG(context, "Unsupported displacement input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_UNSUPPORTED; } } @@ -1304,7 +1326,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { // TODO: code generation required - context->Log("Unsupported node: %s (%s)\n", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str()); + LOG(context, "Unsupported node: %s (%s)", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str()); } } } @@ -1312,7 +1334,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { if (!rprNode && rprNodeMapping) { auto status = rprMaterialSystemCreateNode(context->rprMatSys, rprNodeMapping->id, &rprNode); if (status != RPR_SUCCESS) { - LOG_ERROR(context, "failed to create %s (%s) node: %d\n", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str(), status); + LOG_ERROR(context, "failed to create %s (%s) node: %d", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str(), status); return nullptr; } @@ -1379,12 +1401,12 @@ MtlxNodeGraphNode::MtlxNodeGraphNode( LoaderContext* context) : mtlxGraph(graph) { - context->Log("NodeGraph: %s\n", mtlxGraph->getName().c_str()); + LOG(context, "NodeGraph: %s", mtlxGraph->getName().c_str()); auto graphScope = context->EnterScope(LSGraph, mtlxGraph.get()); bool hasAnyOutputNode = false; for (auto& output : requiredOutputs) { - context->Log("Output: %s -> %s \n", output->getName().c_str(), output->getNodeName().c_str()); + LOG(context, "Output: %s -> %s ", output->getName().c_str(), output->getNodeName().c_str()); // An output of a node graph must have a `nodename` attribute // @@ -1392,7 +1414,7 @@ MtlxNodeGraphNode::MtlxNodeGraphNode( if (subNode) { hasAnyOutputNode = true; } else { - LOG_ERROR(context, "Failed to create node %s in %s\n", output->getNodeName().c_str(), mtlxGraph->getName().c_str()); + LOG_ERROR(context, "Failed to create node %s in %s", output->getNodeName().c_str(), mtlxGraph->getName().c_str()); } } @@ -1409,7 +1431,7 @@ Node* MtlxNodeGraphNode::GetSubNode(std::string const& nodename, LoaderContext* auto mtlxNode = mtlxGraph->getNode(nodename); if (!mtlxNode) { - LOG_ERROR(context, "No node with such name: %s\n", nodename.c_str()); + LOG_ERROR(context, "No node with such name: %s", nodename.c_str()); return nullptr; } @@ -1433,7 +1455,7 @@ Node* MtlxNodeGraphNode::GetSubNode(std::string const& nodename, LoaderContext* auto status = upstreamNode->Connect(outputName, downstreamNode, connection.downstreamInput.get(), context); if (status == RPR_SUCCESS) { - context->Log("Connected %s to %s\n", connection.upstreamNode->getName().c_str(), connection.downstreamNode->getName().c_str()); + LOG(context, "Connected %s to %s", connection.upstreamNode->getName().c_str(), connection.downstreamNode->getName().c_str()); } } @@ -1458,7 +1480,7 @@ Node* MtlxNodeGraphNode::_CreateSubNode( return subNodeIt->second.get(); } - context->Log("Node: %s (%s)\n", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str()); + LOG(context, "Node: %s (%s)", mtlxNode->getName().c_str(), mtlxNode->getCategory().c_str()); auto nodeScope = context->EnterScope(LSNode, mtlxNode.get()); auto nodeHandle = Node::Create(mtlxNode.get(), context); @@ -1471,7 +1493,7 @@ Node* MtlxNodeGraphNode::_CreateSubNode( auto nodeDef = mtlxNode->getNodeDef(); if (!nodeDef) { - LOG_ERROR(context, "Failed to get mtlxNode definition: %s\n", mtlxNode->asString().c_str()); + LOG_ERROR(context, "Failed to get mtlxNode definition: %s", mtlxNode->asString().c_str()); return node; } @@ -1489,7 +1511,7 @@ Node* MtlxNodeGraphNode::_CreateSubNode( continue; } - context->Log("%s %s\n", inputElement->getCategory().c_str(), inputElement->getName().c_str()); + LOG(context, "%s %s", inputElement->getCategory().c_str(), inputElement->getName().c_str()); auto inputScope = context->EnterScope(LSInput, inputElement.get()); // An element that provides a value for the current input @@ -1533,11 +1555,11 @@ Node* MtlxNodeGraphNode::_CreateSubNode( // auto& nodeName = input->getNodeName(); if (!nodeName.empty()) { - context->Log("nodename: %s\n", nodeName.c_str()); + LOG(context, "nodename: %s", nodeName.c_str()); auto mtlxUpstreamNode = mtlxGraph->getNode(nodeName); if (!mtlxUpstreamNode) { - LOG_ERROR(context, "Node \"%s\" cannot be found in \"%s\"\n", nodeName.c_str(), mtlxGraph->getName().c_str()); + LOG_ERROR(context, "Node \"%s\" cannot be found in \"%s\"", nodeName.c_str(), mtlxGraph->getName().c_str()); continue; } @@ -1582,7 +1604,7 @@ Node* MtlxNodeGraphNode::_CreateSubNode( status = geomNode->Connect(mx::EMPTY_STRING, node, inputElement.get(), context); } } else { - LOG_ERROR(context, "Unkown defaultgeomprop: %s\n", defaultGeomProp.c_str()); + LOG_ERROR(context, "Unkown defaultgeomprop: %s", defaultGeomProp.c_str()); } continue; @@ -1593,7 +1615,7 @@ Node* MtlxNodeGraphNode::_CreateSubNode( // auto& valueStr = valueElement->getValueString(); if (!valueStr.empty()) { - context->Log("%s\n", valueStr.c_str()); + LOG(context, "%s", valueStr.c_str()); status = node->SetInput(inputElement.get(), valueElement.get(), context); if (status == RPR_SUCCESS) { @@ -1658,7 +1680,7 @@ rpr_status MtlxNodeGraphNode::SetInput(mx::TypedElement* downstreamElement, mx:: return status; } - LOG_ERROR(context, "failed to set %s input for %s: no such interface socket\n", downstreamElement->getName().c_str(), mtlxGraph->getName().c_str()); + LOG_ERROR(context, "failed to set %s input for %s: no such interface socket", downstreamElement->getName().c_str(), mtlxGraph->getName().c_str()); return RPR_ERROR_INVALID_PARAMETER; } @@ -1676,7 +1698,7 @@ rpr_status MtlxNodeGraphNode::SetInput(mx::TypedElement* downstreamElement, mx:: return status; } - LOG_ERROR(context, "failed to set %s input for %s: no such interface socket\n", downstreamElement->getName().c_str(), mtlxGraph->getName().c_str()); + LOG_ERROR(context, "failed to set %s input for %s: no such interface socket", downstreamElement->getName().c_str(), mtlxGraph->getName().c_str()); return RPR_ERROR_INVALID_PARAMETER; } @@ -1774,10 +1796,10 @@ rpr_status RprNode::SetInput(mx::TypedElement* downstreamElement, rpr_material_n auto value = static_cast(mx::fromValueString(valueString)); return rprMaterialNodeSetInputFByKey(rprNode, downstreamRprId, value, value, value, 0.0f); } else { - LOG_ERROR(context, "failed to parse %s value: unsupported type - %s\n", valueString.c_str(), valueType.c_str()); + LOG_WARNING(context, "failed to parse %s value: unsupported type - %s", valueString.c_str(), valueType.c_str()); } } catch (mx::ExceptionTypeError& e) { - LOG_ERROR(context, "failed to parse %s value: %s\n", valueString.c_str(), e.what()); + LOG_ERROR(context, "failed to parse %s value: %s", valueString.c_str(), e.what()); } return RPR_ERROR_INVALID_PARAMETER; @@ -1810,7 +1832,7 @@ RprMappedNode::RprMappedNode(rpr_material_node node, Mtlx2Rpr::Node const* nodeM rpr_status RprMappedNode::SetInput(mx::TypedElement* downstreamElement, mx::Element* upstreamElement, rpr_material_node upstreamRprNode, LoaderContext* context) { auto inputIt = rprNodeMapping->inputs.find(downstreamElement->getName()); if (inputIt == rprNodeMapping->inputs.end()) { - LOG_ERROR(context, "unknown input: %s\n", downstreamElement->getName().c_str()); + LOG_ERROR(context, "unknown input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_INVALID_PARAMETER; } @@ -1841,7 +1863,7 @@ rpr_status RprMappedNode::SetInput(mx::TypedElement* downstreamElement, mx::Elem rpr_status RprMappedNode::SetInput(mx::TypedElement* downstreamElement, mx::ValueElement* valueElement, LoaderContext* context) { auto inputIt = rprNodeMapping->inputs.find(downstreamElement->getName()); if (inputIt == rprNodeMapping->inputs.end()) { - LOG_ERROR(context, "unknown input: %s\n", downstreamElement->getName().c_str()); + LOG_ERROR(context, "unknown input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_INVALID_PARAMETER; } @@ -1956,7 +1978,7 @@ rpr_status RprImageNode::SetInput(mx::TypedElement* downstreamElement, mx::Value } if (status != RPR_SUCCESS) { - LOG_ERROR(context, "Invalid input for image node %s (%s %s): unknown input or invalid type\n", + LOG_ERROR(context, "Invalid input for image node %s (%s %s): unknown input or invalid type", downstreamElement->getName().c_str(), value.c_str(), valueType.c_str()); } return status; @@ -2065,7 +2087,7 @@ rpr_status RprUberNode::SetInput(mx::TypedElement* downstreamElement, mx::ValueE if (status != RPR_SUCCESS && status != RPR_ERROR_UNSUPPORTED) { - LOG_ERROR(context, "Invalid input for uber node %s (%s %s): unknown input or invalid type\n", + LOG_ERROR(context, "Invalid input for uber node %s (%s %s): unknown input or invalid type", downstreamElement->getName().c_str(), value.c_str(), valueType.c_str()); } return status; @@ -2371,7 +2393,7 @@ RPRMtlxLoader::Result RPRMtlxLoader::Load( rpr_material_system rprMatSys) { LoaderContext ctx = {}; - ctx.logEnabled = _loggingEnabled; + ctx.logLevel = _logLevel; ctx.mtlxDocument = mtlxDocument; ctx.rprMatSys = rprMatSys; ctx.searchPath = searchPath; @@ -2515,7 +2537,7 @@ RPRMtlxLoader::Result RPRMtlxLoader::Load( } if (renderableElements.IsEmpty()) { - LOG_ERROR(&ctx, "No renderable elements in %s\n", mtlxDocument->getSourceUri().c_str()); + LOG_ERROR(&ctx, "No renderable elements in %s", mtlxDocument->getSourceUri().c_str()); return {}; } @@ -2575,7 +2597,7 @@ RPRMtlxLoader::Result RPRMtlxLoader::Load( if (!valueStr.empty()) { auto& type = bindInput->getType(); - ctx.Log("Bindinput %s: %s (%s)\n", bindInput->getName().c_str(), valueStr.c_str(), type.c_str()); + LOG(&ctx, "Bindinput %s: %s (%s)", bindInput->getName().c_str(), valueStr.c_str(), type.c_str()); node->SetInput(bindInput.get(), bindInput.get(), &ctx); } diff --git a/deps/rprMtlxLoader/rprMtlxLoader.h b/deps/rprMtlxLoader/rprMtlxLoader.h index c4a09e2ec..8e0359323 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.h +++ b/deps/rprMtlxLoader/rprMtlxLoader.h @@ -13,7 +13,14 @@ class RPRMtlxLoader { void SetupStdlib(MaterialX::FilePathVec const& libraryNames, MaterialX::FileSearchPath const& searchPath); MaterialX::ConstDocumentPtr GetStdlib() const { return _stdlib; } - void SetLogging(bool enable) { _loggingEnabled = enable; } + enum class LogLevel : int { + None, + Error, + Warning, + Info, + }; + void SetLogging(LogLevel level) { _logLevel = level; } + void SetSceneDistanceUnit(std::string const& unit) { _sceneDistanceUnit = unit; } enum OutputType { @@ -115,7 +122,7 @@ class RPRMtlxLoader { private: MaterialX::DocumentPtr _stdlib; MaterialX::FileSearchPath _stdSearchPath; - bool _loggingEnabled = false; + LogLevel _logLevel = LogLevel::Error; std::string _sceneDistanceUnit = "meter"; }; diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 0a85b5520..7e1a7b50b 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -41,8 +41,8 @@ TF_DEFINE_ENV_SETTING(RPRUSD_MATERIAL_NETWORK_SELECTOR, "rpr", "Material network selector to be used in hdRpr"); TF_DEFINE_ENV_SETTING(RPRUSD_USE_RPRMTLXLOADER, true, "Whether to use RPRMtlxLoader or rprLoadMateriaX"); -TF_DEFINE_ENV_SETTING(RPRUSD_RPRMTLXLOADER_ENABLE_LOGGING, false, - "Enable logging of RPRMtlxLoader"); +TF_DEFINE_ENV_SETTING(RPRUSD_RPRMTLXLOADER_LOG_LEVEL, int(RPRMtlxLoader::LogLevel::Error), + "Set logging level of RPRMtlxLoader"); RprUsdMaterialRegistry::RprUsdMaterialRegistry() : m_materialNetworkSelector(TfGetEnvSetting(RPRUSD_MATERIAL_NETWORK_SELECTOR)) { @@ -67,7 +67,13 @@ RprUsdMaterialRegistry::GetRegisteredNodes() { MaterialX::FileSearchPath searchPath = RPR; m_mtlxLoader = std::make_unique(); m_mtlxLoader->SetupStdlib(libraryNames, searchPath); - m_mtlxLoader->SetLogging(TfGetEnvSetting(RPRUSD_RPRMTLXLOADER_ENABLE_LOGGING)); + + auto logLevel = RPRMtlxLoader::LogLevel(TfGetEnvSetting(RPRUSD_RPRMTLXLOADER_LOG_LEVEL)); + if (logLevel < RPRMtlxLoader::LogLevel::None || + logLevel > RPRMtlxLoader::LogLevel::Info) { + logLevel = RPRMtlxLoader::LogLevel::Error; + } + m_mtlxLoader->SetLogging(logLevel); } auto rprMaterialsPath = TfAbsPath(TfNormPath(RPR + "/materials")); From c009c0ec10d46021b85e6f26fc271dbed75bcd25 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 6 Apr 2021 02:29:52 +0300 Subject: [PATCH 05/50] buildmaster: version update to 2.0.30 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 6a1d803cf..8841ecdbc 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "29") +set(HD_RPR_PATCH_VERSION "30") From 163412ef5faf5c6d83a05902cbb0e2617f0543d4 Mon Sep 17 00:00:00 2001 From: Aleksandr Gurov Date: Thu, 8 Apr 2021 16:45:22 +0300 Subject: [PATCH 06/50] Cache path override and valid render delegate destruction (#455) PURPOSE Merge some features and fixes from development branch EFFECT OF CHANGE Some improvements in for overall stability EFFECT OF CHANGE Integrated RPR Material Library in Houdini (preview version, feedback is welcome). Find a new button in the RPR menu (on the "File Edit View" toolbar) - "Import Material". --- cmake/defaults/Options.cmake | 5 ++- deps/CMakeLists.txt | 8 +++- .../python/generateRenderSettingFiles.py | 6 +++ pxr/imaging/plugin/hdRpr/renderDelegate.cpp | 6 +++ pxr/imaging/rprUsd/config.cpp | 37 +++++++++++++++++++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/cmake/defaults/Options.cmake b/cmake/defaults/Options.cmake index 4bf39b6f2..0cd79bb5c 100644 --- a/cmake/defaults/Options.cmake +++ b/cmake/defaults/Options.cmake @@ -77,4 +77,7 @@ set(PXR_LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX} ) option(BUILD_SHARED_LIBS "Build shared libraries." ON) -option(PXR_BUILD_MONOLITHIC "Build a monolithic library." OFF) \ No newline at end of file +option(PXR_BUILD_MONOLITHIC "Build a monolithic library." OFF) + +option(MATERIALX_BUILD_PYTHON "Build the MaterialX Python package from C++ bindings. Requires Python 2.7 or greater." OFF) +option(MATERIALX_INSTALL_PYTHON "Install the MaterialX Python package as a third-party library when the install target is built." OFF) \ No newline at end of file diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 1e14b577f..c355963e0 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -5,12 +5,16 @@ if(NOT MaterialX_FOUND) # If MaterialX was not explicitly provided, use the one from a submodule set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(MATERIALX_PYTHON_LTO OFF) - set(MATERIALX_INSTALL_PYTHON OFF) set(MATERIALX_BUILD_RENDER OFF) set(MATERIALX_BUILD_GEN_GLSL OFF) set(MATERIALX_BUILD_GEN_OSL OFF) set(MATERIALX_BUILD_TESTS OFF) - add_subdirectory(MaterialX EXCLUDE_FROM_ALL) # EXCLUDE_FROM_ALL allows us to skip installation of mtlx static libraries + + if(MATERIALX_BUILD_PYTHON AND MATERIALX_INSTALL_PYTHON) + add_subdirectory(MaterialX) + else() + add_subdirectory(MaterialX EXCLUDE_FROM_ALL) # EXCLUDE_FROM_ALL allows us to skip installation of mtlx static libraries + endif() install( FILES diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index e08d5cfd8..f53df96c9 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -619,6 +619,8 @@ class HdRprConfig {{ void CleanDirtyFlag(ChangeTracker dirtyFlag); void ResetDirty(); + void ResetRenderSettingsVersion(); + private: HdRprConfig() = default; @@ -732,6 +734,10 @@ class HdRprConfig {{ m_dirtyFlags = Clean; }} +void HdRprConfig::ResetRenderSettingsVersion() {{ + m_lastRenderSettingsVersion = -1; +}} + HdRprConfig::PrefData::PrefData() {{ SetDefault(); }} diff --git a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp index 8d9a02aa3..f6c260080 100644 --- a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp +++ b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp @@ -189,6 +189,12 @@ HdRprDelegate::HdRprDelegate(HdRenderSettingsMap const& renderSettings) { } HdRprDelegate::~HdRprDelegate() { + // Render settings version reset is required for valid recreation of HdRprDelgate + // Config singleton persists in memory after delegate destruction, therefore version must be invalidated + HdRprConfig* config; + auto configInstanceLock = HdRprConfig::GetInstance(&config); + config->ResetRenderSettingsVersion(); + g_rprApi = nullptr; } diff --git a/pxr/imaging/rprUsd/config.cpp b/pxr/imaging/rprUsd/config.cpp index 4f6e6cab9..8e38cea17 100644 --- a/pxr/imaging/rprUsd/config.cpp +++ b/pxr/imaging/rprUsd/config.cpp @@ -3,6 +3,7 @@ #include "pxr/base/arch/fileSystem.h" #include "pxr/base/tf/tf.h" #include "pxr/base/tf/instantiateSingleton.h" +#include "pxr/base/tf/envSetting.h" #include using json = nlohmann::json; @@ -19,6 +20,9 @@ using json = nlohmann::json; PXR_NAMESPACE_OPEN_SCOPE +TF_DEFINE_ENV_SETTING(HDRPR_CACHE_PATH_OVERRIDE, "", + "Set this to override shaders cache path"); + namespace { bool ArchCreateDirectory(const char* path) { @@ -29,6 +33,22 @@ bool ArchCreateDirectory(const char* path) { #endif } +bool ArchDirectoryExists(const char* path) { +#ifdef WIN32 + DWORD ftyp = GetFileAttributesA(path); + if (ftyp == INVALID_FILE_ATTRIBUTES) + return false; //something is wrong with your path! + + if (ftyp & FILE_ATTRIBUTE_DIRECTORY) + return true; // this is a directory! + + return false; // this is not a directory! +#else + throw std::runtime_error("ArchDirectoryExists not implemented for this platform"); + return false; +#endif +} + std::string GetAppDataPath() { #ifdef WIN32 char appDataPath[MAX_PATH]; @@ -60,6 +80,23 @@ std::string GetAppDataPath() { } std::string GetDefaultCacheDir(const char* cacheType) { + // Return HDRPR_CACHE_PATH_OVERRIDE if provided + auto overriddenCacheDir = TfGetEnvSetting(HDRPR_CACHE_PATH_OVERRIDE); + if (!overriddenCacheDir.empty()) { + overriddenCacheDir = overriddenCacheDir + ARCH_PATH_SEP + cacheType; + + bool directoryExists = ArchDirectoryExists(overriddenCacheDir.c_str()); + if (!directoryExists) { + bool succeeded = ArchCreateDirectory(overriddenCacheDir.c_str()); + if (!succeeded) + { + TF_RUNTIME_ERROR("Can't create shader cache directory at: %s", overriddenCacheDir.c_str()); + } + } + + return overriddenCacheDir; + } + auto cacheDir = ArchGetEnv("RPR"); if (cacheDir.empty()) { // Fallback to AppData From f42bcc8c4271cc0028e5d9bc7c353623a82e9c17 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 8 Apr 2021 16:59:53 +0300 Subject: [PATCH 07/50] buildmaster: version update to 2.0.31 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 8841ecdbc..4e9e7f012 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "30") +set(HD_RPR_PATCH_VERSION "31") From 17a1ace14c636ce6e6d976fa8f8099182ba4ef75 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 12 Apr 2021 01:06:07 +0300 Subject: [PATCH 08/50] Improve MaterialX loader (#456) * Add support for rpr_emissive node * Support scale for displacement * Support viewdirection node * Fix the mix node to support surfaceshader inputs * Instead of RPR_MATERIAL_NODE_MATX_CONVERT use a custom-implemented node (In the future this node should account for all possible conversions, right now it always pass input through unchanged) --- deps/rprMtlxLoader/rprMtlxLoader.cpp | 202 ++++++++++++++------------- 1 file changed, 108 insertions(+), 94 deletions(-) diff --git a/deps/rprMtlxLoader/rprMtlxLoader.cpp b/deps/rprMtlxLoader/rprMtlxLoader.cpp index 2e7857a4f..105fbb801 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.cpp +++ b/deps/rprMtlxLoader/rprMtlxLoader.cpp @@ -164,11 +164,6 @@ struct Mtlx2Rpr { {"lumacoeffs", RPR_MATERIAL_INPUT_LUMACOEFF}, } }; - nodes["convert"] = { - RPR_MATERIAL_NODE_MATX_CONVERT, { - {"in", RPR_MATERIAL_INPUT_0}, - } - }; nodes["rotate3d"] = { RPR_MATERIAL_NODE_MATX_ROTATE3D, { {"in", RPR_MATERIAL_INPUT_0}, @@ -208,6 +203,12 @@ struct Mtlx2Rpr { }; nodes["position"] = {RPR_MATERIAL_NODE_MATX_POSITION, {}}; + nodes["rpr_emissive"] = { + RPR_MATERIAL_NODE_EMISSIVE, { + {"color", RPR_MATERIAL_INPUT_COLOR} + } + }; + auto addArithmeticNode = [this](const char* name, rpr_material_node_arithmetic_operation op, int numArgs) { auto& mapping = nodes[name]; mapping.id = RPR_MATERIAL_NODE_ARITHMETIC; @@ -421,6 +422,88 @@ struct RprNode : public Node { size_t MoveRprApiHandles(rpr_material_node* dst) override; }; +// The passthrough node transfers input unaltered +// +struct PassthroughNode : public RprNode { + std::string inputName; + PassthroughNode(std::string inputName) : RprNode(nullptr, false), inputName(std::move(inputName)) {} + ~PassthroughNode() override = default; + + rpr_status SetInput(mx::TypedElement* downstreamElement, mx::Element* upstreamElement, rpr_material_node upstreamRprNode, LoaderContext* context) override { + if (downstreamElement->getName() == inputName) { + rprNode = upstreamRprNode; + isOwningRprNode = false; + return RPR_SUCCESS; + } else { + LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); + return RPR_ERROR_UNSUPPORTED; + } + } + + rpr_status SetInput(mx::TypedElement* downstreamElement, mx::ValueElement* upstreamValueElement, LoaderContext* context) override { + if (downstreamElement->getName() == inputName) { + if (rprNode && isOwningRprNode) { + rprObjectDelete(rprNode); + } + + rprNode = nullptr; + auto status = rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_CONSTANT_TEXTURE, &rprNode); + if (status == RPR_SUCCESS) { + status = RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_VALUE, upstreamValueElement, context); + if (status == RPR_SUCCESS) { + isOwningRprNode = true; + } else { + rprObjectDelete(rprNode); + rprNode = nullptr; + } + } + return status; + } else { + LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); + return RPR_ERROR_UNSUPPORTED; + } + } +}; + +struct DisplacementNode : public RprNode { + DisplacementNode(LoaderContext* context) : RprNode(nullptr, true) { + rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_ARITHMETIC, &rprNode); + rprMaterialNodeSetInputUByKey(rprNode, RPR_MATERIAL_INPUT_OP, RPR_MATERIAL_NODE_OP_MUL); + } + ~DisplacementNode() override = default; + + rpr_status SetInput(mx::TypedElement* downstreamElement, mx::Element* upstreamElement, rpr_material_node upstreamRprNode, LoaderContext* context) override { + if (downstreamElement->getName() == "displacement") { + if (downstreamElement->getType() != "float") { + LOG_ERROR(context, "Only scalar displacement is supported"); + return RPR_ERROR_UNSUPPORTED; + } + + return rprMaterialNodeSetInputNByKey(rprNode, RPR_MATERIAL_INPUT_COLOR0, upstreamRprNode); + } else if (downstreamElement->getName() == "scale") { + return rprMaterialNodeSetInputNByKey(rprNode, RPR_MATERIAL_INPUT_COLOR1, upstreamRprNode); + } else { + LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); + return RPR_ERROR_UNSUPPORTED; + } + } + rpr_status SetInput(mx::TypedElement* downstreamElement, mx::ValueElement* upstreamValueElement, LoaderContext* context) override { + if (downstreamElement->getName() == "displacement") { + if (downstreamElement->getType() != "float") { + LOG_ERROR(context, "Only scalar displacement is supported"); + return RPR_ERROR_UNSUPPORTED; + } + + return RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_COLOR0, upstreamValueElement, context); + } else if (downstreamElement->getName() == "scale") { + return RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_COLOR1, upstreamValueElement, context); + } else { + LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); + return RPR_ERROR_UNSUPPORTED; + } + } +}; + /// The node that can be mapped (fully or partially) to MaterialX standard node /// struct RprMappedNode : public RprNode { @@ -523,7 +606,7 @@ struct MtlxNodeGraphNode : public Node { mx::NodePtr downstreamNode; mx::TypedElementPtr downstreamInput; }; - Node* _CreateSubNode(mx::NodePtr const& mtlxNode, std::vector* pendingConnections, LoaderContext* context); + Node* _CreateSubNode(mx::NodePtr const& mtlxNode, LoaderContext* context); struct InterfaceSocket { mx::NodePtr subNode; @@ -658,7 +741,7 @@ LoaderContext::ScopeGuard::ScopeGuard(LoaderContext* ctx, LogScope logScope, mx: ctx->logScope = logScope; if (logScope == LSGlobal) { ctx->logDepth = kGlobalLogDepth; - } else if (logScope == LSNested) { + } else if (logScope == LSNested || logScope == LSNode) { ctx->logDepth++; } } @@ -1197,54 +1280,18 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { return std::make_unique(); } else if (mtlxNode->getCategory() == "displacement") { - // The displacement node is passthrough node - it transfers input unaltered - // - struct DisplacementNode : public RprNode { - DisplacementNode() : RprNode(nullptr, false) {} - - rpr_status SetInput(mx::TypedElement* downstreamElement, mx::Element* upstreamElement, rpr_material_node upstreamRprNode, LoaderContext* context) override { - if (downstreamElement->getName() == "displacement") { - rprNode = upstreamRprNode; - isOwningRprNode = false; - return RPR_SUCCESS; - } else { - LOG(context, "Unsupported displacement input: %s", downstreamElement->getName().c_str()); - return RPR_ERROR_UNSUPPORTED; - } - } - - rpr_status SetInput(mx::TypedElement* downstreamElement, mx::ValueElement* upstreamValueElement, LoaderContext* context) override { - if (downstreamElement->getName() == "displacement") { - if (rprNode && isOwningRprNode) { - rprObjectDelete(rprNode); - } - - rprNode = nullptr; - auto status = rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_CONSTANT_TEXTURE, &rprNode); - if (status == RPR_SUCCESS) { - status = RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_VALUE, upstreamValueElement, context); - if (status == RPR_SUCCESS) { - isOwningRprNode = true; - } else { - rprObjectDelete(rprNode); - rprNode = nullptr; - } - } - return status; - } else { - LOG(context, "Unsupported displacement input: %s", downstreamElement->getName().c_str()); - return RPR_ERROR_UNSUPPORTED; - } - } - }; - - return std::make_unique(); + return std::make_unique(context); + } else if (mtlxNode->getCategory() == "convert") { + return std::make_unique("in"); } else if (mtlxNode->getCategory() == "texcoord") { rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &rprNode); rprMaterialNodeSetInputUByKey(rprNode, RPR_MATERIAL_INPUT_VALUE, RPR_MATERIAL_NODE_LOOKUP_UV); } else if (mtlxNode->getCategory() == "normal") { rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &rprNode); rprMaterialNodeSetInputUByKey(rprNode, RPR_MATERIAL_INPUT_VALUE, RPR_MATERIAL_NODE_LOOKUP_N); + } else if (mtlxNode->getCategory() == "viewdirection") { + rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &rprNode); + rprMaterialNodeSetInputUByKey(rprNode, RPR_MATERIAL_INPUT_VALUE, RPR_MATERIAL_NODE_LOOKUP_INVEC); } else if (mtlxNode->getCategory() == "sqrt") { rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_ARITHMETIC, &rprNode); rprMaterialNodeSetInputUByKey(rprNode, RPR_MATERIAL_INPUT_OP, RPR_MATERIAL_NODE_OP_POW); @@ -1295,7 +1342,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { } else { // Some of the materialX standard nodes map to RPR differently depending on the node return type // - if (mtlxNode->getCategory() == "mix" && mtlxNode->getType() == "BSDF") { + if (mtlxNode->getCategory() == "mix" && (mtlxNode->getType() == "BSDF" || mtlxNode->getType() == "surfaceshader")) { // In RPR, mixing of two BSDFs can be done with RPR_MATERIAL_NODE_BLEND // static Mtlx2Rpr::Node bsdfMix = { @@ -1435,41 +1482,11 @@ Node* MtlxNodeGraphNode::GetSubNode(std::string const& nodename, LoaderContext* return nullptr; } - // To avoid recursion, we postpone the connection of nodes until the whole subgraph is built - // - std::vector pendingConnections; - pendingConnections.emplace_back(); - pendingConnections.back().downstreamNode = mtlxNode; - - Node* retNode = nullptr; - - while (!pendingConnections.empty()) { - auto connection = std::move(pendingConnections.back()); - pendingConnections.pop_back(); - - Node* downstreamNode = _CreateSubNode(connection.downstreamNode, &pendingConnections, context); - Node* upstreamNode = _CreateSubNode(connection.upstreamNode, &pendingConnections, context); - - if (downstreamNode && upstreamNode) { - auto& outputName = connection.upstreamNodeOutput ? connection.upstreamNodeOutput->getName() : mx::EMPTY_STRING; - auto status = upstreamNode->Connect(outputName, downstreamNode, connection.downstreamInput.get(), context); - - if (status == RPR_SUCCESS) { - LOG(context, "Connected %s to %s", connection.upstreamNode->getName().c_str(), connection.downstreamNode->getName().c_str()); - } - } - - if (connection.downstreamNode == mtlxNode) { - retNode = downstreamNode; - } - } - - return retNode; + return _CreateSubNode(mtlxNode, context); } Node* MtlxNodeGraphNode::_CreateSubNode( mx::NodePtr const& mtlxNode, - std::vector* pendingConnections, LoaderContext* context) { if (!mtlxNode) { return nullptr; @@ -1568,20 +1585,17 @@ Node* MtlxNodeGraphNode::_CreateSubNode( continue; } - // If upstream node is already created, connect output of upstream node to input of downstream node - // - auto upstreamNodeIt = subNodes.find(mtlxUpstreamNode->getName()); - if (upstreamNodeIt != subNodes.end()) { - status = upstreamNodeIt->second->Connect(mtlxUpstreamNodeOutput->getName(), node, inputElement.get(), context); + Node* upstreamNode = _CreateSubNode(mtlxUpstreamNode, context); + if (upstreamNode) { + auto& outputName = mtlxUpstreamNodeOutput ? mtlxUpstreamNodeOutput->getName() : mx::EMPTY_STRING; + auto status = upstreamNode->Connect(outputName, node, inputElement.get(), context); + + if (status == RPR_SUCCESS) { + LOG(context, "Connected %s to %s", mtlxUpstreamNode->getName().c_str(), mtlxNode->getName().c_str()); + } } else { - // Otherwise, postpone the connection process until the upstream node is created - // - pendingConnections->emplace_back(); - auto& pendingConnection = pendingConnections->back(); - pendingConnection.downstreamNode = mtlxNode; - pendingConnection.downstreamInput = std::move(input); - pendingConnection.upstreamNode = std::move(mtlxUpstreamNode); - pendingConnection.upstreamNodeOutput = std::move(mtlxUpstreamNodeOutput); + LOG(context, "Failed to connect %s to %s", mtlxUpstreamNode->getName().c_str(), mtlxNode->getName().c_str()); + status = RPR_ERROR_INVALID_OBJECT; } if (status == RPR_SUCCESS) { From d6df2ec3b8e44d5a51168bc4741c24310e0f93c1 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 12 Apr 2021 01:08:06 +0300 Subject: [PATCH 09/50] Expose environment light background override (#457) --- pxr/imaging/plugin/hdRpr/domeLight.cpp | 10 +++- pxr/imaging/plugin/hdRpr/rprApi.cpp | 64 ++++++++++++++++++-------- pxr/imaging/plugin/hdRpr/rprApi.h | 4 +- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/domeLight.cpp b/pxr/imaging/plugin/hdRpr/domeLight.cpp index a57bcd31a..26dd1ba69 100644 --- a/pxr/imaging/plugin/hdRpr/domeLight.cpp +++ b/pxr/imaging/plugin/hdRpr/domeLight.cpp @@ -26,6 +26,10 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE +TF_DEFINE_PRIVATE_TOKENS(_tokens, + ((backgroundOverride, "rpr:backgroundOverride")) +); + static void removeFirstSlash(std::string& string) { // Don't need this for *nix/Mac #ifdef _WIN32 @@ -71,6 +75,8 @@ void HdRprDomeLight::Sync(HdSceneDelegate* sceneDelegate, return; } + VtValue const& backgroundOverride = sceneDelegate->GetLightParamValue(id, _tokens->backgroundOverride); + float intensity = sceneDelegate->GetLightParamValue(id, HdLightTokens->intensity).Get(); float exposure = sceneDelegate->GetLightParamValue(id, HdLightTokens->exposure).Get(); float computedIntensity = computeLightIntensity(intensity, exposure); @@ -100,9 +106,9 @@ void HdRprDomeLight::Sync(HdSceneDelegate* sceneDelegate, color[2] *= temperatureColor[2]; } - m_rprLight = rprApi->CreateEnvironmentLight(color, computedIntensity); + m_rprLight = rprApi->CreateEnvironmentLight(color, computedIntensity, backgroundOverride); } else { - m_rprLight = rprApi->CreateEnvironmentLight(texturePath, computedIntensity); + m_rprLight = rprApi->CreateEnvironmentLight(texturePath, computedIntensity, backgroundOverride); } if (m_rprLight) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 1e1489039..235a067fd 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -242,6 +242,9 @@ struct HdRprApiEnvironmentLight { std::unique_ptr light; std::unique_ptr image; + std::unique_ptr backgroundOverrideLight; + std::unique_ptr backgroundOverrideImage; + enum { kDetached, kAttachedAsLight, @@ -752,7 +755,7 @@ class HdRprApiImpl { } } - HdRprApiEnvironmentLight* CreateEnvironmentLight(std::unique_ptr&& image, float intensity) { + HdRprApiEnvironmentLight* CreateEnvironmentLight(std::unique_ptr&& image, float intensity, VtValue const& backgroundOverride) { // XXX (RPR): default environment light should be removed before creating a new one - RPR limitation RemoveDefaultLight(); @@ -785,6 +788,20 @@ class HdRprApiImpl { return nullptr; } + if (backgroundOverride.IsHolding()) { + GfVec3f const& backgroundOverrideColor = backgroundOverride.UncheckedGet(); + envLight->backgroundOverrideLight.reset(m_rprContext->CreateEnvironmentLight(&status)); + envLight->backgroundOverrideImage = CreateConstantColorImage(backgroundOverrideColor.data()); + + if (!envLight->backgroundOverrideLight || + !envLight->backgroundOverrideImage || + RPR_ERROR_CHECK(envLight->backgroundOverrideLight->SetImage(envLight->backgroundOverrideImage->GetRootImage()), "Failed to set background override env light image", m_rprContext.get()) || + RPR_ERROR_CHECK(envLight->light->SetEnvironmentLightOverride(RPR_ENVIRONMENT_LIGHT_OVERRIDE_BACKGROUND, envLight->backgroundOverrideLight.get()), "Failed to set env light background override")) { + envLight->backgroundOverrideLight = nullptr; + envLight->backgroundOverrideImage = nullptr; + } + } + m_dirtyFlags |= ChangeTracker::DirtyScene; m_numLights++; return envLight; @@ -814,7 +831,7 @@ class HdRprApiImpl { } } - HdRprApiEnvironmentLight* CreateEnvironmentLight(const std::string& path, float intensity) { + HdRprApiEnvironmentLight* CreateEnvironmentLight(const std::string& path, float intensity, VtValue const& backgroundOverride) { if (!m_rprContext || path.empty()) { return nullptr; } @@ -826,29 +843,22 @@ class HdRprApiImpl { return nullptr; } - return CreateEnvironmentLight(std::move(image), intensity); + return CreateEnvironmentLight(std::move(image), intensity, backgroundOverride); } - HdRprApiEnvironmentLight* CreateEnvironmentLight(GfVec3f color, float intensity) { + HdRprApiEnvironmentLight* CreateEnvironmentLight(GfVec3f color, float intensity, VtValue const& backgroundOverride) { if (!m_rprContext) { return nullptr; } - std::array backgroundColor = {color[0], color[1], color[2]}; - rpr_image_format format = {3, RPR_COMPONENT_TYPE_FLOAT32}; - rpr_uint imageSize = m_rprContextMetadata.pluginType == kPluginHybrid ? 64 : 1; - std::vector> imageData(imageSize * imageSize, backgroundColor); - LockGuard rprLock(m_rprContext->GetMutex()); - rpr::Status status; - auto image = std::unique_ptr(RprUsdCoreImage::Create(m_rprContext.get(), imageSize, imageSize, format, imageData.data(), &status)); - if (!image) { - RPR_ERROR_CHECK(status, "Failed to create image", m_rprContext.get()); + auto backgroundImage = CreateConstantColorImage(color.data()); + if (!backgroundImage) { return nullptr; } - return CreateEnvironmentLight(std::move(image), intensity); + return CreateEnvironmentLight(std::move(backgroundImage), intensity, backgroundOverride); } void SetTransform(rpr::SceneObject* object, GfMatrix4f const& transform) { @@ -2990,7 +3000,7 @@ Don't show this message again? void AddDefaultLight() { if (!m_defaultLightObject) { const GfVec3f k_defaultLightColor(0.5f, 0.5f, 0.5f); - m_defaultLightObject = CreateEnvironmentLight(k_defaultLightColor, 1.f); + m_defaultLightObject = CreateEnvironmentLight(k_defaultLightColor, 1.f, VtValue()); if (RprUsdIsLeakCheckEnabled()) { m_defaultLightObject->light->SetName("defaultLight"); @@ -3012,6 +3022,22 @@ Don't show this message again? } } + std::unique_ptr CreateConstantColorImage(float const* color) { + std::array colorArray = {color[0], color[1], color[2]}; + rpr_image_format format = {3, RPR_COMPONENT_TYPE_FLOAT32}; + rpr_uint imageSize = m_rprContextMetadata.pluginType == kPluginHybrid ? 64 : 1; + std::vector> imageData(imageSize * imageSize, colorArray); + + rpr::Status status; + auto image = std::unique_ptr(RprUsdCoreImage::Create(m_rprContext.get(), imageSize, imageSize, format, imageData.data(), &status)); + if (!image) { + RPR_ERROR_CHECK(status, "Failed to create const color image", m_rprContext.get()); + return nullptr; + } + + return image; + } + void SplitPolygons(const VtIntArray& indexes, const VtIntArray& vpf, VtIntArray& out_newIndexes, VtIntArray& out_newVpf) { out_newIndexes.clear(); out_newVpf.clear(); @@ -3684,14 +3710,14 @@ rpr::Shape* HdRprApi::CreateMeshInstance(rpr::Shape* prototypeMesh) { return m_impl->CreateMeshInstance(prototypeMesh); } -HdRprApiEnvironmentLight* HdRprApi::CreateEnvironmentLight(GfVec3f color, float intensity) { +HdRprApiEnvironmentLight* HdRprApi::CreateEnvironmentLight(GfVec3f color, float intensity, VtValue const& backgroundOverride) { m_impl->InitIfNeeded(); - return m_impl->CreateEnvironmentLight(color, intensity); + return m_impl->CreateEnvironmentLight(color, intensity, backgroundOverride); } -HdRprApiEnvironmentLight* HdRprApi::CreateEnvironmentLight(const std::string& prthTotexture, float intensity) { +HdRprApiEnvironmentLight* HdRprApi::CreateEnvironmentLight(const std::string& prthTotexture, float intensity, VtValue const& backgroundOverride) { m_impl->InitIfNeeded(); - return m_impl->CreateEnvironmentLight(prthTotexture, intensity); + return m_impl->CreateEnvironmentLight(prthTotexture, intensity, backgroundOverride); } void HdRprApi::SetTransform(HdRprApiEnvironmentLight* envLight, GfMatrix4f const& transform) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index 605ca672e..a78fd4020 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -71,8 +71,8 @@ class HdRprApi final { HdRprApi(HdRprDelegate* delegate); ~HdRprApi(); - HdRprApiEnvironmentLight* CreateEnvironmentLight(const std::string& pathTotexture, float intensity); - HdRprApiEnvironmentLight* CreateEnvironmentLight(GfVec3f color, float intensity); + HdRprApiEnvironmentLight* CreateEnvironmentLight(const std::string& pathTotexture, float intensity, VtValue const& backgroundOverride); + HdRprApiEnvironmentLight* CreateEnvironmentLight(GfVec3f color, float intensity, VtValue const& backgroundOverride); void SetTransform(HdRprApiEnvironmentLight* envLight, GfMatrix4f const& transform); void Release(HdRprApiEnvironmentLight* envLight); From d926bfd62b1437d8441fd0a4adce00d14e182326 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Mon, 12 Apr 2021 01:09:39 +0300 Subject: [PATCH 10/50] buildmaster: version update to 2.0.32 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 4e9e7f012..dec9b4577 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "31") +set(HD_RPR_PATCH_VERSION "32") From ed794b16c05c5ec0ded0da8fce604c4a35199c31 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 12 Apr 2021 19:04:40 +0300 Subject: [PATCH 11/50] Fix distant light visibility (#458) --- pxr/imaging/plugin/hdRpr/distantLight.cpp | 11 +++++++++++ pxr/imaging/plugin/hdRpr/domeLight.cpp | 4 ---- pxr/imaging/plugin/hdRpr/light.cpp | 4 ---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/distantLight.cpp b/pxr/imaging/plugin/hdRpr/distantLight.cpp index 276a9d71c..c5e05058a 100644 --- a/pxr/imaging/plugin/hdRpr/distantLight.cpp +++ b/pxr/imaging/plugin/hdRpr/distantLight.cpp @@ -47,6 +47,17 @@ void HdRprDistantLight::Sync(HdSceneDelegate* sceneDelegate, bool newLight = false; if (bits & HdLight::DirtyParams) { + bool isVisible = sceneDelegate->GetVisible(id); + if (!isVisible) { + if (m_rprLight) { + rprApi->Release(m_rprLight); + m_rprLight = nullptr; + } + + *dirtyBits = HdLight::Clean; + return; + } + float intensity = sceneDelegate->GetLightParamValue(id, HdLightTokens->intensity).Get(); float exposure = sceneDelegate->GetLightParamValue(id, HdLightTokens->exposure).Get(); float computedIntensity = computeLightIntensity(intensity, exposure); diff --git a/pxr/imaging/plugin/hdRpr/domeLight.cpp b/pxr/imaging/plugin/hdRpr/domeLight.cpp index 26dd1ba69..967471efd 100644 --- a/pxr/imaging/plugin/hdRpr/domeLight.cpp +++ b/pxr/imaging/plugin/hdRpr/domeLight.cpp @@ -67,10 +67,6 @@ void HdRprDomeLight::Sync(HdSceneDelegate* sceneDelegate, bool isVisible = sceneDelegate->GetVisible(id); if (!isVisible) { - // Invisible light does not produces any emission on a scene. - // So we simply keep light primitive empty in that case. - // We can do it in such a way because Hydra releases light object - // whenever it changed and creates it from scratch *dirtyBits = HdLight::Clean; return; } diff --git a/pxr/imaging/plugin/hdRpr/light.cpp b/pxr/imaging/plugin/hdRpr/light.cpp index 97aa33829..fe241dea4 100644 --- a/pxr/imaging/plugin/hdRpr/light.cpp +++ b/pxr/imaging/plugin/hdRpr/light.cpp @@ -396,10 +396,6 @@ void HdRprLight::Sync(HdSceneDelegate* sceneDelegate, bool isVisible = sceneDelegate->GetVisible(id); if (!isVisible) { - // Invisible light does not produces any emission on a scene. - // So we simply keep light primitive empty in that case. - // We can do it in such a way because Hydra releases light object - // whenever it changed and creates it from scratch *dirtyBits = DirtyBits::Clean; return; } From 0418c1b0535326d881b20f17c672593273dfe8e5 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Mon, 12 Apr 2021 19:09:47 +0300 Subject: [PATCH 12/50] buildmaster: version update to 2.0.33 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index dec9b4577..64581323c 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "32") +set(HD_RPR_PATCH_VERSION "33") From 379b10c86e8e4b0d4bc04df505b85e2d957a454f Mon Sep 17 00:00:00 2001 From: George Shakula Date: Tue, 13 Apr 2021 04:53:07 +0300 Subject: [PATCH 13/50] Allow dynamic change of session type (#459) PURPOSE Optimize final rendering in RPRViewer. EFFECT OF CHANGE Speed up rendering via husk in case of multiple render products Allow dynamic change of session type (batch/interactive) --- .../python/generateRenderSettingFiles.py | 41 +++++-- pxr/imaging/plugin/hdRpr/renderBuffer.cpp | 2 +- pxr/imaging/plugin/hdRpr/renderDelegate.cpp | 5 - pxr/imaging/plugin/hdRpr/renderDelegate.h | 6 - pxr/imaging/plugin/hdRpr/rprApi.cpp | 103 +++++++++++------- pxr/imaging/plugin/hdRpr/rprApi.h | 2 +- 6 files changed, 92 insertions(+), 67 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index f53df96c9..1701c2ad8 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -78,7 +78,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'name': 'RenderMode', 'settings': [ { - 'name': 'renderMode', + 'name': 'coreRenderMode', 'ui_name': 'Render Mode', 'defaultValue': 'Global Illumination', 'values': [ @@ -101,13 +101,13 @@ def hidewhen_not_tahoe(render_setting_categories): 'minValue': 0.0, 'maxValue': 100.0, 'houdini': { - 'hidewhen': 'renderMode != "AmbientOcclusion"' + 'hidewhen': 'coreRenderMode != "AmbientOcclusion"' } }, { 'folder': 'Contour Settings', 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' }, 'settings': [ { @@ -117,7 +117,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'minValue': 0.0, 'maxValue': 1.0, 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' } }, { @@ -126,7 +126,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'defaultValue': True, 'help': 'Whether to use geometry normals for edge detection or not', 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' } }, { @@ -137,7 +137,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'maxValue': 100.0, 'help': 'Linewidth of edges detected via normals', 'houdini': { - 'hidewhen': ['renderMode != "Contour"', 'contourUseNormal == 0'] + 'hidewhen': ['coreRenderMode != "Contour"', 'contourUseNormal == 0'] } }, { @@ -147,7 +147,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'minValue': 0.0, 'maxValue': 180.0, 'houdini': { - 'hidewhen': ['renderMode != "Contour"', 'contourUseNormal == 0'] + 'hidewhen': ['coreRenderMode != "Contour"', 'contourUseNormal == 0'] } }, { @@ -156,7 +156,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'defaultValue': True, 'help': 'Whether to use primitive Id for edge detection or not', 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' } }, { @@ -167,7 +167,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'maxValue': 100.0, 'help': 'Linewidth of edges detected via primitive Id', 'houdini': { - 'hidewhen': ['renderMode != "Contour"', 'contourUsePrimId == 0'] + 'hidewhen': ['coreRenderMode != "Contour"', 'contourUsePrimId == 0'] } }, { @@ -176,7 +176,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'defaultValue': True, 'help': 'Whether to use material Id for edge detection or not', 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' } }, { @@ -187,7 +187,7 @@ def hidewhen_not_tahoe(render_setting_categories): 'maxValue': 100.0, 'help': 'Linewidth of edges detected via material Id', 'houdini': { - 'hidewhen': ['renderMode != "Contour"', 'contourUseMaterialId == 0'] + 'hidewhen': ['coreRenderMode != "Contour"', 'contourUseMaterialId == 0'] } }, { @@ -204,7 +204,7 @@ def hidewhen_not_tahoe(render_setting_categories): ' * cyan - material Id + normal\\n' ' * black - all', 'houdini': { - 'hidewhen': 'renderMode != "Contour"' + 'hidewhen': 'coreRenderMode != "Contour"' } } ] @@ -575,6 +575,23 @@ def hidewhen_not_tahoe(render_setting_categories): 'defaultValue': False } ] + }, + { + 'name': 'Session', + 'settings': [ + { + 'name': 'renderMode', + 'defaultValue': 'interactive', + 'values': [ + SettingValue('batch'), + SettingValue('interactive') + ] + }, + { + 'name': 'progressive', + 'defaultValue': True + } + ] } ] diff --git a/pxr/imaging/plugin/hdRpr/renderBuffer.cpp b/pxr/imaging/plugin/hdRpr/renderBuffer.cpp index 606956284..cc54f0a7c 100644 --- a/pxr/imaging/plugin/hdRpr/renderBuffer.cpp +++ b/pxr/imaging/plugin/hdRpr/renderBuffer.cpp @@ -92,7 +92,7 @@ void HdRprRenderBuffer::_Deallocate() { } void* HdRprRenderBuffer::Map() { - m_rprApi->Resolve(); + m_rprApi->Resolve(GetId()); #ifdef ENABLE_MULTITHREADED_RENDER_BUFFER std::unique_lock lock(m_mapMutex); diff --git a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp index f6c260080..791055459 100644 --- a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp +++ b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp @@ -118,9 +118,6 @@ class HdRprDiagnosticMgrDelegate : public TfDiagnosticMgr::Delegate { TF_DEFINE_PRIVATE_TOKENS(_tokens, (openvdbAsset) \ (percentDone) \ - (renderMode) \ - (batch) \ - (progressive) \ (RPR) ); @@ -157,8 +154,6 @@ HdRprDelegate::HdRprDelegate(HdRenderSettingsMap const& renderSettings) { SetRenderSetting(entry.first, entry.second); } - m_isBatch = GetRenderSetting(_tokens->renderMode) == _tokens->batch; - m_isProgressive = GetRenderSetting(_tokens->progressive).GetWithDefault(true); m_rprApi.reset(new HdRprApi(this)); g_rprApi = m_rprApi.get(); diff --git a/pxr/imaging/plugin/hdRpr/renderDelegate.h b/pxr/imaging/plugin/hdRpr/renderDelegate.h index c0b1f3edd..7ac069e52 100644 --- a/pxr/imaging/plugin/hdRpr/renderDelegate.h +++ b/pxr/imaging/plugin/hdRpr/renderDelegate.h @@ -94,17 +94,11 @@ class HdRprDelegate final : public HdRenderDelegate { void SetDrivers(HdDriverVector const& drivers) override; #endif // PXR_VERSION >= 2005 - bool IsBatch() const { return m_isBatch; } - bool IsProgressive() const { return m_isProgressive; } - private: static const TfTokenVector SUPPORTED_RPRIM_TYPES; static const TfTokenVector SUPPORTED_SPRIM_TYPES; static const TfTokenVector SUPPORTED_BPRIM_TYPES; - bool m_isBatch; - bool m_isProgressive; - std::unique_ptr m_rprApi; std::unique_ptr m_renderParam; HdRenderSettingDescriptorList m_settingDescriptors; diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 235a067fd..f857392cf 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -75,6 +75,12 @@ TF_DEFINE_ENV_SETTING(HDRPR_RENDER_QUALITY_OVERRIDE, "", namespace { +TF_DEFINE_PRIVATE_TOKENS(_tokens, + (batch) + (renderMode) + (progressive) +); + TfToken GetRenderQuality(HdRprConfig const& config) { std::string renderQualityOverride = TfGetEnvSetting(HDRPR_RENDER_QUALITY_OVERRIDE); @@ -1485,15 +1491,15 @@ class HdRprApiImpl { rpr_uint GetRprRenderMode(TfToken const& mode) { static std::map s_mapping = { - {HdRprRenderModeTokens->GlobalIllumination, RPR_RENDER_MODE_GLOBAL_ILLUMINATION}, - {HdRprRenderModeTokens->DirectIllumination, RPR_RENDER_MODE_DIRECT_ILLUMINATION}, - {HdRprRenderModeTokens->Wireframe, RPR_RENDER_MODE_WIREFRAME}, - {HdRprRenderModeTokens->MaterialIndex, RPR_RENDER_MODE_MATERIAL_INDEX}, - {HdRprRenderModeTokens->Position, RPR_RENDER_MODE_POSITION}, - {HdRprRenderModeTokens->Normal, RPR_RENDER_MODE_NORMAL}, - {HdRprRenderModeTokens->Texcoord, RPR_RENDER_MODE_TEXCOORD}, - {HdRprRenderModeTokens->AmbientOcclusion, RPR_RENDER_MODE_AMBIENT_OCCLUSION}, - {HdRprRenderModeTokens->Diffuse, RPR_RENDER_MODE_DIFFUSE}, + {HdRprCoreRenderModeTokens->GlobalIllumination, RPR_RENDER_MODE_GLOBAL_ILLUMINATION}, + {HdRprCoreRenderModeTokens->DirectIllumination, RPR_RENDER_MODE_DIRECT_ILLUMINATION}, + {HdRprCoreRenderModeTokens->Wireframe, RPR_RENDER_MODE_WIREFRAME}, + {HdRprCoreRenderModeTokens->MaterialIndex, RPR_RENDER_MODE_MATERIAL_INDEX}, + {HdRprCoreRenderModeTokens->Position, RPR_RENDER_MODE_POSITION}, + {HdRprCoreRenderModeTokens->Normal, RPR_RENDER_MODE_NORMAL}, + {HdRprCoreRenderModeTokens->Texcoord, RPR_RENDER_MODE_TEXCOORD}, + {HdRprCoreRenderModeTokens->AmbientOcclusion, RPR_RENDER_MODE_AMBIENT_OCCLUSION}, + {HdRprCoreRenderModeTokens->Diffuse, RPR_RENDER_MODE_DIFFUSE}, }; auto it = s_mapping.find(mode); @@ -1507,10 +1513,10 @@ class HdRprApiImpl { } m_dirtyFlags |= ChangeTracker::DirtyScene; - auto& renderMode = preferences.GetRenderMode(); + auto& renderMode = preferences.GetCoreRenderMode(); if (m_rprContextMetadata.pluginType == kPluginNorthstar) { - if (renderMode == HdRprRenderModeTokens->Contour) { + if (renderMode == HdRprCoreRenderModeTokens->Contour) { if (!m_contourAovs) { m_contourAovs = std::make_unique(); m_contourAovs->normal = CreateAov(HdAovTokens->normal); @@ -1546,7 +1552,7 @@ class HdRprApiImpl { } RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_RENDER_MODE, GetRprRenderMode(renderMode)), "Failed to set render mode"); - if (renderMode == HdRprRenderModeTokens->AmbientOcclusion) { + if (renderMode == HdRprCoreRenderModeTokens->AmbientOcclusion) { RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_AO_RAY_LENGTH, preferences.GetAoRadius()), "Failed to set ambient occlusion radius"); } } @@ -1683,6 +1689,16 @@ class HdRprApiImpl { UpdateColorAlpha(m_colorAov.get()); } + + if (preferences.IsDirty(HdRprConfig::DirtySession) || force) { + m_isProgressive = preferences.GetProgressive(); + bool isBatch = preferences.GetRenderMode() == HdRprRenderModeTokens->batch; + if (m_isBatch != isBatch) { + m_isBatch = isBatch; + m_batchREM = isBatch ? std::make_unique() : nullptr; + m_dirtyFlags |= ChangeTracker::DirtyScene; + } + } } void UpdateCamera(RenderSetting const& aspectRatioPolicy, RenderSetting const& instantaneousShutter) { @@ -2081,23 +2097,19 @@ class HdRprApiImpl { return; } - if (!m_batchREM) { - m_batchREM = std::make_unique(); - } auto renderScope = m_batchREM->EnterRenderScope(); EnableRenderUpdateCallback(BatchRenderUpdateCallback); + // Also, we try to maximize the number of samples rendered with one rprContextRender call. + bool isMaximizingContextIterations = false; + // In a batch session, we disable resolving of all samples except the first and last. // Also, if the user will keep progressive mode on, we support snapshoting (resolving intermediate renders) - + // // User might decide to completely disable progress updates to maximize performance. // In this case, snapshoting is not available. - const bool isProgressive = m_delegate->IsProgressive(); - - // Also, we try to maximize the number of samples rendered with one rprContextRender call. - bool isMaximizingContextIterations = false; - if (isProgressive) { + if (m_isProgressive) { // We can keep the ability to log progress and do snapshots // while maximizing RPR_CONTEXT_ITERATIONS, only if RUC is supported. if (m_isRenderUpdateCallbackEnabled) { @@ -2401,7 +2413,7 @@ class HdRprApiImpl { if (m_state == kStateRender) { try { - if (m_delegate->IsBatch()) { + if (m_isBatch) { BatchRenderImpl(renderThread); } else { if (m_rprContextMetadata.pluginType == RprUsdPluginType::kPluginHybrid && @@ -2653,7 +2665,7 @@ Don't show this message again? RprUsdMaterialRegistry::GetInstance().CommitResources(m_imageCache.get()); } - void Resolve() { + void Resolve(SdfPath const& aovId) { // hdRpr's rendering is implemented asynchronously - rprContextRender spins in the background thread. // // Resolve works differently depending on the current rendering session type: @@ -2662,9 +2674,8 @@ Don't show this message again? // * In an interactive session, it simply does nothing because we always resolve // data to HdRenderBuffer as fast as possible. It might change in the future though. // - if (m_batchREM) { - m_batchREM->OnResolveRequest(); - m_batchREM->WaitUntilNextRenderEvent(); + if (m_isBatch) { + m_batchREM->WaitForResolve(aovId); } } @@ -3567,32 +3578,37 @@ Don't show this message again? class BatchRenderEventManager { public: - void WaitUntilNextRenderEvent() { + void WaitForResolve(SdfPath const& aovId) { + if (m_signalingAovId.IsEmpty()) { + m_signalingAovId = aovId; + } else if (m_signalingAovId != aovId) { + // When there is more than one bound aov, + // we want to avoid blocking resolve for each of them separately. + // Instead, block only on the first one only. + return; + } + + m_isResolveRequested.store(true); std::unique_lock lock(m_renderEventMutex); m_renderEventCV.wait(lock, [this]() -> bool { return !m_isRenderInProgress || !m_isResolveRequested; }); } class RenderScopeGuard { public: - RenderScopeGuard(std::atomic* isRenderInProgress, std::condition_variable* renderEventCV) - : m_isRenderInProgress(isRenderInProgress), m_renderEventCV(renderEventCV) { - m_isRenderInProgress->store(true); - m_renderEventCV->notify_one(); + RenderScopeGuard(BatchRenderEventManager* rem) : m_rem(rem) { + m_rem->m_signalingAovId = SdfPath::EmptyPath(); + m_rem->m_isRenderInProgress.store(true); + m_rem->m_renderEventCV.notify_one(); } ~RenderScopeGuard() { - m_isRenderInProgress->store(false); - m_renderEventCV->notify_one(); + m_rem->m_isRenderInProgress.store(false); + m_rem->m_renderEventCV.notify_one(); } private: - std::atomic* m_isRenderInProgress; - std::condition_variable* m_renderEventCV; + BatchRenderEventManager* m_rem; }; - RenderScopeGuard EnterRenderScope() { return RenderScopeGuard(&m_isRenderInProgress, &m_renderEventCV); } - - void OnResolveRequest() { - m_isResolveRequested.store(true); - } + RenderScopeGuard EnterRenderScope() { return RenderScopeGuard(this); } bool IsResolveRequested() const { return m_isResolveRequested; @@ -3608,8 +3624,11 @@ Don't show this message again? std::condition_variable m_renderEventCV; std::atomic m_isRenderInProgress{false}; std::atomic m_isResolveRequested{false}; + SdfPath m_signalingAovId; }; std::unique_ptr m_batchREM; + std::atomic m_isBatch{false}; + bool m_isProgressive; struct ResolveData { struct AovEntry { @@ -3930,8 +3949,8 @@ void HdRprApi::CommitResources() { m_impl->CommitResources(); } -void HdRprApi::Resolve() { - m_impl->Resolve(); +void HdRprApi::Resolve(SdfPath const& aovId) { + m_impl->Resolve(aovId); } void HdRprApi::Render(HdRprRenderThread* renderThread) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index a78fd4020..77a38a2a7 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -158,7 +158,7 @@ class HdRprApi final { RenderStats GetRenderStats() const; void CommitResources(); - void Resolve(); + void Resolve(SdfPath const& aovId); void Render(HdRprRenderThread* renderThread); void AbortRender(); From a37fd7ab1c166e9f085c16c70e5f25348899bdb3 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 13 Apr 2021 05:09:34 +0300 Subject: [PATCH 14/50] buildmaster: version update to 2.0.34 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 64581323c..8f9633da5 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "33") +set(HD_RPR_PATCH_VERSION "34") From 05a893ed541e92c502269b8d08957f902dc61143 Mon Sep 17 00:00:00 2001 From: Aleksandr Gurov Date: Tue, 13 Apr 2021 16:12:32 +0300 Subject: [PATCH 15/50] Added rif dxcompiler (#460) * Changed reemitting stage to restarting render * Added MaterialX options to pass into HdRprPlugin * Added shader cache env override * CIS Houdini python3 workaround (#442) * Fix crash on material update (#443) * Fix crash on material update If Rprim is invisible, Hydra skips its re-sync. In case material was updated, RPR requires updating material reference. Otherwise, Rprim would hold a dangling reference to a material that leads to a crash in the RPR core. * Fix crash in Material Properties when graph is invalid state * Rpr material library (#444) PURPOSE To integrate RPR Material Library in Houdini EFFECT OF CHANGE Integrated RPR Material Library in Houdini (preview version, feedback is welcome). Find a new button in the RPR menu (on the "File Edit View" toolbar) - "Import Material". * buildmaster: version update to 2.0.23 * Fix compilation error (#445) * buildmaster: version update to 2.0.24 * HdRprConfig render settings version invalidation on render delegate destruction * Revert "Changed reemitting stage to restarting render" This reverts commit 1dd9a833d8c5f66b401f0115768720226631ed1b. * Added RIF dxcompiler.dll Co-authored-by: George Shakula Co-authored-by: radeonprorender --- cmake/modules/FindRif.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/FindRif.cmake b/cmake/modules/FindRif.cmake index 51c4ccc52..e063da458 100644 --- a/cmake/modules/FindRif.cmake +++ b/cmake/modules/FindRif.cmake @@ -34,6 +34,7 @@ find_library(RIF_LIBRARY if(WIN32) set(RIF_BINARIES + ${RIF_LOCATION_LIB}/dxcompiler.dll ${RIF_LOCATION_LIB}/MIOpen.dll ${RIF_LOCATION_LIB}/RadeonImageFilters.dll ${RIF_LOCATION_LIB}/RadeonML_MIOpen.dll From d2e38053aa26d1fe0e28b3e97b1cc90197395ffd Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 13 Apr 2021 16:24:44 +0300 Subject: [PATCH 16/50] buildmaster: version update to 2.0.35 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 8f9633da5..ae5e67290 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "34") +set(HD_RPR_PATCH_VERSION "35") From 1ec76d4b1cef022d9c5faa47051249b5b2c0f669 Mon Sep 17 00:00:00 2001 From: Aleksandr Gurov Date: Fri, 16 Apr 2021 19:14:55 +0300 Subject: [PATCH 17/50] Fixed adaptive sampling counter for numSamples < minSamples case (#462) PURPOSE PR created to have valid render stats, without these changes progress doesn't updated for first iterations EFFECT OF CHANGE Valid render stats percent field --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index f857392cf..aedc1be33 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2219,7 +2219,7 @@ class HdRprApiImpl { } } - if (isAdaptiveSamplingEnabled && + if (isAdaptiveSamplingEnabled && m_numSamples >= m_minSamples && RPR_ERROR_CHECK(m_rprContext->GetInfo(RPR_CONTEXT_ACTIVE_PIXEL_COUNT, sizeof(m_activePixels), &m_activePixels, NULL), "Failed to query active pixels")) { m_activePixels = -1; } @@ -2349,7 +2349,7 @@ class HdRprApiImpl { ResolveFramebuffers(); } - if (IsAdaptiveSamplingEnabled() && + if (IsAdaptiveSamplingEnabled() && m_numSamples >= m_minSamples && RPR_ERROR_CHECK(m_rprContext->GetInfo(RPR_CONTEXT_ACTIVE_PIXEL_COUNT, sizeof(m_activePixels), &m_activePixels, NULL), "Failed to query active pixels")) { m_activePixels = -1; } From aff552dec883e182e9ac90a62c1b0071c00b42ec Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Fri, 16 Apr 2021 19:24:47 +0300 Subject: [PATCH 18/50] buildmaster: version update to 2.0.36 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index ae5e67290..5c57e8316 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "35") +set(HD_RPR_PATCH_VERSION "36") From 2e15ba07a85266a175e8ad6793e0944a51cd4662 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak <33626169+bnagirniak@users.noreply.github.com> Date: Wed, 21 Apr 2021 23:42:23 +0300 Subject: [PATCH 19/50] Fixed cyrillic typos in some .mtlx files. (#467) --- .../rprUsd/materialNodes/mtlxFiles/Shaders/rpr_blend.mtlx | 2 +- .../rprUsd/materialNodes/mtlxFiles/Shaders/rpr_orennayar.mtlx | 2 +- .../rprUsd/materialNodes/mtlxFiles/Shaders/rpr_refraction.mtlx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_blend.mtlx b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_blend.mtlx index ea9bf069b..09af5a612 100644 --- a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_blend.mtlx +++ b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_blend.mtlx @@ -4,7 +4,7 @@ - + diff --git a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_orennayar.mtlx b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_orennayar.mtlx index 3d5e46c12..628179625 100644 --- a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_orennayar.mtlx +++ b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_orennayar.mtlx @@ -1,6 +1,6 @@ - + diff --git a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_refraction.mtlx b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_refraction.mtlx index dee6efb86..08fefaf6f 100644 --- a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_refraction.mtlx +++ b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/Shaders/rpr_refraction.mtlx @@ -1,6 +1,6 @@ - + From 7b9d5b611b5d97531029e88dd5089f3a92c21adc Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Wed, 21 Apr 2021 23:55:01 +0300 Subject: [PATCH 20/50] buildmaster: version update to 2.0.37 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 5c57e8316..8791c1799 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "36") +set(HD_RPR_PATCH_VERSION "37") From ca6c31340d499b1009b8163aa5030dfaa3ca3d4d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 22 Apr 2021 04:28:26 +0300 Subject: [PATCH 21/50] Create intermediate directories when exporting .rpr (#463) PURPOSE Resolve user-reported issue of failed .rpr export when intermediate directories are not created in the case where output path has $OS expression EFFECT OF CHANGE Fixed creation of intermediate directories when exporting .rpr --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 9 +++++++++ .../plugin/rprHoudini/hda/rpr_exportRpr1.hda | Bin 10570 -> 10578 bytes 2 files changed, 9 insertions(+) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index aedc1be33..c088baa06 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -52,6 +52,7 @@ using json = nlohmann::json; #include "pxr/usd/usdRender/tokens.h" #include "pxr/usd/usdGeom/tokens.h" #include "pxr/base/tf/envSetting.h" +#include "pxr/base/tf/fileUtils.h" #include "pxr/base/tf/getenv.h" #include "notify/message.h" @@ -2463,6 +2464,14 @@ Don't show this message again? } #endif // BUILD_AS_HOUDINI_PLUGIN + // Create intermediate directories if needed + auto exportDir = TfGetPathName(m_rprSceneExportPath); + if (!exportDir.empty()) { + if (!TfMakeDirs(exportDir, -1, true)) { + fprintf(stderr, "Failed to create output directory\n"); + } + } + uint32_t currentYFlip; if (m_isOutputFlipped) { currentYFlip = RprUsdGetInfo(m_rprContext.get(), RPR_CONTEXT_Y_FLIP); diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda index 9b011440092556b0709bc7244c8faca1d2b5721b..ce88fe6a9e2b4cfa8be16a360308592a1c7c421c 100644 GIT binary patch delta 2928 zcmV-$3y<{5Qqoe8DFk47)bo)o9t2={)bo)~9R)F9dDQcfaj67gdDQch9sw%^V0qN@ zlT85_1Ymj8^OI=-Av0ik)bjuU00c;7Y;XVo5}E)2003Zl)bjuU01H%aZ)|feb7*C3 zW&i*Zng9R;0AP94?~}a&9|T}|)bo?z0TwHwV0qN@00007R%LQ?X>V=-03d7t000GG zdDQa&000L`V{dL#R!0B;AaRo+0viGOlRW|-33vbi0d-(`)bq1t0@M|M-COH#+c*;U z;=WuA-2cG(3N!(>jvjvHLl2v0*Vr}=oTNQqb5I$Hwsnz3L88-Uivatl-;mV9vZO?^ zoNRgyl2GIf=cnP!aQN__|7tXpzWCuERf#^mUQb#5gso~v(R+GVgFoU?ODH-nwTQv) zJkt0;y=L8>yGh60nT36SN?F@>ZPwrt&^zRNzCpfu)MsPQSDSOp%ozzRGJ!Uww)9Ta z-tTuJ>Ckt>r1Lp(8EUnf9t~_}Qy0C}+WkRyPepIL?cPAwnkIE!VlwKxRr~^fR*^|4tuB$;EUa%SU(JYwZn}vga`8+&*d!WC6|9=0sLpPw54Fbv}p=m)F{N>KH;#!u?TOj+q^i6eP`4HX7NK|Q3wU&A;Z8Kcjq z$7AF4_~P?u{F`ww`nO@A*2#GEaddfcc6rgNt$@U(^~j}nrGY6a*Oqk~c4;kf=}v!D zdZBBpZB^}e_sCmifb{mBs_4(}-R@uM+}p|yXr$Pqd3%u;gPjlbj;b$vvC>RN6HpAkl>wy{Zq%)@@QcCyEF%<;bx$0NR)$pCVQHXJuP@qqVx%A@#yiUNt&ROGviogz0a*6uOTu*C43IZRG9L2=*pe48E@hOeJGeS9+29*S@~D3 z9ds{$dbrO)dKr-69CUby!AqYP>S9@R8fEQhn#8e=(s^_kb7l&uoiog4nTgC`_&Ut8T4sg2*HJe$ll8jrrvty;=bFkoQFTAb+RcCFo^YpyQ}A{@+|Wdxr2 z1eELSp3#7bLLIr-aVA_-0cO-StGMESzT-$G2k5g6$rwg5_dsVp<#B6mNDSXp!SR&~ zzew>^6bMn>gLJEm%nze8be5v6C`-;x5HQO~8wp}`d47~o+wQF$*w+qO7XhDB8O%q% znC0(`xKshrQI@ARE*WHqUw-J9Y1a}KrK%OI?L5P>mI2s2%PysGSU>o-MNp`J`C*!| z@@ogwfgT~rV=y0-dvD2t4kZuT4?u18oIq-yXQQ~%G>N@9e?y!GXc!5jqc8x=TZ_ zXss-WC<=@s*)ho+mSXnGd#6OmzD>~ok`*s^j#{US`L$RRCjBoHW^}_p(JD}FrmAz0 zEGiqOl~Vw3|<+gs>=gdtjh$V zf98muD#E=OBu-r@n;$2Cz+>~n3|O1^1mBdJ1uX8cPm#ID{p3Sa+k2L)W0bsek>T!spLSH!TS4uIV3Q#N38T_OtM+Y z3rW2=h=dO}Tz48*N9(8W{K`g>3v!VRPkFV>*bEap4nLhRqI0DdM2I^!qi)1k|GrXm zkg2QvqJzxr^@xeO{vCtp?cX6atSNQtKqTp$34T^?AWYPv%MlZ86F9YwvJO&U6Thoy zwc@KB;ymiPZ<+{yp+%VFA<*+ek}?a&RDV&nrx)Us=Swv_WgXo`QXfH8!!K%}DzyBt z{bh}8h^Yv3`aq*L@^djqK;u>GsmX(uOaQ#rK9fdcWubMefxx z5g2oCe#w^9ZLRP^L+*{_%teD-s^v5PTml&va{z@6A)ZNp4#h;>Qh6(sv@Jd<$+9kM zfkzs99%mR(wj!R;l~q>xv-htddExJZZ?bKMx$r>?%m9M$h&V&TExh1f5OBqZ zy&1mOzm6`ChNna0;`rm4aWow7z8)W+9vzQ|N1@9Ad*MlKmG0u9gf5FO9Y!SKrMPH%p1`o1L8)W$H9D z(|Jq0AEdh`X4}*g7qh6pEnhkuQRr&tX9yO%E1h9}${7)e%lN57%Zy59i{OS2S-~k` zhJL4+od4xmmzxlU%}YB3g*2&!d?A%IVqxU!16D2%7PAzg(v#D@9Fl~9CpuXIxqy#}qSLJh zdrFR$@=@oW|K_I;Nhr?wIun2aJv!JVJkI*~YtE&19&fL%UZ3!9I`Id0r4h|E>dk%aSy5svVDpXoJ?l#( a7vufmhvV_9SFalX13|q$fP}NgB7_Ekx{{;- delta 2920 zcmV-u3zziLQp!@0DFk22AlQ*D9t2;?AlQ*l9R(?0${^U0aj67f${^U29sw%^U&V=-03c)l000GF z${^SP000L`V{dL#R!0B;AZe2!0viGGlRW|-32*=a0d-%>AlS2I0@M|M)m!Ut+c*;U z;=WuA-2cG(3N!(>jvjubA9~n4yT-P0;3Vw`rVbj@+_#Cxb&47k3cd3uw>TRvt*Sbh+?-{1v?KExb`^4sy`Q$ry9l$g8@FWCe z$fNcRqT?}|fwnxE;$#+hm=pOj21x;PL4P?)WawGqgVB;W?jDhNj^Z z-^@My%a_6F+XM4|!-o(1za5{P>S$!-3Fw@@axbLz}sQ z>>p?l^RPde;|T!~GQSB5t7{uZ%48a`ZOlW$gqj=h{M7iDWm%sI3&A=d1zG=S{G@Np zB(tr8-_~8uF;k|FzTA{Y9n(Mcy>_?V(e`Sh=%j?*UW`Ia($IDbzK`Wx{VVYT z!t~rsUO=>AztKrLyx-Fv#aHG?jJ9UH(>ti!hWht^^qdnhp4y2(@|nB{xC)iE;43!k zQH*?Cpuf}pt{x>du&(j=0I;WiL#PClGR0s+9#X;Vet7Qs6OWv@9zlu#Oo@znG+4mQ z1Xh*LgcTGO#73w^?;)8;Q~m)}`4c`BMM5Bhggq4wslA(*f7RMS_p*lj0;HEA8O%V3 zhZshG>GMLJFN)5htnE!xKh{Y?|MG4um?@NY&M=?mCW5c_G+b1+AOiSbVHU`1Kga!h zfr)HE5lYxIT>|ubh5T8nr~>6*&I#vGcbMZ%kt@P5B8<@2)_ONxNTzdGsn(xuQZv(_ zyOS8hJam*2EJlOuRF)~)@B|ip$>K6Bk4;;DBJ|ab?(@gK8=kgS3VF-S2kGULRw>WJ zGnr{D#l|K?mEBFvWIeI9(1B0)xu&wn?DbARjpde1EdaVC%msnC({5zKJ0aj#m+P&N1V=$G)>W@a^?Qfro>ca}|MSjDT{z z-7^|;nW!Tdd)`=RD#V=nc9o&H?|Djp$szjULNJDriapR7qrz{k4Tkt%aevoB zieMZX`Zx%ubfs=M&(YSM)MM!ouM>8Qy(%csAjecuI#|@TSc0tNbw1~bt2UNSsWqmI ztR7k&$mPzZ&s`6t_7`}Bll41)ebI{Ka9Yy>i+M}Hh&BhXeDI+2goiEymaWo~EJiC2 zBK88qSaw1(gQb|e)b5N3RkscLU$ElE%2DfdKD(A{!nFQH!kliz6R!gGW+uA;NdX$- zV^GMyTRFNyQ5j7fOV&JRt`p+tehqx$buDyCe@HBPpBSRp->3ue0{EYQ7$U^U;H&1f zV15=AJTcC(M=}2kk={3(3tx}>Ftx2v(Rt;VsxA*;v91D$6&FiyHtVCDp$p$*6L5tKQ91UeVwFrEdX zr}A(w28mY}%I5nC@VMfCFay>mjNqG9O`EMtb@+4{m~H>>WR9jc=dxp)$bmTmK&EQO-)Y4rGunnBZ^e2Ete`yBsk#Hi6UVXzL&aHu+gbYm{H* zkmpg)ebYn=EyJXL4uPH*l9E~4r{;^YJ+l<2I$x?WQr6L3EcFpoHO55^RHc?5mA|Z> zjWCsA&K_vgMt&~m2q?U2UA5Lyb=jSuLiEXQ@XG<7K-%ynvgF=S$L#7QQ(WQIG3gi! zZ+@wg%x$gcLPOz=L>wDXFxna)Cz~ zdl6^kP_|;8XeckeCp9e{Z|Cn{L+~Qnf^YI=mOW>n1#SUBbVQt^5f)x@F9^7j!`>X< z>tBbLM}yOWb#eUZ%sLv3c3+QXrMee?4mb1n1XZjk#+eX0rSmqVvG1rMyDc)n+r3$cY2WPZB!Dspm$}MYvMCVR z+L&+CK;FTkY+JQ2>O81w=V$N>yGxZ}aiAF!$b0vh^T}N6r}OYe^iIivV2*yLnI82O z7~ps;L@uAk21i@Rg#)T_+;%MO-*3R+ThOjPI{77lxI<$6YDv>#j` zEZylXL;e7PDE7+BqbqTd6zL-#5K>Ye%P1~h6cO(+mC7h5P(n(}m!v$RuW|}8{KUOI zpKtH9VP5(~ow-LKZF>a!^I-c;kk;YIz!A;M0nDJyaJMxK*Th80<~68h~k5+2Wv`Ck&00l z9`zPS3aKkD_~jCS0X=%yCc@7${H@^ry70GGSFcaRkD5eEJmPKVYdi2K8~Ke>dJlWy ze)v*A^=!Ao^^`FEDWh$TB7_EC)055s From 0915245dcec9ae5b3993ee9ce62a029ede50a6df Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 22 Apr 2021 04:30:01 +0300 Subject: [PATCH 22/50] Fix crash on macOS when using RPR Material Library and simplify its installation (#464) PURPOSE Resolve #453 EFFECT OF CHANGE Fixed crash on macOS on first use of the RPR Material Library. --- README.md | 9 ++++ pxr/imaging/plugin/rprHoudini/CMakeLists.txt | 31 ++++++++--- .../plugin/rprHoudini/MatLib_INSTALL.md | 25 +++++++++ .../rprHoudini/activateHoudiniPlugin.cpp | 18 +++++++ .../rprHoudini/activateMatlibPlugin.cpp | 13 +++++ ...n.cpp.in => houdiniPluginActivator.cpp.in} | 33 +++--------- .../scripts/python/houRpr/materialLibrary.py | 53 +++---------------- 7 files changed, 103 insertions(+), 79 deletions(-) create mode 100644 pxr/imaging/plugin/rprHoudini/MatLib_INSTALL.md create mode 100644 pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp create mode 100644 pxr/imaging/plugin/rprHoudini/activateMatlibPlugin.cpp rename pxr/imaging/plugin/rprHoudini/{activateHoudiniPlugin.cpp.in => houdiniPluginActivator.cpp.in} (90%) diff --git a/README.md b/README.md index 0c2c71745..a7244543a 100644 --- a/README.md +++ b/README.md @@ -110,3 +110,12 @@ Launch either usdview or Houdini's Solaris viewport and select RPR as the render * `HDRPR_TRACING_DIR` To change the default directory, add the environment variable `HDRPR_TRACING_DIR` pointing to the location in which you wish the trace files to be recorded. For example, set `HDRPR_TRACING_DIR=C:\folder\` to activate the tracing in `C:\folder\`. + +Houdini +----------------------------- + +##### RPR Material Library + +1. Download [.mtlx version of RPR Material Library](https://drive.google.com/file/d/1i5jdYGS7gmrxw_Y0y7uotx4gxXVr8cMB/view?usp=sharing). + +2. Follow instructions from INSTALL.md shipped with the material library. diff --git a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt index 29f9889c1..1aa35eef1 100644 --- a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt +++ b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt @@ -25,14 +25,29 @@ GroupSources(RPR_for_Houdini) houdini_configure_target(RPR_for_Houdini "INSTDIR" "${CMAKE_INSTALL_PREFIX}/houdini/dso") set(HOUDINI_MAJOR_MINOR_VERSION "${Houdini_VERSION_MAJOR}.${Houdini_VERSION_MINOR}") -configure_file(activateHoudiniPlugin.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/activateHoudiniPlugin.cpp) -add_executable(activateHoudiniPlugin ${CMAKE_CURRENT_BINARY_DIR}/activateHoudiniPlugin.cpp) -set_property(TARGET activateHoudiniPlugin PROPERTY CXX_STANDARD 11) -target_link_libraries(activateHoudiniPlugin PRIVATE ghc_filesystem) -target_compile_definitions(activateHoudiniPlugin PRIVATE GHC_WIN_WSTRING_STRING_TYPE) -install( - TARGETS activateHoudiniPlugin - RUNTIME DESTINATION .) +configure_file(houdiniPluginActivator.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/houdiniPluginActivator.cpp) + +function(add_plugin_activator name) + add_executable(${name} ${name}.cpp) + set_property(TARGET ${name} PROPERTY CXX_STANDARD 11) + target_link_libraries(${name} PRIVATE ghc_filesystem) + target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + target_compile_definitions(${name} PRIVATE GHC_WIN_WSTRING_STRING_TYPE) +endfunction() + +add_plugin_activator(activateHoudiniPlugin) +install(TARGETS activateHoudiniPlugin RUNTIME DESTINATION .) + +if(RPR_INSTALL_MATLIB_PACKAGE) + add_plugin_activator(activateMatlibPlugin) + install(TARGETS activateMatlibPlugin RUNTIME DESTINATION MaterialLibrary) + + install( + FILES ${CMAKE_CURRENT_SOURCE_DIR}/MatLib_INSTALL.md + DESTINATION MaterialLibrary + RENAME INSTALL.md) +endif() + install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/hda/rpr_exportRpr1.hda diff --git a/pxr/imaging/plugin/rprHoudini/MatLib_INSTALL.md b/pxr/imaging/plugin/rprHoudini/MatLib_INSTALL.md new file mode 100644 index 000000000..69342595a --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/MatLib_INSTALL.md @@ -0,0 +1,25 @@ +## Installation + +### Automatic + +Run `activateMatlibPlugin`. It will find your houdini preference dir and add material library package that will point to the current directory. + +### Manual + +Add a new Houdini package with such configuration json: +``` +{ + "env":[ + { + "RPR_MTLX_MATERIAL_LIBRARY_PATH":"path-to-the-package" + } + ] +} +``` +where `path-to-the-package` depends on where do you unzip the material library package and should point to the directory that contains INSTALL.md (this file) + +More info here https://www.sidefx.com/docs/houdini/ref/plugins.html + +## Feedback + +In case you encounter any issues or would like to make a feature request, please post an "issue" on our official [GitHub repository](https://github.com/GPUOpen-LibrariesAndSDKs/RadeonProRenderUSD/issues) diff --git a/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp b/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp new file mode 100644 index 000000000..989531d5c --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp @@ -0,0 +1,18 @@ +#include "houdiniPluginActivator.cpp" + +int main() { + int exitCode = ActivateHoudiniPlugin("RPR_for_Houdini", { + {"RPR", ""}, + {"HOUDINI_PATH", "/houdini"}, + {"PYTHONPATH", "/lib/python"}, +#if defined(_WIN32) || defined(_WIN64) + {"PATH", "/lib"} +#endif + }); + +#if defined(_WIN32) || defined(_WIN64) + system("pause"); +#endif + + return exitCode; +} diff --git a/pxr/imaging/plugin/rprHoudini/activateMatlibPlugin.cpp b/pxr/imaging/plugin/rprHoudini/activateMatlibPlugin.cpp new file mode 100644 index 000000000..9553726c0 --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/activateMatlibPlugin.cpp @@ -0,0 +1,13 @@ +#include "houdiniPluginActivator.cpp" + +int main() { + int exitCode = ActivateHoudiniPlugin("RPR_MaterialLibrary", { + {"RPR_MTLX_MATERIAL_LIBRARY_PATH", ""} + }); + +#if defined(_WIN32) || defined(_WIN64) + system("pause"); +#endif + + return exitCode; +} diff --git a/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in b/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in similarity index 90% rename from pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in rename to pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in index c33a4bade..2a7f9d1f0 100644 --- a/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in +++ b/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in @@ -186,7 +186,7 @@ fs::path GetHoudiniUserPrefDir(const char* hver) { return {}; } -int ActivateHoudiniPlugin() { +int ActivateHoudiniPlugin(std::string const& pluginName, std::vector> const& env) { auto houdiniUserPrefDir = GetHoudiniUserPrefDir("@HOUDINI_MAJOR_MINOR_VERSION@"); if (houdiniUserPrefDir.empty()) { std::cout << "Can not determine HOUDINI_USER_PREF_DIR. Please check your environment and specify HOUDINI_USER_PREF_DIR" << std::endl; @@ -200,29 +200,20 @@ int ActivateHoudiniPlugin() { return EXIT_FAILURE; } - auto rprPath = executablePath.parent_path().string(); - std::replace(rprPath.begin(), rprPath.end(), '\\', '/'); - std::cout << "RPR path: " << rprPath << std::endl; + auto package = executablePath.parent_path().lexically_normal().string(); + std::replace(package.begin(), package.end(), '\\', '/'); + std::cout << "Package path: " << package << std::endl; auto packagesDir = houdiniUserPrefDir / "packages"; fs::create_directories(packagesDir); - auto packageJsonFilepath = packagesDir / "RPR_for_Houdini.json"; + auto packageJsonFilepath = packagesDir / (pluginName + ".json"); std::ofstream packageJson(packageJsonFilepath); if (!packageJson.is_open()) { std::cout << "Failed to open output file: " << packageJsonFilepath << std::endl; return EXIT_FAILURE; } - std::vector> env = { - {"RPR", ""}, - {"HOUDINI_PATH", "/houdini"}, - {"PYTHONPATH", "/lib/python"}, -#if defined(_WIN32) || defined(_WIN64) - {"PATH", "/lib"} -#endif - }; - packageJson << '{'; packageJson << '\"' << "env" << '\"'; packageJson << ':'; @@ -232,7 +223,7 @@ int ActivateHoudiniPlugin() { packageJson << '\"' << it->first << '\"'; packageJson << ':'; packageJson << '\"'; - packageJson << rprPath << it->second; + packageJson << package << it->second; packageJson << '\"'; packageJson << '}'; if (std::next(it) != env.end()) { @@ -247,16 +238,6 @@ int ActivateHoudiniPlugin() { return EXIT_FAILURE; } - std::cout << "Successfully activated RPR plugin" << std::endl; + std::cout << "Successfully activated the plugin" << std::endl; return EXIT_SUCCESS; } - -int main() { - int exitCode = ActivateHoudiniPlugin(); - -#if defined(_WIN32) || defined(_WIN64) - system("pause"); -#endif - - return exitCode; -} diff --git a/pxr/imaging/plugin/rprHoudini/scripts/python/houRpr/materialLibrary.py b/pxr/imaging/plugin/rprHoudini/scripts/python/houRpr/materialLibrary.py index 71ea3a6f1..bd5095fbc 100644 --- a/pxr/imaging/plugin/rprHoudini/scripts/python/houRpr/materialLibrary.py +++ b/pxr/imaging/plugin/rprHoudini/scripts/python/houRpr/materialLibrary.py @@ -8,35 +8,6 @@ material_library=None -HOWTO_INSTALL_MD = ''' -### How to install -1. Download MaterialX version of "Radeon ProRender Material Library" - [link](https://drive.google.com/file/d/1e2Qys1UMi9pu_x3wW5ctm9b8_FIohLKG/view?usp=sharing) (TODO: host somewhere) -2. Unzip to any directory - this will be our `INSTALL_DIR`. -3. Add `RPR_MTLX_MATERIAL_LIBRARY_PATH` environment variable value of which is `INSTALL_DIR`. - This can be done in a few ways: - * by modifying houdini.env file. [More info](https://www.sidefx.com/docs/houdini/basics/config_env.html) at "Setting environment variables" - * by modifying `HOUDINI_USER_PREF_DIR/packages/RPR_for_Houdini.json` package file. [More info](https://www.sidefx.com/docs/houdini/ref/plugins.html) - * by setting environment variable globally. [More info](https://superuser.com/questions/284342/what-are-path-and-other-environment-variables-and-how-can-i-set-or-use-them) -4. Restart Houdini -''' - -# Generated from HOWTO_INSTALL_MD -HOWTO_INSTALL_HTML = ''' -

How to install

-
    -
  1. Download MaterialX version of "Radeon ProRender Material Library" - link (TODO: host somewhere)
  2. -
  3. Unzip to any directory - this will be our INSTALL_DIR.
  4. -
  5. Add RPR_MTLX_MATERIAL_LIBRARY_PATH environment variable value of which is INSTALL_DIR. - This can be done in a few ways:
      -
    • by modifying houdini.env file. More info at "Setting environment variables"
    • -
    • by modifying HOUDINI_USER_PREF_DIR/packages/RPR_for_Houdini.json package file. More info
    • -
    • by setting environment variable globally. More info
    • -
    -
  6. -
  7. Restart Houdini
  8. -
-''' - HELP_TEXT = ''' To import a material click on a corresponding swatch. The material is always imported as a separate "Material Library" LOP node. @@ -54,10 +25,9 @@ def recursive_mkdir(path): class MaterialLibrary: class InitError(Exception): - def __init__(self, brief_msg, full_msg): - self.brief_msg = brief_msg - self.full_msg = full_msg - super(MaterialLibrary.InitError, self).__init__(brief_msg) + def __init__(self, msg): + self.msg = msg + super(MaterialLibrary.InitError, self).__init__(msg) class MaterialData: @@ -73,9 +43,7 @@ def __init__(self): self.path = os.environ.get('RPR_MTLX_MATERIAL_LIBRARY_PATH') if not self.path: - raise MaterialLibrary.InitError( - 'Material Library is not installed.', - HOWTO_INSTALL_HTML) + raise MaterialLibrary.InitError('Material Library is not installed: install guide') materials_json_file = os.path.join(self.path, 'materials.json') try: @@ -109,13 +77,9 @@ def __init__(self): self.material_groups.sort(key=lambda entry: entry[0]) except IOError as e: - raise MaterialLibrary.InitError( - 'Corrupted Material Library.', - 'materials.json could not be read.') + raise MaterialLibrary.InitError('Corrupted Material Library: missing materials.json.') except ValueError: - raise MaterialLibrary.InitError( - 'Corrupted Material Library', - 'Invalid materials.json.') + raise MaterialLibrary.InitError('Corrupted Material Librar: invalid materials.json.') MATERIAL_LIBRARY_TAG='hdrpr_material_library_generated' @@ -623,9 +587,8 @@ def import_material(): except MaterialLibrary.InitError as e: msg = QtWidgets.QMessageBox(hou.qt.mainWindow()) msg.setIcon(QtWidgets.QMessageBox.Critical) - msg.setText(e.brief_msg) - msg.setInformativeText(e.full_msg) - msg.setWindowTitle("Error") + msg.setText(e.msg) + msg.setWindowTitle("Material Library initialization failed") msg.show() return From 669d4454136bf56c76da057575cbc1ecb72a0bf3 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 22 Apr 2021 04:30:40 +0300 Subject: [PATCH 23/50] Fix houdini plugin rpath on Linux (#465) PURPOSE Resolve user-reported issue - on Linux, there were no RPR materials in Houdini. EFFECT OF CHANGE Fixed RPR's VOP nodes creation. --- pxr/imaging/plugin/rprHoudini/CMakeLists.txt | 9 ++++++++- pxr/imaging/plugin/rprHoudini/VOP_RPRMaterial.cpp | 2 ++ pxr/imaging/rprUsd/debugCodes.cpp | 1 + pxr/imaging/rprUsd/debugCodes.h | 3 ++- pxr/imaging/rprUsd/materialRegistry.cpp | 3 +++ pxr/imaging/rprUsd/materialRegistry.h | 3 +++ 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt index 1aa35eef1..d37ec04e0 100644 --- a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt +++ b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt @@ -20,9 +20,16 @@ target_link_libraries(RPR_for_Houdini rprUsd Houdini) +_pxr_init_rpath(rpath "houdini/dso") +_pxr_add_rpath(rpath "${CMAKE_INSTALL_PREFIX}/lib") +_pxr_install_rpath(rpath RPR_for_Houdini) + GroupSources(RPR_for_Houdini) -houdini_configure_target(RPR_for_Houdini "INSTDIR" "${CMAKE_INSTALL_PREFIX}/houdini/dso") +set_target_properties(RPR_for_Houdini PROPERTIES PREFIX "") +install(TARGETS RPR_for_Houdini + RUNTIME DESTINATION "houdini/dso" + LIBRARY DESTINATION "houdini/dso") set(HOUDINI_MAJOR_MINOR_VERSION "${Houdini_VERSION_MAJOR}.${Houdini_VERSION_MINOR}") configure_file(houdiniPluginActivator.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/houdiniPluginActivator.cpp) diff --git a/pxr/imaging/plugin/rprHoudini/VOP_RPRMaterial.cpp b/pxr/imaging/plugin/rprHoudini/VOP_RPRMaterial.cpp index e68f6b339..b611c7522 100644 --- a/pxr/imaging/plugin/rprHoudini/VOP_RPRMaterial.cpp +++ b/pxr/imaging/plugin/rprHoudini/VOP_RPRMaterial.cpp @@ -653,6 +653,8 @@ static const char* GetUIName(RprUsdMaterialNodeInfo const* shaderInfo) { } VOP_RPRMaterialOperator* VOP_RPRMaterialOperator::Create(RprUsdMaterialNodeInfo const* shaderInfo) { + TF_DEBUG(RPR_USD_DEBUG_MATERIAL_REGISTRY).Msg("Creating \"%s\" VOP node\n", shaderInfo->GetName()); + if (shaderInfo->GetName()) { if (std::strcmp("rpr_materialx_node", shaderInfo->GetName()) == 0) { return VOP_RPRMaterialOperator::_Create(shaderInfo); diff --git a/pxr/imaging/rprUsd/debugCodes.cpp b/pxr/imaging/rprUsd/debugCodes.cpp index b32860920..c1f9043fc 100644 --- a/pxr/imaging/rprUsd/debugCodes.cpp +++ b/pxr/imaging/rprUsd/debugCodes.cpp @@ -22,6 +22,7 @@ TF_REGISTRY_FUNCTION(TfDebug) { TF_DEBUG_ENVIRONMENT_SYMBOL(RPR_USD_DEBUG_CORE_UNSUPPORTED_ERROR, "signal about unsupported errors"); TF_DEBUG_ENVIRONMENT_SYMBOL(RPR_USD_DEBUG_DUMP_MATERIALS, "Dump material networks to the files in the current working directory") TF_DEBUG_ENVIRONMENT_SYMBOL(RPR_USD_DEBUG_LEAKS, "signal about rpr_context leaks"); + TF_DEBUG_ENVIRONMENT_SYMBOL(RPR_USD_DEBUG_MATERIAL_REGISTRY, "Print debug info about material registry"); } bool RprUsdIsLeakCheckEnabled() { diff --git a/pxr/imaging/rprUsd/debugCodes.h b/pxr/imaging/rprUsd/debugCodes.h index 339fe0024..39ebd7a0f 100644 --- a/pxr/imaging/rprUsd/debugCodes.h +++ b/pxr/imaging/rprUsd/debugCodes.h @@ -23,7 +23,8 @@ PXR_NAMESPACE_OPEN_SCOPE TF_DEBUG_CODES( RPR_USD_DEBUG_CORE_UNSUPPORTED_ERROR, RPR_USD_DEBUG_DUMP_MATERIALS, - RPR_USD_DEBUG_LEAKS + RPR_USD_DEBUG_LEAKS, + RPR_USD_DEBUG_MATERIAL_REGISTRY ); RPRUSD_API diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 7e1a7b50b..7894fc9f7 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -61,6 +61,7 @@ RprUsdMaterialRegistry::GetRegisteredNodes() { TF_WARN("RPR environment variable is not set"); return m_registeredNodes; } + TF_DEBUG(RPR_USD_DEBUG_MATERIAL_REGISTRY).Msg("RPR: %s\n", RPR.c_str()); if (TfGetEnvSetting(RPRUSD_USE_RPRMTLXLOADER)) { MaterialX::FilePathVec libraryNames = {"libraries", "materials"}; @@ -84,6 +85,8 @@ RprUsdMaterialRegistry::GetRegisteredNodes() { } for (auto& file : materialFiles) { + TF_DEBUG(RPR_USD_DEBUG_MATERIAL_REGISTRY).Msg("Processing material: \"%s\"\n", file.c_str()); + // UI Folder corresponds to subsections on UI // e.g. $RPR/Patterns/material.mtlx corresponds to Pattern UI folder auto uiFolder = file.substr(rprMaterialsPath.size() + 1); diff --git a/pxr/imaging/rprUsd/materialRegistry.h b/pxr/imaging/rprUsd/materialRegistry.h index 3ecb83e75..c1c0f3dbf 100644 --- a/pxr/imaging/rprUsd/materialRegistry.h +++ b/pxr/imaging/rprUsd/materialRegistry.h @@ -15,6 +15,7 @@ limitations under the License. #define RPRUSD_MATERIAL_REGISTRY_H #include "pxr/imaging/rprUsd/api.h" +#include "pxr/imaging/rprUsd/debugCodes.h" #include "pxr/imaging/hd/material.h" #include "pxr/base/arch/demangle.h" #include "pxr/base/tf/singleton.h" @@ -197,6 +198,8 @@ inline void RprUsdMaterialRegistry::Register( TfToken const& id, RprUsdMaterialNodeFactoryFnc factory, RprUsdMaterialNodeInfo const* info) { + TF_DEBUG(RPR_USD_DEBUG_MATERIAL_REGISTRY).Msg("Registering material node with id \"%s\"\n", id.GetText()); + RprUsdMaterialNodeDesc desc = {}; desc.factory = std::move(factory); desc.info = info; From 43c836f6fbfcba8d5b809dccbe5bc23a8893f259 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 22 Apr 2021 04:31:37 +0300 Subject: [PATCH 24/50] .rpr export: export depth AOV as RPR_AOV_DEPTH (#466) PURPOSE To improve .rpr export EFFECT OF CHANGE .rpr export now exports USD's depth AOV as RPR_AOV_DEPTH. --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index c088baa06..332b56eed 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2610,15 +2610,16 @@ Don't show this message again? if (aovDesc->id == kColorAlpha) { aovDesc = &HdRprAovRegistry::GetInstance().GetAovDesc(RPR_AOV_COLOR, false); } else if (aovDesc->id == kNdcDepth) { - // RprsRender does not support it...yet? - continue; + // XXX: RprsRender does not support it but for the users, it is more expected if we map it to the linear depth instead of ignoring it at all + aovDesc = &HdRprAovRegistry::GetInstance().GetAovDesc(RPR_AOV_DEPTH, false); } else { fprintf(stderr, "Unprocessed computed AOV: %u\n", aovDesc->id); continue; } } - if (TF_VERIFY(aovDesc->id < kNumRprsAovNames) && + if (TF_VERIFY(aovDesc->id != kAovNone) && + TF_VERIFY(aovDesc->id < kNumRprsAovNames) && TF_VERIFY(!aovDesc->computed)) { auto aovName = kRprsAovNames[aovDesc->id]; if (aovDesc->id >= RPR_AOV_LPE_0 && aovDesc->id <= RPR_AOV_LPE_8) { From 1697a598867ea7e1aae802d7fa89f4c5b72e6468 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 22 Apr 2021 04:39:58 +0300 Subject: [PATCH 25/50] buildmaster: version update to 2.0.38 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 8791c1799..dd9ba0e65 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "37") +set(HD_RPR_PATCH_VERSION "38") From bbc13ae60d41cffbd135553d52c2a663490cf566 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 30 Apr 2021 00:40:27 +0300 Subject: [PATCH 26/50] RPRMaterialXLoader: fix passthrough node (#469) PURPOSE To fix crash when using standard_surface material. EFFECT OF CHANGE None, changes that lead to this behavior were not released. --- deps/rprMtlxLoader/rprMtlxLoader.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/deps/rprMtlxLoader/rprMtlxLoader.cpp b/deps/rprMtlxLoader/rprMtlxLoader.cpp index 105fbb801..debe11c6e 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.cpp +++ b/deps/rprMtlxLoader/rprMtlxLoader.cpp @@ -442,22 +442,20 @@ struct PassthroughNode : public RprNode { rpr_status SetInput(mx::TypedElement* downstreamElement, mx::ValueElement* upstreamValueElement, LoaderContext* context) override { if (downstreamElement->getName() == inputName) { - if (rprNode && isOwningRprNode) { - rprObjectDelete(rprNode); + if (rprNode && !isOwningRprNode) { + LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); + return RPR_ERROR_UNSUPPORTED; } - rprNode = nullptr; - auto status = rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_CONSTANT_TEXTURE, &rprNode); - if (status == RPR_SUCCESS) { - status = RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_VALUE, upstreamValueElement, context); - if (status == RPR_SUCCESS) { - isOwningRprNode = true; - } else { - rprObjectDelete(rprNode); - rprNode = nullptr; + if (!rprNode) { + auto status = rprMaterialSystemCreateNode(context->rprMatSys, RPR_MATERIAL_NODE_CONSTANT_TEXTURE, &rprNode); + if (status != RPR_SUCCESS) { + return status; } + isOwningRprNode = true; } - return status; + + return RprNode::SetInput(downstreamElement, RPR_MATERIAL_INPUT_VALUE, upstreamValueElement, context); } else { LOG(context, "Unsupported input: %s", downstreamElement->getName().c_str()); return RPR_ERROR_UNSUPPORTED; From a9d5a78aedfecde37292137d41a61ae4e552a715 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Fri, 30 Apr 2021 00:55:02 +0300 Subject: [PATCH 27/50] buildmaster: version update to 2.0.39 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index dd9ba0e65..b622f60dd 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "38") +set(HD_RPR_PATCH_VERSION "39") From af2a078457c2f3b1a19a9e5876dd0c0b1b3157bb Mon Sep 17 00:00:00 2001 From: George Shakula Date: Tue, 4 May 2021 20:39:19 +0300 Subject: [PATCH 28/50] Update to USD 21.05 (#472) --- pxr/imaging/plugin/hdRpr/light.cpp | 16 ++- pxr/imaging/plugin/hdRpr/rprApi.cpp | 14 +- pxr/imaging/rprUsd/coreImage.cpp | 24 ++-- pxr/imaging/rprUsd/coreImage.h | 6 +- pxr/imaging/rprUsd/imageCache.cpp | 2 +- pxr/imaging/rprUsd/materialRegistry.cpp | 6 +- pxr/imaging/rprUsd/util.cpp | 170 +++++++++++++++++++++--- pxr/imaging/rprUsd/util.h | 39 ++++-- 8 files changed, 222 insertions(+), 55 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/light.cpp b/pxr/imaging/plugin/hdRpr/light.cpp index fe241dea4..eb85ac857 100644 --- a/pxr/imaging/plugin/hdRpr/light.cpp +++ b/pxr/imaging/plugin/hdRpr/light.cpp @@ -31,6 +31,16 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE +#if PXR_VERSION >= 2105 +#define USD_LUX_TOKEN_SHAPING_IES_FILE UsdLuxTokens->inputsShapingIesFile +#define USD_LUX_TOKEN_SHAPING_CONE_ANGLE UsdLuxTokens->inputsShapingConeAngle +#define USD_LUX_TOKEN_SHAPING_CONE_SOFTNESS UsdLuxTokens->inputsShapingConeSoftness +#else +#define USD_LUX_TOKEN_SHAPING_IES_FILE UsdLuxTokens->shapingIesFile +#define USD_LUX_TOKEN_SHAPING_CONE_ANGLE UsdLuxTokens->shapingConeAngle +#define USD_LUX_TOKEN_SHAPING_CONE_SOFTNESS UsdLuxTokens->shapingConeSoftness +#endif + namespace { float GetDiskLightNormalization(GfMatrix4f const& transform, float radius) { @@ -401,7 +411,7 @@ void HdRprLight::Sync(HdSceneDelegate* sceneDelegate, } bool newLight = false; - auto iesFile = sceneDelegate->GetLightParamValue(id, UsdLuxTokens->shapingIesFile); + auto iesFile = sceneDelegate->GetLightParamValue(id, USD_LUX_TOKEN_SHAPING_IES_FILE); if (iesFile.IsHolding()) { auto& path = iesFile.UncheckedGet(); if (!path.GetResolvedPath().empty()) { @@ -411,8 +421,8 @@ void HdRprLight::Sync(HdSceneDelegate* sceneDelegate, } } } else { - auto coneAngle = sceneDelegate->GetLightParamValue(id, UsdLuxTokens->shapingConeAngle); - auto coneSoftness = sceneDelegate->GetLightParamValue(id, UsdLuxTokens->shapingConeSoftness); + auto coneAngle = sceneDelegate->GetLightParamValue(id, USD_LUX_TOKEN_SHAPING_CONE_ANGLE); + auto coneSoftness = sceneDelegate->GetLightParamValue(id, USD_LUX_TOKEN_SHAPING_CONE_SOFTNESS); if (coneAngle.IsHolding() && coneSoftness.IsHolding()) { if (auto light = rprApi->CreateSpotLight(coneAngle.UncheckedGet(), coneSoftness.UncheckedGet())) { m_light = light; diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 332b56eed..1677147e1 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -30,8 +30,6 @@ using json = nlohmann::json; #include "renderParam.h" #include "pxr/imaging/rprUsd/util.h" -#include "pxr/imaging/glf/uvTextureData.h" - #include "pxr/imaging/rprUsd/config.h" #include "pxr/imaging/rprUsd/error.h" #include "pxr/imaging/rprUsd/helpers.h" @@ -3405,16 +3403,16 @@ Don't show this message again? return false; } - auto textureData = GlfUVTextureData::New(path, INT_MAX, 0, 0, 0, 0); - if (textureData && textureData->Read(0, false)) { + auto textureData = RprUsdTextureData::New(path); + if (textureData) { rif_image_desc imageDesc = {}; - imageDesc.image_width = textureData->ResizedWidth(); - imageDesc.image_height = textureData->ResizedHeight(); + imageDesc.image_width = textureData->GetWidth(); + imageDesc.image_height = textureData->GetHeight(); imageDesc.image_depth = 1; imageDesc.image_row_pitch = 0; imageDesc.image_slice_pitch = 0; - auto textureMetadata = RprUsdGetGlfTextureMetadata(&(*textureData)); + auto textureMetadata = textureData->GetGLMetadata(); uint8_t bytesPerComponent; if (textureMetadata.glType == GL_UNSIGNED_BYTE) { @@ -3449,7 +3447,7 @@ Don't show this message again? return false; } size_t imageSize = bytesPerComponent * imageDesc.num_components * imageDesc.image_width * imageDesc.image_height; - std::memcpy(mappedData, textureData->GetRawBuffer(), imageSize); + std::memcpy(mappedData, textureData->GetData(), imageSize); RIF_ERROR_CHECK(rifImageUnmap(rifImage->GetHandle(), mappedData), "Failed to unmap rif image"); auto colorRb = static_cast(colorOutputRb->aovBinding->renderBuffer); diff --git a/pxr/imaging/rprUsd/coreImage.cpp b/pxr/imaging/rprUsd/coreImage.cpp index a2723c0e1..c9ce21783 100644 --- a/pxr/imaging/rprUsd/coreImage.cpp +++ b/pxr/imaging/rprUsd/coreImage.cpp @@ -39,13 +39,13 @@ rpr::ImageDesc GetRprImageDesc(rpr::ImageFormat format, uint32_t width, uint32_t } template -std::unique_ptr _ConvertTexture(GlfUVTextureData* textureData, rpr::ImageFormat const& srcFormat, uint32_t dstNumComponents, PixelConverterFunc&& converter) { - uint8_t* src = textureData->GetRawBuffer(); +std::unique_ptr _ConvertTexture(RprUsdTextureData* textureData, rpr::ImageFormat const& srcFormat, uint32_t dstNumComponents, PixelConverterFunc&& converter) { + uint8_t* src = textureData->GetData(); size_t srcPixelStride = srcFormat.num_components * sizeof(ComponentT); size_t dstPixelStride = dstNumComponents * sizeof(ComponentT); - size_t numPixels = size_t(textureData->ResizedWidth()) * textureData->ResizedHeight(); + size_t numPixels = size_t(textureData->GetWidth()) * textureData->GetHeight(); auto dstData = std::make_unique(numPixels * dstPixelStride); uint8_t* dst = dstData.get(); @@ -66,7 +66,7 @@ template <> struct WhiteColor { }; template -std::unique_ptr ConvertTexture(GlfUVTextureData* textureData, rpr::ImageFormat const& format, uint32_t dstNumComponents) { +std::unique_ptr ConvertTexture(RprUsdTextureData* textureData, rpr::ImageFormat const& format, uint32_t dstNumComponents) { if (dstNumComponents < format.num_components) { // Trim excessive channels return _ConvertTexture(textureData, format, dstNumComponents, @@ -129,10 +129,10 @@ std::unique_ptr ConvertTexture(GlfUVTextureData* textureData, rpr::Im return nullptr; } -rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData, uint32_t numComponentsRequired) { +rpr::Image* CreateRprImage(rpr::Context* context, RprUsdTextureData* textureData, uint32_t numComponentsRequired) { rpr::ImageFormat format = {}; - auto imageMetadata = RprUsdGetGlfTextureMetadata(textureData); + auto imageMetadata = textureData->GetGLMetadata(); switch (imageMetadata.glType) { case GL_UNSIGNED_BYTE: @@ -163,9 +163,9 @@ rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData, TF_RUNTIME_ERROR("Unsupported pixel data GLformat: %#x", imageMetadata.glFormat); return nullptr; } - rpr::ImageDesc desc = GetRprImageDesc(format, textureData->ResizedWidth(), textureData->ResizedHeight()); + rpr::ImageDesc desc = GetRprImageDesc(format, textureData->GetWidth(), textureData->GetHeight()); - auto textureBuffer = textureData->GetRawBuffer(); + auto textureBuffer = textureData->GetData(); std::unique_ptr convertedData; if (numComponentsRequired != 0 && @@ -181,7 +181,7 @@ rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData, if (convertedData) { textureBuffer = convertedData.get(); format.num_components = numComponentsRequired; - desc = GetRprImageDesc(format, textureData->ResizedWidth(), textureData->ResizedHeight()); + desc = GetRprImageDesc(format, textureData->GetWidth(), textureData->GetHeight()); } } @@ -198,12 +198,12 @@ rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData, } // namespace anonymous RprUsdCoreImage* RprUsdCoreImage::Create(rpr::Context* context, std::string const& path, uint32_t numComponentsRequired) { - auto textureData = GlfUVTextureData::New(path, INT_MAX, 0, 0, 0, 0); - if (!textureData || !textureData->Read(0, false)) { + auto textureData = RprUsdTextureData::New(path); + if (!textureData) { return nullptr; } - return Create(context, {{0, textureData.operator->()}}, numComponentsRequired); + return Create(context, {{0, textureData.get()}}, numComponentsRequired); } RprUsdCoreImage* RprUsdCoreImage::Create(rpr::Context* context, uint32_t width, uint32_t height, rpr::ImageFormat format, void const* data, rpr::Status* status) { diff --git a/pxr/imaging/rprUsd/coreImage.h b/pxr/imaging/rprUsd/coreImage.h index ae64eb6d8..d8064bddf 100644 --- a/pxr/imaging/rprUsd/coreImage.h +++ b/pxr/imaging/rprUsd/coreImage.h @@ -15,7 +15,7 @@ limitations under the License. #define PXR_IMAGING_RPR_USD_CORE_IMAGE_H #include "pxr/imaging/rprUsd/api.h" -#include "pxr/imaging/glf/uvTextureData.h" +#include "pxr/imaging/rprUsd/util.h" #include @@ -30,9 +30,9 @@ class RprUsdCoreImage { struct UDIMTile { uint32_t id; - GlfUVTextureData* textureData; + RprUsdTextureData* textureData; - UDIMTile(uint32_t id, GlfUVTextureData* textureData) : id(id), textureData(textureData) {} + UDIMTile(uint32_t id, RprUsdTextureData* textureData) : id(id), textureData(textureData) {} }; RPRUSD_API static RprUsdCoreImage* Create(rpr::Context* context, std::vector const& textureData, uint32_t numComponentsRequired); diff --git a/pxr/imaging/rprUsd/imageCache.cpp b/pxr/imaging/rprUsd/imageCache.cpp index 9c633a749..f287852fd 100644 --- a/pxr/imaging/rprUsd/imageCache.cpp +++ b/pxr/imaging/rprUsd/imageCache.cpp @@ -81,7 +81,7 @@ RprUsdImageCache::GetImage( // Assume that all tiles have the same colorspace // auto data = tiles[0].textureData; - GLenum internalFormat = RprUsdGetGlfTextureMetadata(data).internalFormat; + GLenum internalFormat = data->GetGLMetadata().internalFormat; if (internalFormat == GL_SRGB || internalFormat == GL_SRGB8 || internalFormat == GL_SRGB_ALPHA || diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 7894fc9f7..48e256215 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -12,7 +12,6 @@ limitations under the License. ************************************************************************/ #include "pxr/imaging/rprUsd/util.h" -#include "pxr/imaging/glf/uvTextureData.h" #include "pxr/imaging/rprUsd/materialRegistry.h" #include "pxr/imaging/rprUsd/imageCache.h" #include "pxr/imaging/rprUsd/debugCodes.h" @@ -133,7 +132,7 @@ void RprUsdMaterialRegistry::CommitResources( std::string path; uint32_t udimTileId; - GlfUVTextureDataRefPtr data; + RprUsdTextureDataRefPtr data; UniqueTextureInfo(std::string const& path, uint32_t udimTileId) : path(path), udimTileId(udimTileId), data(nullptr) {} @@ -180,8 +179,7 @@ void RprUsdMaterialRegistry::CommitResources( WorkParallelForN(uniqueTextures.size(), [&uniqueTextures](size_t begin, size_t end) { for (size_t i = begin; i < end; ++i) { - auto textureData = GlfUVTextureData::New(uniqueTextures[i].path, INT_MAX, 0, 0, 0, 0); - if (textureData && textureData->Read(0, false)) { + if (auto textureData = RprUsdTextureData::New(uniqueTextures[i].path)) { uniqueTextures[i].data = textureData; } else { TF_RUNTIME_ERROR("Failed to load %s texture", uniqueTextures[i].path.c_str()); diff --git a/pxr/imaging/rprUsd/util.cpp b/pxr/imaging/rprUsd/util.cpp index d9e754931..a4638486f 100644 --- a/pxr/imaging/rprUsd/util.cpp +++ b/pxr/imaging/rprUsd/util.cpp @@ -47,23 +47,163 @@ bool RprUsdInitGLApi() { #endif } -RprUsdGlfTextureMetadata RprUsdGetGlfTextureMetadata(GlfUVTextureData* uvTextureData) { - RprUsdGlfTextureMetadata ret = {}; #if PXR_VERSION >= 2011 -# if PXR_VERSION >= 2102 - auto hioFormat = uvTextureData->GetFormat(); -# else - auto hioFormat = uvTextureData->GetHioFormat(); -# endif - ret.glType = GlfGetGLType(hioFormat); - ret.glFormat = GlfGetGLFormat(hioFormat); - ret.internalFormat = GlfGetGLInternalFormat(hioFormat); -#else - ret.internalFormat = uvTextureData->GLInternalFormat(); - ret.glType = uvTextureData->GLType(); - ret.glFormat = uvTextureData->GLFormat(); -#endif + +static const RprUsdTextureData::GLMetadata g_GLMetadata[HioFormatCount] = +{ + // glFormat, glType, glInternatFormat // HioFormat + {GL_RED, GL_UNSIGNED_BYTE, GL_R8 }, // UNorm8 + {GL_RG, GL_UNSIGNED_BYTE, GL_RG8 }, // UNorm8Vec2 + {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8 }, // UNorm8Vec3 + {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8 }, // UNorm8Vec4 + + {GL_RED, GL_BYTE, GL_R8_SNORM }, // SNorm8 + {GL_RG, GL_BYTE, GL_RG8_SNORM }, // SNorm8Vec2 + {GL_RGB, GL_BYTE, GL_RGB8_SNORM }, // SNorm8Vec3 + {GL_RGBA, GL_BYTE, GL_RGBA8_SNORM }, // SNorm8Vec4 + + {GL_RED, GL_HALF_FLOAT, GL_R16F }, // Float16 + {GL_RG, GL_HALF_FLOAT, GL_RG16F }, // Float16Vec2 + {GL_RGB, GL_HALF_FLOAT, GL_RGB16F }, // Float16Vec3 + {GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F }, // Float16Vec4 + + {GL_RED, GL_FLOAT, GL_R32F }, // Float32 + {GL_RG, GL_FLOAT, GL_RG32F }, // Float32Vec2 + {GL_RGB, GL_FLOAT, GL_RGB32F }, // Float32Vec3 + {GL_RGBA, GL_FLOAT, GL_RGBA32F }, // Float32Vec4 + + {GL_RED, GL_DOUBLE, GL_RED }, // Double64 + {GL_RG, GL_DOUBLE, GL_RG }, // Double64Vec2 + {GL_RGB, GL_DOUBLE, GL_RGB }, // Double64Vec3 + {GL_RGBA, GL_DOUBLE, GL_RGBA }, // Double64Vec4 + + {GL_RED, GL_UNSIGNED_SHORT,GL_R16UI }, // UInt16 + {GL_RG, GL_UNSIGNED_SHORT,GL_RG16UI }, // UInt16Vec2 + {GL_RGB, GL_UNSIGNED_SHORT,GL_RGB16UI }, // UInt16Vec3 + {GL_RGBA, GL_UNSIGNED_SHORT,GL_RGBA16UI }, // UInt16Vec4 + + {GL_RED, GL_SHORT, GL_R16I }, // Int16 + {GL_RG, GL_SHORT, GL_RG16I }, // Int16Vec2 + {GL_RGB, GL_SHORT, GL_RGB16I }, // Int16Vec3 + {GL_RGBA, GL_SHORT, GL_RGBA16I }, // Int16Vec4 + + {GL_RED, GL_UNSIGNED_INT, GL_R32UI }, // UInt32 + {GL_RG, GL_UNSIGNED_INT, GL_RG32UI }, // UInt32Vec2 + {GL_RGB, GL_UNSIGNED_INT, GL_RGB32UI }, // UInt32Vec3 + {GL_RGBA, GL_UNSIGNED_INT, GL_RGBA32UI }, // UInt32Vec4 + + {GL_RED, GL_INT, GL_R32I }, // Int32 + {GL_RG, GL_INT, GL_RG32I }, // Int32Vec2 + {GL_RGB, GL_INT, GL_RGB32I }, // Int32Vec3 + {GL_RGBA, GL_INT, GL_RGBA32I }, // Int32Vec4 + + {GL_NONE, GL_NONE, GL_NONE }, // UNorm8srgb - not supported by OpenGL + {GL_NONE, GL_NONE, GL_NONE }, // UNorm8Vec2srgb - not supported by OpenGL + {GL_RGB, GL_UNSIGNED_BYTE, GL_SRGB8, }, // UNorm8Vec3srgb + {GL_RGBA, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8 }, // UNorm8Vec4sRGB + + {GL_RGB, GL_FLOAT, + GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT }, // BC6FloatVec3 + {GL_RGB, GL_FLOAT, + GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT }, // BC6UFloatVec3 + {GL_RGBA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_RGBA_BPTC_UNORM }, // BC7UNorm8Vec4 + {GL_RGBA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM }, // BC7UNorm8Vec4srgb + {GL_RGBA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT }, // BC1UNorm8Vec4 + {GL_RGBA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT }, // BC3UNorm8Vec4 +}; + +#endif // PXR_VERSION >= 2011 + +#if PXR_VERSION >= 2105 + +std::shared_ptr RprUsdTextureData::New(std::string const& filepath) { + auto ret = std::make_unique(); + auto hioImage = HioImage::OpenForReading(filepath); + if (!hioImage) { + return nullptr; + } + + ret->_hioStorageSpec.width = hioImage->GetWidth(); + ret->_hioStorageSpec.height = hioImage->GetHeight(); + ret->_hioStorageSpec.depth = 1; + ret->_hioStorageSpec.format = hioImage->GetFormat(); + ret->_hioStorageSpec.flipped = false; + + size_t dataSize = ret->_hioStorageSpec.width * ret->_hioStorageSpec.height * HioGetDataSizeOfFormat(ret->_hioStorageSpec.format); + ret->_data = std::make_unique(dataSize); + ret->_hioStorageSpec.data = ret->_data.get(); + + if (!hioImage->Read(ret->_hioStorageSpec)) { + return nullptr; + } + + return ret; +} + +uint8_t* RprUsdTextureData::GetData() const { + return _data.get(); +} + +int RprUsdTextureData::GetWidth() const { + return _hioStorageSpec.width; +} + +int RprUsdTextureData::GetHeight() const { + return _hioStorageSpec.height; +} + +RprUsdTextureData::GLMetadata RprUsdTextureData::GetGLMetadata() const { + return g_GLMetadata[_hioStorageSpec.format]; +} + +#else // PXR_VERSION < 2105 + +std::shared_ptr RprUsdTextureData::New(std::string const& filepath) { + auto ret = std::make_unique(); + + ret->_uvTextureData = GlfUVTextureData::New(filepath, INT_MAX, 0, 0, 0, 0); + if (!ret->_uvTextureData || !ret->_uvTextureData->Read(0, false)) { + return nullptr; + } + return ret; } +uint8_t* RprUsdTextureData::GetData() const { + return _uvTextureData->GetRawBuffer(); +} + +int RprUsdTextureData::GetWidth() const { + return _uvTextureData->ResizedWidth(); +} + +int RprUsdTextureData::GetHeight() const { + return _uvTextureData->ResizedHeight(); +} + +RprUsdTextureData::GLMetadata RprUsdTextureData::GetGLMetadata() const { +#if PXR_VERSION >= 2011 + +# if PXR_VERSION >= 2102 + HioFormat hioFormat = _uvTextureData->GetFormat(); +# else // PXR_VERSION < 2102 + HioFormat hioFormat = _uvTextureData->GetHioFormat(); +# endif // PXR_VERSION >= 2102 + return g_GLMetadata[hioFormat]; + +#else // PXR_VERSION < 2011 + RprUsdTextureData::GLMetadata ret; + ret.internalFormat = _uvTextureData->GLInternalFormat(); + ret.glType = _uvTextureData->GLType(); + ret.glFormat = _uvTextureData->GLFormat(); + return ret; +#endif // PXR_VERSION >= 2011 +} + +#endif // PXR_VERSION >= 2105 + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/rprUsd/util.h b/pxr/imaging/rprUsd/util.h index d9b912140..7f7130213 100644 --- a/pxr/imaging/rprUsd/util.h +++ b/pxr/imaging/rprUsd/util.h @@ -22,26 +22,47 @@ limitations under the License. #include "pxr/imaging/glf/glew.h" #endif +#if PXR_VERSION >= 2105 +#include "pxr/imaging/hio/image.h" +#else #include "pxr/imaging/glf/uvTextureData.h" +#endif #include PXR_NAMESPACE_OPEN_SCOPE -RPRUSD_API -bool RprUsdGetUDIMFormatString(std::string const& filepath, std::string* out_formatString); +class RPRUSD_API RprUsdTextureData { +public: + static std::shared_ptr New(std::string const& filepath); -RPRUSD_API -bool RprUsdInitGLApi(); + uint8_t* GetData() const; + int GetWidth() const; + int GetHeight() const; + + struct GLMetadata { + GLenum glFormat; + GLenum glType; + GLenum internalFormat; + }; + GLMetadata GetGLMetadata() const; -struct RprUsdGlfTextureMetadata { - GLenum glType; - GLenum glFormat; - GLenum internalFormat; +private: +#if PXR_VERSION >= 2105 + HioImage::StorageSpec _hioStorageSpec; + std::unique_ptr _data; +#else // PXR_VERSION < 2105 + GlfUVTextureDataRefPtr _uvTextureData; +#endif }; +using RprUsdTextureDataRefPtr = std::shared_ptr; + +RPRUSD_API +bool RprUsdGetUDIMFormatString(std::string const& filepath, std::string* out_formatString); + RPRUSD_API -RprUsdGlfTextureMetadata RprUsdGetGlfTextureMetadata(GlfUVTextureData* uvTextureData); +bool RprUsdInitGLApi(); PXR_NAMESPACE_CLOSE_SCOPE From c73187f64a0927edf882230042ce71c4c1b9f1c3 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Tue, 4 May 2021 20:39:40 +0300 Subject: [PATCH 29/50] Tweak .rpr export node (#473) PURPOSE Such variables as $OS were not correctly expanded in Houdini's params. EFFECT OF CHANGE .rpr export node now correctly expands such expression variables as $OS. --- .../plugin/rprHoudini/hda/rpr_exportRpr1.hda | Bin 10578 -> 11637 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda index ce88fe6a9e2b4cfa8be16a360308592a1c7c421c..c63bbca3bd79f5b678561ef3882bf94fe678a8a5 100644 GIT binary patch delta 3329 zcmb7EX*?AC7M_NTWo)5B#+d9|Gsu!iS+isqZ_1LHF(Z>Fv_SxSj4Lm^}rLS)Il zX5Z({zNR8uN@OdSce(e=`@6q;&zEz~bDrmap7Z5DXt`k%CCe18M~+qy{Ue#5Vv)B( z9|9hEhX5UNL?5}As`P@VrHJ(LqMSUm9{!;t?-ruXt3M>`RS z_f$vB@yF@mv(ffkTKrUb};HYHoO8@r-g#UVhyD!z5d2mNVAJn)4-o1Fi#GeyQ27L{ z?bF&-#{;S+3(L3JY&Ob=+=N|qzX*LBcpx*TSoWaf%X!P&=CywBQZzl+V(utFlA?ktO?1mN8xlV*PY>PYNfcMVT8eCMqQ8V zV)}4_)A+)V-4|J&X}=em=Pt#_z z8-^w5yi+jq*Y6Rtn%Cddt-t!xm5$%lDa;e}P-wz=VERsQ(fkGGIz6S!aRY4?ElsDo zKzF|&V1DGZWhBd&5NoazeU}oni}eOz!}*oy7Yu<)}1g-eOfXvIe)BQhYE3CX%ZmCTI$9|nbaX%<(|YZ{+)9{0!crb#07{JPW!caWf4 zr8m7T?ECJXqt(3U=1(L?Sz9N~3#YtL#o zl#nROw%+(DmH9VX{?E)Wo&A9w4<@_wKf|?!7GVf>TDGsYlHv1S5Z}7L`!+#kd-A;C z&v6xtxfR@Z4AoPku8L@NRcCpvpnsM-Zkxc?X6>oz<#T#aw`g)aHf3qc4>f!{`Sdp% zrg;+N;wztkY43gG;pt&6ozvS~ieu|FCzorcZ!Hygo*AmTlaXW6_X|<0u7s_1Bqm0O zj+SiJ(gO1BuBEb5iMG?5zjVe@;5_>g_kX>vsLxpu`8~^qhz+!m|H-dE_efVOmpEFt zUpcThu_ZtNIS4h}cG&pM27$7j_K!1UVoYxYyk;zyhKEUyAuu_@={yXUnrb#0h-2>Szwu#PDW}rP-llijCEu z3FaFOmgFy%y3f3@o3M8|FO^BaL6LR7zvB7(h-kS>7ogyN>mfg>sgzdAwZft2u9hxu zAFX=fz;e@;#&8TMHmUQNnPy6ZO~D(Q26vYuON!wkTjS8_ zcIw;9r*BoZ*5SfsPx*5`VaepfDj+>m+K=_w=pra;_oiIzXw7v z(QO!Q>CLIIqsg)m>T>W{o<`tc-L;7KmW+wdl7`nACnj}M9i5=h{IHyM&U>Qs3T&1~soi;~)@=x!!_2xd1FJF!ZIXtw z;|;}4M#4sgza;ad?W6?#8h+_hOZi>hL80hl3VfB849^n&%H|#Dr)7~GD9*&`fsp?2 zJc8do`$dQ(OU&7x1fh^MO8rsouWtm-WnB~2qPgqoF$GP5 z+VrZ&^O&HOx$}(%!0Hy!t zL~u(kJO0NUvk#FL-F>%~?etc5zr2r_4}cxMy|9%yb!_AA71b)~hx+1){{Ja;U!3%aCsdD?X>q+(>X)LyWXU?d_*LlDh73Sli z!X;`(+_%^zzJ08+hBx*ZSkkiRC)MHws~ZTVWv)@cXM1kxXTOmQ+xhz_4pUK=*5SD| zo$Hq@l_+hc8|lQNxJRfgqO4D+Y86M8c2HiBgOyI4%l5_HE}>BX3i1i}I8}*^_)$%9 zKKMo_MvULle20lj1BRfNXFxv8gti|g>G|r&jE|-s2^GaSba#zumd&vfsX>~+gs1+f z%3agE4HZAhz_3SxcY|2$XA|(qZt6RB2}kqcAgmnLqCDm8$rgHTl+@aXi1`;e5g{Hs z2Fjjq-{GTM%*qlN0!$L_e5^s4E{o?9;A=_GR2u|nS>~ua`+MUHi$ou7l`|mG)=#7E z00rF|z$<<+%qHEalZkSMbg?3bj|1#cQPeK67Ok;RJf0OKssohP5ZSuv8K zosNs02l$RAhM(x@ti`p4mVu4)?9JQ3T-TLD-nQlVwu?e}daeZAcJGsqf;G1=T_TU^ z3Xb+H!J2}f*$Hkl8ymUp-j6l>9%o*hDu$HzwaBk}U9%v&Ms^h!Jvs_s7(*fvh zzwSKyy#7?k7Wv%f>Q+z{wq5Ot7};J-9oFt@UA;B&sZ7C3(F`kttSjI+BCLPl9hg>$k) zlDH!yD-^>0>i7G8|9U@O&*$^?c)#{;jasH(q{oc!Jdzdu-(x1oD0#`{F9@vq3-C~o zlqjeAUjhICn?Vr5H5g ^@4e3;>+!002_@>+oJ60d+3lKcn0~DZ_PyZvX&r=lxj& z{$Z@vD3mW+4(*BXMgCvW|5cm#4iLnc=WnU-Z)t$?4@US0qvbsA0RRsP09Z=@QB1ao zAhZ|C9{@!D{0E%+7vFG4`CHi<{=tEG7~MHK(F42|9hBul_@ARf{zi=mIyKHlalV>U zSQceaa~d>y(SRf0V{%HBy`Wsn1#J#VZVq__*DD=ErU1W*bLrzf4dquG3ViReXP8sj zz7gli0sC7;G;ih1&i#2|n`G?{Co_lRgc@(dk%)VC@j43@#*!LxO-bDwnxp%=9mrWi z+l}7Y$G9jXhnY~nk6*cmuTUd8^*S-waS!()yL>d63^^^M7^_;*ylXoCWiw24WjL&- zd`CSH;@y-7J>!eC;_I0BbgUO<21m86f6<-H6Ay88Q(SGM3N*@=t4gpF7y&l*@pipn zMLo26_IaaJvKEt)C{$deZ^tkFby4TRzUkT8O-(_DQqO5n`ha&)EAKWu5Q#POU_UZ? zk6SbMO?HbxCF3Bx9KhVp>CJvzgF#fdM0)@~c8SE6^e%<>rIU%e0bVY*#id({05(QN zqrRy5so9hi%O;D8q)u-rn{&~;PAfL?C{ghji}QaYUn|6iCYTfjz@KXI>`n_jje1HC zpT@Vf)>i8YIX#E$jmYHAWAkzG*aJ7c}%qDX`-?qj%7%#8UU$mw{=$yuQGTGp zVT)_=$Nuo$z+g;ZC}yOpCgyF$USCC6MXZ$6WOj%^sF!TuiYeCSUWre&pUryMufE%e znBAX*s^y{0*$wBF&od-;&+@4zMpb0|}>)u+{UKRjIy+cZ4GW*i->lS}cOp%Gjx+An+B1h#1Q6Yr$x1r1#3@%1@-{^aQ zlqmLyj-eWnI+&vVg-G^3>)an<%cQ~v2x@^YN-|don*OQH;lQp&C|Lep>yX|(Ncy~B zaClO;aSC%F9_PX~@ga&&I;go;oGFu5Zh;b7{@xXxAQ+iSCTL3w0X+%0VLjhki}8>YT& zDX%k(6e3qEhz-_bi4qEqW_c;kHC6q#$L%Iw=^SB6&7bczzmA07nd05n)WomcLgLyc zE!0%-d#|>L^j)*x@<Pm-N!5oTudu zMOWcH4|^x0G5u)$3*KuZkAyyp3DPQ>2V_-h(_`5Z%yVRJn!`E8{GV6f&X25Nq*5Tc zKbElR38dEdOM~M?*2$_`-n(tfBKNUMMh(8-hrJ-y_s0?1A#tH?h3Re9FX~ca4_pQ- zOcueRBL0Q@1?U1~l_c8o+Gq71?HR4mn%NScT6q>xL2?0tfpEZ(x%Qnf5|gYi^l~at z{Eig}Ij&OOy3k3vet~JZ@k~GeHN{`L9@^N&Kp(&BY;)G#+gYq#*SD?DGF!~X2Un+( zIm(oRvrB6vjX#)jDhyl~IPDgUiOw{i*{Bhknq+t20~J|8$cCM{i<_yf)}RrKY@(_h zW^c;!10Mg*Ke;t*SpB0taVg5td(Rjv5Wb|xg2>u^QIPoKIa^*7b6{4@A=hDK6k{j zCxB2=bEVR76y_{(A{$y&tlPt81z&Non2bDad2uz8#BCSlpi%Zd;jlc?J47V=N{(Ek zQ07$8H_mGxg?ACs+#4^RoLbu9jhV-8e((O#9otRe(%`UvWo+==vqmOKk|kAi`cl7O zw%boq1o3KL=gnbS29JDL+AU(rL6bdL{8%204DQhxxoGb9qzau*Er!W4;*J`#N(Okc zM&H)E3>MB+M3M?@}z2j-u~GDLn+m5#V_;K>F)e|U1t_{B9wC%_F4SXXG7p8Bo$C$9-Pu?h^90#|+tyL78k zzuQyU${P1@LnzV)L5NhwRUcje9$4ZSvCVLFx4{)Ae;cbT`V=CQSifl!=~jXcl?aoz zG-+_?XT8yJ8Jm>Ap>`+ioSoqs zar20DErT`a5t|vNi9E#yzQV3ks8EWo;Juo3MYYWTtsSk?GB~}m`nWWn{CzJe`PGR~ z{POx7Oy!wW$eOO$O2O%9TYnLg@zMb{H@x>QM&yNuge3L4f(TBQasz1<| z40S0sYgJ9zRVf<`i=_|4;+@&I_(v1vAHDmPsBy1rnGU`&afyo`jf(Ei9`~!+(l^+6 zKqbTD?^G=+(eBVe_|O3E42*Dt{oU1BON?~p3t4Tc{suW8Y^>qA2&f0Yd9x^CILnSe zA=sw1H2$iCVdgjEPz`>GFSqnq$w1sz(q)4l+4iqaoB{9dcR)HPyVB$yCK3%O3;UGE zfy#oLolxN-sL;dvh9v_)#QY7vtc`_|1i2J>p=)CE6&)`omr{FJx@+(F)PzS|W;B){ zOb^5>#!^3EdmoXPOV1#_-x__`f;pA&TFp3lBfqeaAF-;eG=?#57cOrTN6w6c`5K>g z$vSHYS}c2i^I+y}lP+|PCPBE82KFlr22zcXDPI#g9J-}k6QhZb3uue>i+A6^YoQ|u zW>_iUAXpW|c+qPHUsfN)ZA;~X-@mCYpAib-^_o1A4xz?}nkR-*^^;u@@$~8;t+*mfEj^v64n!`RR*hQ6p zd;>FA6^fh1wH%A5iWtj%h}s!6O{gn&U)hW7vs1NTafE%Im-Nla=fn*fUtz#0SK=aJ zS;|;9SL!OgtsDn$L_>MrqkUEWQzFOGJ(vk{=E< zz%d{#jVUqB4~P3cA1XqjsJdFGqAirhHaBgHSSar|ROnAlG3#IaUSUj;cKF!n$YTe7 zL;d~u=&)gKxM$kJi?@PnP Date: Tue, 4 May 2021 20:40:20 +0300 Subject: [PATCH 30/50] Add toon shader node (#470) PURPOSE Adds a toon shader node for users EFFECT OF CHANGE Users can create toon shader looks. --- deps/RPR | 2 +- pxr/imaging/rprUsd/CMakeLists.txt | 1 + .../materialNodes/rpr/arithmeticNode.cpp | 9 +- .../rprUsd/materialNodes/rpr/catcherNode.cpp | 10 +- .../materialNodes/rpr/combineShadersNode.cpp | 6 +- .../rprUsd/materialNodes/rpr/displaceNode.cpp | 14 +- .../materialNodes/rpr/materialXNode.cpp | 12 +- .../rprUsd/materialNodes/rpr/nodeInfo.h | 59 +++++- .../rprUsd/materialNodes/rpr/toonNode.cpp | 172 ++++++++++++++++++ 9 files changed, 259 insertions(+), 26 deletions(-) create mode 100644 pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp diff --git a/deps/RPR b/deps/RPR index 5ca51cc43..3b2ac06d9 160000 --- a/deps/RPR +++ b/deps/RPR @@ -1 +1 @@ -Subproject commit 5ca51cc43b41f04e812b393ffcb402f9a6b56f9f +Subproject commit 3b2ac06d9de9de99f5cb7aa1e2bce9579c411767 diff --git a/pxr/imaging/rprUsd/CMakeLists.txt b/pxr/imaging/rprUsd/CMakeLists.txt index 38b9b5ec1..066c95da5 100644 --- a/pxr/imaging/rprUsd/CMakeLists.txt +++ b/pxr/imaging/rprUsd/CMakeLists.txt @@ -61,6 +61,7 @@ target_sources(rprUsd PRIVATE materialNodes/rpr/baseNode.h materialNodes/rpr/baseNode.cpp materialNodes/rpr/nodeInfo.h + materialNodes/rpr/toonNode.cpp materialNodes/rpr/catcherNode.cpp materialNodes/rpr/displaceNode.cpp materialNodes/rpr/materialXNode.cpp diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/arithmeticNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/arithmeticNode.cpp index ca9d21568..0897933f3 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/arithmeticNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/arithmeticNode.cpp @@ -9,6 +9,13 @@ PXR_NAMESPACE_OPEN_SCOPE +TF_DEFINE_PRIVATE_TOKENS(_tokens, + (color0) + (color1) + (color2) + (color3) +); + template RprUsd_MaterialNode* RprUsd_CreateRprNode( RprUsd_MaterialBuilderContext* ctx, @@ -33,7 +40,7 @@ RprUsd_RprNodeInfo* GetNodeInfo() { for (int i = 0; i < Node::kArity; ++i) { RprUsd_RprNodeInput input(RprUsd_RprNodeInput::kColor3); - input.name = TfStringPrintf("color%d", i); + input.name = _tokens->allTokens[i]; input.uiName = TfStringPrintf("Color %d", i); input.valueString = "0,0,0"; input.uiSoftMin = "0"; diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/catcherNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/catcherNode.cpp index 5ba58719f..7b92b250e 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/catcherNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/catcherNode.cpp @@ -20,7 +20,7 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_PRIVATE_TOKENS(RprUsdRprCatcherNodeTokens, +TF_DEFINE_PRIVATE_TOKENS(_tokens, (in) (enable) ); @@ -49,10 +49,10 @@ class RprUsd_RprCatcherNode : public RprUsd_MaterialNode { bool SetInput( TfToken const& inputId, VtValue const& value) override { - if (inputId == RprUsdRprCatcherNodeTokens->in) { + if (inputId == _tokens->in) { m_output = value; return true; - } else if (inputId == RprUsdRprCatcherNodeTokens->enable) { + } else if (inputId == _tokens->enable) { if (value.IsHolding()) { *m_catcherToggle = value.UncheckedGet() != 0; return true; @@ -72,11 +72,11 @@ class RprUsd_RprCatcherNode : public RprUsd_MaterialNode { nodeInfo.name = "rpr_" + catcherType + "_catcher"; RprUsd_RprNodeInput in(RprUsdMaterialNodeElement::kSurfaceShader); - in.name = "in"; + in.name = _tokens->in; nodeInfo.inputs.push_back(in); RprUsd_RprNodeInput enable(RprUsdMaterialNodeElement::kBoolean); - enable.name = "enable"; + enable.name = _tokens->enable; enable.uiName = "Enable"; enable.valueString = "true"; nodeInfo.inputs.push_back(enable); diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/combineShadersNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/combineShadersNode.cpp index 7335443a0..9b67ce54f 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/combineShadersNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/combineShadersNode.cpp @@ -72,17 +72,17 @@ class RprUsd_RprCombineShadersNode : public RprUsd_MaterialNode { nodeInfo.uiFolder = "Shaders"; RprUsd_RprNodeInput surfaceInput(RprUsdMaterialNodeElement::kSurfaceShader); - surfaceInput.name = "surface"; + surfaceInput.name = HdMaterialTerminalTokens->surface; surfaceInput.uiName = "Surface Shader"; nodeInfo.inputs.push_back(surfaceInput); RprUsd_RprNodeInput displacementInput(RprUsdMaterialNodeElement::kDisplacementShader); - displacementInput.name = "displacement"; + displacementInput.name = HdMaterialTerminalTokens->displacement; displacementInput.uiName = "Displacement Shader"; nodeInfo.inputs.push_back(displacementInput); RprUsd_RprNodeInput volumeInput(RprUsdMaterialNodeElement::kVolumeShader); - volumeInput.name = "volume"; + volumeInput.name = HdMaterialTerminalTokens->volume; volumeInput.uiName = "Volume Shader"; nodeInfo.inputs.push_back(volumeInput); diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/displaceNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/displaceNode.cpp index 79c2867f1..61014b53a 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/displaceNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/displaceNode.cpp @@ -20,7 +20,7 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_PRIVATE_TOKENS(RprUsdRprDisplaceNodeTokens, +TF_DEFINE_PRIVATE_TOKENS(_tokens, (minscale) (maxscale) (in) @@ -54,7 +54,7 @@ class RprUsd_RprDisplaceNode : public RprUsd_MaterialNode { bool SetInput( TfToken const& inputId, VtValue const& value) override { - if (inputId == RprUsdRprDisplaceNodeTokens->minscale) { + if (inputId == _tokens->minscale) { if (value.IsHolding()) { m_displacementScale[0] = value.UncheckedGet(); } else { @@ -62,7 +62,7 @@ class RprUsd_RprDisplaceNode : public RprUsd_MaterialNode { m_displacementScale[0] = 0.0f; return false; } - } else if (inputId == RprUsdRprDisplaceNodeTokens->maxscale) { + } else if (inputId == _tokens->maxscale) { if (value.IsHolding()) { m_displacementScale[1] = value.UncheckedGet(); } else { @@ -70,7 +70,7 @@ class RprUsd_RprDisplaceNode : public RprUsd_MaterialNode { m_displacementScale[1] = 1.0f; return false; } - } else if (inputId == RprUsdRprDisplaceNodeTokens->in) { + } else if (inputId == _tokens->in) { if (value.IsHolding>()) { m_output = value; } else { @@ -104,16 +104,16 @@ class RprUsd_RprDisplaceNode : public RprUsd_MaterialNode { input.uiSoftMin = "0"; input.uiSoftMax = "1"; - input.name = "in"; + input.name = _tokens->in; input.uiName = "Displacement"; input.valueString = "0"; nodeInfo.inputs.push_back(input); - input.name = "minscale"; + input.name = _tokens->minscale; input.uiName = "Minimum Scale"; nodeInfo.inputs.push_back(input); - input.name = "maxscale"; + input.name = _tokens->maxscale; input.uiName = "Maximum Scale"; input.valueString = "1"; nodeInfo.inputs.push_back(input); diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp index 453b280cd..11d090ce2 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp @@ -367,33 +367,33 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { nodeInfo.uiFolder = "Shaders"; RprUsd_RprNodeInput fileInput(RprUsdMaterialNodeElement::kFilepath); - fileInput.name = RprUsdRprMaterialXNodeTokens->file.GetText(); + fileInput.name = RprUsdRprMaterialXNodeTokens->file; fileInput.uiName = "File"; nodeInfo.inputs.push_back(fileInput); RprUsd_RprNodeInput stringInput(RprUsdMaterialNodeElement::kString); - stringInput.name = RprUsdRprMaterialXNodeTokens->string.GetText(); + stringInput.name = RprUsdRprMaterialXNodeTokens->string; stringInput.uiName = ""; // hide from UI nodeInfo.inputs.push_back(stringInput); RprUsd_RprNodeInput basePathInput(RprUsdMaterialNodeElement::kString); - basePathInput.name = RprUsdRprMaterialXNodeTokens->basePath.GetText(); + basePathInput.name = RprUsdRprMaterialXNodeTokens->basePath; basePathInput.uiName = ""; // hide from UI nodeInfo.inputs.push_back(basePathInput); RprUsd_RprNodeInput stPrimvarNameInput(RprUsdMaterialNodeElement::kString); - stPrimvarNameInput.name = RprUsdRprMaterialXNodeTokens->stPrimvarName.GetText(); + stPrimvarNameInput.name = RprUsdRprMaterialXNodeTokens->stPrimvarName; stPrimvarNameInput.uiName = "UV Primvar Name"; stPrimvarNameInput.valueString = "st"; nodeInfo.inputs.push_back(stPrimvarNameInput); RprUsd_RprNodeInput surfaceElementInput(RprUsdMaterialNodeElement::kString); - surfaceElementInput.name = RprUsdRprMaterialXNodeTokens->surfaceElement.GetText(); + surfaceElementInput.name = RprUsdRprMaterialXNodeTokens->surfaceElement; surfaceElementInput.uiName = "Surface Element"; nodeInfo.inputs.push_back(surfaceElementInput); RprUsd_RprNodeInput displacementElementInput(RprUsdMaterialNodeElement::kString); - displacementElementInput.name = RprUsdRprMaterialXNodeTokens->displacementElement.GetText(); + displacementElementInput.name = RprUsdRprMaterialXNodeTokens->displacementElement; displacementElementInput.uiName = "Displacement Element"; nodeInfo.inputs.push_back(displacementElementInput); diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/nodeInfo.h b/pxr/imaging/rprUsd/materialNodes/rpr/nodeInfo.h index 5364a904a..f2ec82cc5 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/nodeInfo.h +++ b/pxr/imaging/rprUsd/materialNodes/rpr/nodeInfo.h @@ -15,9 +15,44 @@ limitations under the License. #define RPRUSD_MATERIAL_NODES_RPR_NODE_INFO_H #include "pxr/imaging/rprUsd/materialRegistry.h" +#include "pxr/base/gf/vec2f.h" + +namespace std { + +PXR_NAMESPACE_USING_DIRECTIVE + +inline std::string to_string(GfVec2f const& v) { + return TfStringPrintf("%f,%f", v[0], v[1]); +} + +inline std::string to_string(GfVec3f const& v) { + return TfStringPrintf("%f,%f,%f", v[0], v[1], v[2]); +} + +inline std::string to_string(TfToken const& v) { + return v.GetString(); +} + +} // namespace std PXR_NAMESPACE_OPEN_SCOPE +template +struct ToRprUsdMaterialNodeInputType; + +#define DEFINE_TYPE_CONVERSION(c_type, material_type) \ + template <> \ + struct ToRprUsdMaterialNodeInputType { \ + static constexpr RprUsdMaterialNodeInput::Type value = RprUsdMaterialNodeInput::k##material_type; \ + }; + +DEFINE_TYPE_CONVERSION(bool, Boolean); +DEFINE_TYPE_CONVERSION(int, Integer); +DEFINE_TYPE_CONVERSION(float, Float); +DEFINE_TYPE_CONVERSION(GfVec2f, Vector2); +DEFINE_TYPE_CONVERSION(GfVec3f, Color3); +DEFINE_TYPE_CONVERSION(TfToken, Token); + struct RprUsd_RprNodeInput : public RprUsdMaterialNodeInput { RprUsd_RprNodeInput(RprUsdMaterialNodeInput::Type type) : RprUsdMaterialNodeInput(type) {} const char* GetName() const override { return GetCStr(name); } @@ -29,9 +64,26 @@ struct RprUsd_RprNodeInput : public RprUsdMaterialNodeInput { const char* GetUIFolder() const override { return GetCStr(uiFolder); } const char* GetDocString() const override { return GetCStr(docString); } const char* GetValueString() const override { return GetCStr(valueString); } - std::vector const& GetTokenValues() const override { return m_tokenValues; } + std::vector const& GetTokenValues() const override { return tokenValues; } - std::string name; + template + RprUsd_RprNodeInput(TfToken const& name, T defaultValue, RprUsdMaterialNodeInput::Type type = RprUsdMaterialNodeInput::kInvalid, const char* uiName = nullptr) + : RprUsdMaterialNodeInput(type != RprUsdMaterialNodeInput::kInvalid ? type : ToRprUsdMaterialNodeInputType::value) + , name(name) + , uiSoftMin("0") + , uiSoftMax("1") + , value(VtValue(defaultValue)) + , valueString(std::to_string(defaultValue)) { + if (!uiName) { + this->uiName = name.GetString(); + this->uiName[0] = ::toupper(this->uiName[0]); + } else { + this->uiName = uiName; + } + + } + + TfToken name; std::string uiName; std::string uiMin; std::string uiSoftMin; @@ -39,8 +91,9 @@ struct RprUsd_RprNodeInput : public RprUsdMaterialNodeInput { std::string uiSoftMax; std::string uiFolder; std::string docString; + VtValue value; std::string valueString; - std::vector m_tokenValues; + std::vector tokenValues; }; struct RprUsd_RprNodeOutput : public RprUsdMaterialNodeElement { diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp new file mode 100644 index 000000000..15c2ee3d8 --- /dev/null +++ b/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp @@ -0,0 +1,172 @@ +/************************************************************************ +Copyright 2020 Advanced Micro Devices, Inc +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +************************************************************************/ + +#include "baseNode.h" +#include "nodeInfo.h" + +#include "pxr/imaging/rprUsd/materialHelpers.h" +#include "pxr/base/arch/attributes.h" +#include "pxr/base/gf/vec3f.h" + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_PRIVATE_TOKENS(_tokens, + (roughness) + (normal) + (shadowColor) + (midLevel) + (midLevelMix) + (midColor) + (highlightLevel) + (highlightLevelMix) + (highlightColor) + (interpolationMode) + (Linear) + (None) +); + +template +bool ProcessInput(TfToken const& inputId, VtValue const& inputValue, SmartPtr const& rprNode, rpr::MaterialNodeInput rprInput) { + if (inputValue.IsHolding() || + inputValue.IsHolding()) { + return SetRprInput(rprNode.get(), rprInput, inputValue) == RPR_SUCCESS; + } + TF_RUNTIME_ERROR("Input `%s` has invalid type: %s, expected - %s", inputId.GetText(), inputValue.GetTypeName().c_str(), TfType::Find().GetTypeName().c_str()); + return false; +} + +/// \class RprUsd_RprToonNode +/// +/// The node that wraps RPR nodes required to setup correct RPR toon shader. +/// +class RprUsd_RprToonNode : public RprUsd_MaterialNode { +public: + RprUsd_RprToonNode(RprUsd_MaterialBuilderContext* ctx) { + + rpr::Status status; + m_toonClosureNode.reset(ctx->rprContext->CreateMaterialNode(RPR_MATERIAL_NODE_TOON_CLOSURE, &status)); + if (!m_toonClosureNode) { + throw RprUsd_NodeError(RPR_GET_ERROR_MESSAGE(status, "Failed to create toon closure node", ctx->rprContext)); + } + m_rampNode.reset(ctx->rprContext->CreateMaterialNode(RPR_MATERIAL_NODE_TOON_RAMP, &status)); + if (!m_rampNode) { + throw RprUsd_NodeError(RPR_GET_ERROR_MESSAGE(status, "Failed to create toon ramp node", ctx->rprContext)); + } + status = m_toonClosureNode->SetInput(RPR_MATERIAL_INPUT_DIFFUSE_RAMP, m_rampNode.get()); + if (status != RPR_SUCCESS) { + throw RprUsd_NodeError(RPR_GET_ERROR_MESSAGE(status, "Failed to set ramp node input of closure node", ctx->rprContext)); + } + } + ~RprUsd_RprToonNode() override = default; + + VtValue GetOutput(TfToken const& outputId) override { + return VtValue(m_toonClosureNode); + } + + bool SetInput( + TfToken const& id, + VtValue const& value) override { + if (id == _tokens->shadowColor) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_SHADOW); + } else if (id == _tokens->midLevel) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_POSITION1); + } else if (id == _tokens->midLevelMix) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_RANGE1); + } else if (id == _tokens->midColor) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_MID); + } else if (id == _tokens->highlightLevel) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_POSITION2); + } else if (id == _tokens->highlightLevelMix) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_RANGE2); + } else if (id == _tokens->highlightColor) { + return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_HIGHLIGHT); + } else if (id == _tokens->interpolationMode) { + if (value.IsHolding()) { + int interpolationModeInt = value.UncheckedGet(); + auto interpolationMode = !interpolationModeInt ? RPR_INTERPOLATION_MODE_NONE : RPR_INTERPOLATION_MODE_LINEAR; + return m_rampNode->SetInput(RPR_MATERIAL_INPUT_INTERPOLATION, interpolationMode) == RPR_SUCCESS; + } + TF_RUNTIME_ERROR("Input `%s` has invalid type: %s, expected - `Token`", id.GetText(), value.GetTypeName().c_str()); + return false; + } else if (id == _tokens->roughness) { + return ProcessInput(id, value, m_toonClosureNode, RPR_MATERIAL_INPUT_ROUGHNESS); + } else if (id == _tokens->normal) { + return ProcessInput(id, value, m_toonClosureNode, RPR_MATERIAL_INPUT_NORMAL); + } + + TF_RUNTIME_ERROR("Unknown input `%s` for RPR Toon node", id.GetText()); + return false; + } + + static RprUsd_RprNodeInfo* GetInfo() { + static RprUsd_RprNodeInfo* ret = nullptr; + if (ret) { + return ret; + } + + ret = new RprUsd_RprNodeInfo; + auto& nodeInfo = *ret; + + nodeInfo.name = "rpr_toon"; + nodeInfo.uiName = "RPR Toon"; + nodeInfo.uiFolder = "Shaders"; + + nodeInfo.inputs.emplace_back(_tokens->shadowColor, GfVec3f(0.0f)); + + nodeInfo.inputs.emplace_back(_tokens->midLevel, 0.5f); + nodeInfo.inputs.emplace_back(_tokens->midLevelMix, 0.05f); + nodeInfo.inputs.emplace_back(_tokens->midColor, GfVec3f(0.4f)); + nodeInfo.inputs.emplace_back(_tokens->highlightLevel, 0.8f); + nodeInfo.inputs.emplace_back(_tokens->highlightLevelMix, 0.05f); + nodeInfo.inputs.emplace_back(_tokens->highlightColor, GfVec3f(0.8f)); + + RprUsd_RprNodeInput interpolationModeInput(_tokens->interpolationMode, _tokens->None); + interpolationModeInput.value = VtValue(0); + interpolationModeInput.tokenValues = {_tokens->None, _tokens->Linear}; + nodeInfo.inputs.push_back(interpolationModeInput); + + nodeInfo.inputs.emplace_back(_tokens->roughness, 1.0f); + nodeInfo.inputs.emplace_back(_tokens->normal, GfVec3f(0.0f), RprUsdMaterialNodeElement::kVector3, ""); + + RprUsd_RprNodeOutput output(RprUsdMaterialNodeElement::kSurfaceShader); + output.name = "surface"; + nodeInfo.outputs.push_back(output); + + return ret; + } + +private: + std::unique_ptr m_rampNode; + std::shared_ptr m_toonClosureNode; +}; + +ARCH_CONSTRUCTOR(RprUsd_InitDisplaceNode, 255, void) { + auto nodeInfo = RprUsd_RprToonNode::GetInfo(); + RprUsdMaterialRegistry::GetInstance().Register( + TfToken(nodeInfo->name, TfToken::Immortal), + [](RprUsd_MaterialBuilderContext* context, std::map const& parameters) { + auto node = new RprUsd_RprToonNode(context); + for (auto& input : RprUsd_RprToonNode::GetInfo()->inputs) { + auto it = parameters.find(input.name); + if (it == parameters.end()) { + node->SetInput(input.name, input.value); + } else { + node->SetInput(input.name, it->second); + } + } + return node; + }, + nodeInfo); +} + +PXR_NAMESPACE_CLOSE_SCOPE From f03b0c1195d3299f3570e4e4cf39659c74b32c8d Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 4 May 2021 20:49:33 +0300 Subject: [PATCH 31/50] buildmaster: version update to 2.0.40 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index b622f60dd..2e31f0067 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "39") +set(HD_RPR_PATCH_VERSION "40") From 2eb96170e702bc749a7b7fd9303ec724c9eeca39 Mon Sep 17 00:00:00 2001 From: Aleksandr Gurov Date: Tue, 4 May 2021 22:45:37 +0300 Subject: [PATCH 32/50] Update mesh id on DirtyPrimId (#474) --- pxr/imaging/plugin/hdRpr/mesh.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index d399a3a9d..c3c8d4957 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -378,6 +378,8 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } + isIdDirty |= *dirtyBits & HdChangeTracker::DirtyPrimID; + m_smoothNormals = !m_displayStyle.flatShadingEnabled; // Don't compute smooth normals on a refined mesh. They are implicitly smooth. if (m_enableSubdiv && m_refineLevel != 0) { From 7adc67fde748f11daa806bec5bf48131152a2169 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 4 May 2021 22:49:34 +0300 Subject: [PATCH 33/50] buildmaster: version update to 2.0.41 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 2e31f0067..914ce0675 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "40") +set(HD_RPR_PATCH_VERSION "41") From dd8f0899407140070d775885db0d9f6d0b1a7644 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak <33626169+bnagirniak@users.noreply.github.com> Date: Wed, 19 May 2021 18:39:03 +0300 Subject: [PATCH 34/50] Made adjustments due to USD 21.05 changes: (#476) * Made adjustments due to USD 21.05 changes: - fixed getting light transform - added check for camera focus distance * Added PXR_VERSION check * Moved PXR_VERSION check to compile-time --- pxr/imaging/plugin/hdRpr/light.cpp | 4 ++++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pxr/imaging/plugin/hdRpr/light.cpp b/pxr/imaging/plugin/hdRpr/light.cpp index eb85ac857..319918071 100644 --- a/pxr/imaging/plugin/hdRpr/light.cpp +++ b/pxr/imaging/plugin/hdRpr/light.cpp @@ -397,7 +397,11 @@ void HdRprLight::Sync(HdSceneDelegate* sceneDelegate, HdDirtyBits bits = *dirtyBits; if (bits & DirtyBits::DirtyTransform) { +#if PXR_VERSION >= 2011 + m_transform = GfMatrix4f(sceneDelegate->GetTransform(id)); +#else m_transform = GfMatrix4f(sceneDelegate->GetLightParamValue(id, HdTokens->transform).Get()); +#endif } if (bits & DirtyParams) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 1677147e1..629cdf7e8 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1806,7 +1806,9 @@ class HdRprApiImpl { float focusDistance = 1.0f; m_hdCamera->GetFocusDistance(&focusDistance); - RPR_ERROR_CHECK(m_camera->SetFocusDistance(focusDistance), "Failed to set camera focus distance"); + if (focusDistance > 0.0f) { + RPR_ERROR_CHECK(m_camera->SetFocusDistance(focusDistance), "Failed to set camera focus distance"); + } float fstop = 0.0f; m_hdCamera->GetFStop(&fstop); From b027ba03ccb4f0c68a629269d0d5c63a2fcd326b Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Wed, 19 May 2021 18:55:19 +0300 Subject: [PATCH 35/50] buildmaster: version update to 2.0.42 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 914ce0675..3e7c6849b 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "41") +set(HD_RPR_PATCH_VERSION "42") From 57d5c74704c79d220a8ca4b799de3f33bfec1f9c Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 27 May 2021 19:15:17 +0300 Subject: [PATCH 36/50] Extend cryptomatte support (#475) * Extend cryptomatte support * Configurable cryptomatte names for materials and meshes * Cryptomatte export: * Export 6 levels of CryptoObject and CryptoMaterial * Embed manifests * Preview layer * Make cryptomatte .exr export support optional --- .gitmodules | 3 + cmake/defaults/Packages.cmake | 34 ++- deps/CMakeLists.txt | 9 + deps/murmurhash | 1 + pxr/imaging/plugin/hdRpr/CMakeLists.txt | 5 + pxr/imaging/plugin/hdRpr/material.cpp | 4 +- pxr/imaging/plugin/hdRpr/mesh.cpp | 17 +- pxr/imaging/plugin/hdRpr/mesh.h | 1 + pxr/imaging/plugin/hdRpr/primvarUtil.cpp | 3 + pxr/imaging/plugin/hdRpr/primvarUtil.h | 1 + .../python/generateGeometrySettingFiles.py | 7 + .../python/generateRenderSettingFiles.py | 41 +++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 278 +++++++++++++++++- pxr/imaging/plugin/hdRpr/rprApi.h | 2 +- .../rprHoudini/LOP_RPRMaterialProperties.cpp | 15 +- pxr/imaging/rprUsd/helpers.h | 51 +++- pxr/imaging/rprUsd/materialRegistry.cpp | 34 ++- pxr/imaging/rprUsd/materialRegistry.h | 1 + pxr/imaging/rprUsd/tokens.h | 3 +- 19 files changed, 456 insertions(+), 54 deletions(-) create mode 160000 deps/murmurhash diff --git a/.gitmodules b/.gitmodules index 185f0a949..43c4683e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "deps/ghc_filesystem"] path = deps/ghc_filesystem url = https://github.com/gulrak/filesystem +[submodule "deps/murmurhash"] + path = deps/murmurhash + url = https://github.com/aappleby/smhasher diff --git a/cmake/defaults/Packages.cmake b/cmake/defaults/Packages.cmake index 7471a62c9..1b086ca3e 100644 --- a/cmake/defaults/Packages.cmake +++ b/cmake/defaults/Packages.cmake @@ -99,20 +99,32 @@ else() find_package(OpenVDB QUIET) endif() -if(OpenVDB_FOUND) - if(HoudiniUSD_FOUND) - find_package(OpenEXR QUIET COMPONENTS Half_sidefx) - endif() - +macro(find_exr) if(NOT OpenEXR_FOUND) - find_package(OpenEXR QUIET COMPONENTS Half) - endif() + set(SIDEFX_COMPONENTS ${ARGV}) + list(TRANSFORM SIDEFX_COMPONENTS APPEND "_sidefx") - if(NOT OpenEXR_FOUND) - message(FATAL_ERROR "Failed to find Half library") + if(HoudiniUSD_FOUND) + find_package(OpenEXR QUIET COMPONENTS ${SIDEFX_COMPONENTS}) + endif() + + if(NOT OpenEXR_FOUND) + find_package(OpenEXR QUIET COMPONENTS ${ARGV}) + endif() endif() -else() - message(STATUS "Skipping OpenVDB support") +endmacro() + +find_exr(Half IlmImf Iex) + +set(RPR_EXR_EXPORT_ENABLED TRUE) +if(NOT OpenEXR_FOUND) + set(RPR_EXR_EXPORT_ENABLED FALSE) +endif() + +find_exr(Half) + +if(NOT OpenEXR_FOUND) + message(FATAL_ERROR "Failed to find Half library") endif() # ---------------------------------------------- diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index c355963e0..ad9c09bab 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -74,4 +74,13 @@ if(HoudiniUSD_FOUND) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ghc_filesystem) endif() +# Murmurhash +# ---------------------------------------------- + +set(MURMURHASH_DIR ${CMAKE_CURRENT_SOURCE_DIR}/murmurhash/src) +add_library(murmurhash STATIC + ${MURMURHASH_DIR}/MurmurHash3.h + ${MURMURHASH_DIR}/MurmurHash3.cpp) +target_include_directories(murmurhash PUBLIC ${MURMURHASH_DIR}) + # ---------------------------------------------- diff --git a/deps/murmurhash b/deps/murmurhash new file mode 160000 index 000000000..61a0530f2 --- /dev/null +++ b/deps/murmurhash @@ -0,0 +1 @@ +Subproject commit 61a0530f28277f2e850bfc39600ce61d02b518de diff --git a/pxr/imaging/plugin/hdRpr/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/CMakeLists.txt index c3f7d8f09..aae09e236 100644 --- a/pxr/imaging/plugin/hdRpr/CMakeLists.txt +++ b/pxr/imaging/plugin/hdRpr/CMakeLists.txt @@ -98,6 +98,7 @@ pxr_plugin(hdRpr cameraUtil rprUsd json + murmurhash ${RIF_LIBRARY} ${OPENEXR_LIBRARIES} @@ -151,6 +152,10 @@ pxr_plugin(hdRpr ndrParserPlugin.cpp ) +if(RPR_EXR_EXPORT_ENABLED) + target_compile_definitions(hdRpr PRIVATE -DRPR_EXR_EXPORT_ENABLED) +endif() + target_sources(hdRpr PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/notify/message.h) if(APPLE) diff --git a/pxr/imaging/plugin/hdRpr/material.cpp b/pxr/imaging/plugin/hdRpr/material.cpp index 3e20c7592..3b0c01264 100644 --- a/pxr/imaging/plugin/hdRpr/material.cpp +++ b/pxr/imaging/plugin/hdRpr/material.cpp @@ -41,7 +41,7 @@ void HdRprMaterial::Sync(HdSceneDelegate* sceneDelegate, VtValue vtMat = sceneDelegate->GetMaterialResource(GetId()); if (vtMat.IsHolding()) { auto& networkMap = vtMat.UncheckedGet(); - m_rprMaterial = rprApi->CreateMaterial(sceneDelegate, networkMap); + m_rprMaterial = rprApi->CreateMaterial(GetId(), sceneDelegate, networkMap); } if (!m_rprMaterial) { @@ -69,7 +69,7 @@ void HdRprMaterial::Sync(HdSceneDelegate* sceneDelegate, networkMap.map[HdMaterialTerminalTokens->displacement] = network; networkMap.terminals.push_back(mtlxNode.path); - m_rprMaterial = rprApi->CreateMaterial(sceneDelegate, networkMap); + m_rprMaterial = rprApi->CreateMaterial(GetId(), sceneDelegate, networkMap); } } } diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index c3c8d4957..d2b8d888b 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -140,10 +140,7 @@ RprUsdMaterial const* HdRprMesh::GetFallbackMaterial( } m_fallbackMaterial = rprApi->CreateDiffuseMaterial(color); - - if (RprUsdIsLeakCheckEnabled()) { - rprApi->SetName(m_fallbackMaterial, GetId().GetText()); - } + rprApi->SetName(m_fallbackMaterial, GetId().GetText()); } return m_fallbackMaterial; @@ -376,6 +373,10 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, m_ignoreContour = geomSettings.ignoreContour; isIgnoreContourDirty = true; } + + if (m_cryptomatteName != geomSettings.cryptomatteName) { + m_cryptomatteName = geomSettings.cryptomatteName; + } } isIdDirty |= *dirtyBits & HdChangeTracker::DirtyPrimID; @@ -537,11 +538,9 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (!m_rprMeshes.empty()) { - if (newMesh && RprUsdIsLeakCheckEnabled()) { - auto name = id.GetText(); - for (auto& rprMesh : m_rprMeshes) { - rprApi->SetName(rprMesh, name); - } + auto name = m_cryptomatteName.empty() ? id.GetText() : m_cryptomatteName.c_str(); + for (auto& rprMesh : m_rprMeshes) { + rprApi->SetName(rprMesh, name); } if (newMesh || (*dirtyBits & HdChangeTracker::DirtySubdivTags)) { diff --git a/pxr/imaging/plugin/hdRpr/mesh.h b/pxr/imaging/plugin/hdRpr/mesh.h index 3513525d1..dd2419fa8 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.h +++ b/pxr/imaging/plugin/hdRpr/mesh.h @@ -96,6 +96,7 @@ class HdRprMesh final : public HdRprBaseRprim { int m_id = -1; bool m_ignoreContour; + std::string m_cryptomatteName; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp index b8b3f28f5..8b00f85aa 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp @@ -20,6 +20,7 @@ TF_DEFINE_PRIVATE_TOKENS(HdRprGeometryPrimvarTokens, ((id, "rpr:id")) ((subdivisionLevel, "rpr:subdivisionLevel")) ((ignoreContour, "rpr:ignoreContour")) + ((cryptomatteName, "rpr:cryptomatteName")) ((visibilityPrimary, "rpr:visibilityPrimary")) ((visibilityShadow, "rpr:visibilityShadow")) ((visibilityReflection, "rpr:visibilityReflection")) @@ -60,6 +61,8 @@ void HdRprParseGeometrySettings( } } else if (desc.name == HdRprGeometryPrimvarTokens->ignoreContour) { HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->ignoreContour, sceneDelegate, id, &geomSettings->ignoreContour); + } else if (desc.name == HdRprGeometryPrimvarTokens->cryptomatteName) { + HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->cryptomatteName, sceneDelegate, id, &geomSettings->cryptomatteName); } else if (desc.name == HdRprGeometryPrimvarTokens->visibilityPrimary) { setVisibilityFlag(HdRprGeometryPrimvarTokens->visibilityPrimary, kVisiblePrimary); } else if (desc.name == HdRprGeometryPrimvarTokens->visibilityShadow) { diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.h b/pxr/imaging/plugin/hdRpr/primvarUtil.h index 5eaba948d..51dfdd2e7 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.h +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.h @@ -40,6 +40,7 @@ struct HdRprGeometrySettings { int subdivisionLevel = 0; uint32_t visibilityMask = 0; bool ignoreContour = false; + std::string cryptomatteName; }; void HdRprParseGeometrySettings( diff --git a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py index 2234374b7..98a986186 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py @@ -38,6 +38,13 @@ 'defaultValue': False, 'help': 'Whether to extract contour for a mesh or not' }, + { + 'name': 'primvars:rpr:cryptomatteName', + 'ui_name': 'Cryptomatte Name', + 'defaultValue': '', + 'c_type': 'std::string', + 'help': 'String used to generate cryptomatte ID. If not specified, the path to a primitive used.' + }, { 'folder': 'Visibility Settings', 'settings': visibility_flag_settings diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 1701c2ad8..1188087e5 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -545,6 +545,47 @@ def hidewhen_not_tahoe(render_setting_categories): } ] }, + { + 'name': 'Cryptomatte', + 'settings': [ + { + 'name': 'cryptomatteOutputPath', + 'ui_name': 'Cryptomatte Output Path', + 'defaultValue': '', + 'c_type': 'std::string', + 'help': 'Controls where cryptomatte should be saved. Use \'Cryptomatte Output Mode\' to control when cryptomatte is saved.', + 'houdini': { + 'type': 'file' + } + }, + { + 'name': 'cryptomatteOutputMode', + 'ui_name': 'Cryptomatte Output Mode', + 'defaultValue': 'Batch', + 'values': [ + SettingValue('Batch'), + SettingValue('Interactive') + ], + 'help': 'Batch - save cryptomatte only in the batch rendering mode (USD Render ROP, husk). Interactive - same as the Batch but also save cryptomatte in the non-batch rendering mode. Cryptomatte always saved after \'Max Samples\' is reached.', + 'houdini': { + 'hidewhen': 'cryptomatteOutputPath == ""', + } + }, + { + 'name': 'cryptomattePreviewLayer', + 'ui_name': 'Cryptomatte Add Preview Layer', + 'defaultValue': False, + 'help': 'Whether to generate cryptomatte preview layer or not. Whether you need it depends on the software you are planning to use cryptomatte in. For example, Houdini\'s COP Cryptomatte requires it, Nuke, on contrary, does not.', + 'houdini': { + 'hidewhen': 'cryptomatteOutputPath == ""', + } + + } + ], + 'houdini': { + 'hidewhen': hidewhen_not_northstar + } + }, { 'name': 'UsdNativeCamera', 'settings': [ diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 629cdf7e8..d038173ef 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -52,12 +52,20 @@ using json = nlohmann::json; #include "pxr/base/tf/envSetting.h" #include "pxr/base/tf/fileUtils.h" #include "pxr/base/tf/getenv.h" +#include "pxr/base/work/loops.h" #include "notify/message.h" #include #include +#ifdef RPR_EXR_EXPORT_ENABLED +#include +#include +#include +#include +#endif // RPR_EXR_EXPORT_ENABLED + #ifdef BUILD_AS_HOUDINI_PLUGIN #include #endif // BUILD_AS_HOUDINI_PLUGIN @@ -113,6 +121,29 @@ RprUsdRenderDeviceType ToRprUsd(TfToken const& configDeviceType) { } } +bool CreateIntermediateDirectories(std::string const& filePath) { + auto dir = TfGetPathName(filePath); + if (!dir.empty()) { + return TfMakeDirs(dir, -1, true); + } + return true; +} + +template +void UnalignedRead(void const* src, size_t* offset, T* dst) { + std::memcpy(dst, (uint8_t const*)src + *offset, sizeof(T)); + *offset += sizeof(T); +} + +GfVec4f ColorizeId(uint32_t id) { + return { + (float)(id & 0xFF) / 0xFF, + (float)((id & 0xFF00) >> 8) / 0xFF, + (float)((id & 0xFF0000) >> 16) / 0xFF, + 1.0f + }; +} + } // namespace anonymous TfToken GetRprLpeAovName(rpr::Aov aov) { @@ -1009,13 +1040,13 @@ class HdRprApiImpl { m_dirtyFlags |= ChangeTracker::DirtyScene; } - RprUsdMaterial* CreateMaterial(HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork) { + RprUsdMaterial* CreateMaterial(SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork) { if (!m_rprContext) { return nullptr; } LockGuard rprLock(m_rprContext->GetMutex()); - return RprUsdMaterialRegistry::GetInstance().CreateMaterial(sceneDelegate, materialNetwork, m_rprContext.get(), m_imageCache.get()); + return RprUsdMaterialRegistry::GetInstance().CreateMaterial(materialId, sceneDelegate, materialNetwork, m_rprContext.get(), m_imageCache.get()); } RprUsdMaterial* CreatePointsMaterial(VtVec3fArray const& colors) { @@ -1646,6 +1677,17 @@ class HdRprApiImpl { RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_OCIO_RENDERING_COLOR_SPACE, preferences.GetOcioRenderingColorSpace().c_str()), "Faled to set OCIO rendering color space"); m_dirtyFlags |= ChangeTracker::DirtyScene; } + + if (preferences.IsDirty(HdRprConfig::DirtyCryptomatte) || force) { +#ifdef RPR_EXR_EXPORT_ENABLED + m_cryptomatteOutputPath = preferences.GetCryptomatteOutputPath(); + m_cryptomattePreviewLayer = preferences.GetCryptomattePreviewLayer(); +#else + if (!preferences.GetCryptomatteOutputPath().empty()) { + fprintf(stderr, "Cryptomatte export is not supported: hdRpr compiled without .exr support\n"); + } +#endif // RPR_EXR_EXPORT_ENABLED + } } } @@ -1698,6 +1740,32 @@ class HdRprApiImpl { m_dirtyFlags |= ChangeTracker::DirtyScene; } } + + if (preferences.IsDirty(HdRprConfig::DirtySession) || preferences.IsDirty(HdRprConfig::DirtyCryptomatte) || force) { + if (!m_cryptomatteOutputPath.empty() && + (m_isBatch || preferences.GetCryptomatteOutputMode() == HdRprCryptomatteOutputModeTokens->Interactive) && + m_rprContextMetadata.pluginType == kPluginNorthstar) { + if (!m_cryptomatteAovs) { + auto cryptomatteAovs = std::make_unique(); + cryptomatteAovs->obj.aov[0] = CreateAov(HdRprAovTokens->cryptomatteObj0); + cryptomatteAovs->obj.aov[1] = CreateAov(HdRprAovTokens->cryptomatteObj1); + cryptomatteAovs->obj.aov[2] = CreateAov(HdRprAovTokens->cryptomatteObj2); + cryptomatteAovs->mat.aov[0] = CreateAov(HdRprAovTokens->cryptomatteMat0); + cryptomatteAovs->mat.aov[1] = CreateAov(HdRprAovTokens->cryptomatteMat1); + cryptomatteAovs->mat.aov[2] = CreateAov(HdRprAovTokens->cryptomatteMat2); + for (int i = 0; i < 3; ++i) { + if (!cryptomatteAovs->obj.aov[i] || + !cryptomatteAovs->mat.aov[i]) { + cryptomatteAovs = nullptr; + break; + } + } + m_cryptomatteAovs = std::move(cryptomatteAovs); + } + } else { + m_cryptomatteAovs = nullptr; + } + } } void UpdateCamera(RenderSetting const& aspectRatioPolicy, RenderSetting const& instantaneousShutter) { @@ -2093,6 +2161,188 @@ class HdRprApiImpl { return true; } + uint32_t cryptomatte_avoid_bad_float_hash(uint32_t hash) { + // from Cryptomatte Specification version 1.2.0 + // This is for avoiding nan, inf, subnormals + // + // if all exponent bits are 0 (subnormals, +zero, -zero) set exponent to 1 + // if all exponent bits are 1 (NaNs, +inf, -inf) set exponent to 254 + uint32_t exponent = hash >> 23 & 255; // extract exponent (8 bits) + if (exponent == 0 || exponent == 255) { + hash ^= 1 << 23; // toggle bit + } + return hash; + } + std::string cryptomatte_hash_name(const char* name, size_t size) { + uint32_t m3hash = 0; + MurmurHash3_x86_32(name, size, 0, &m3hash); + m3hash = cryptomatte_avoid_bad_float_hash(m3hash); + return TfStringPrintf("%08x", m3hash); + } + template + std::string cryptomatte_hash_name(char (&name)[size]) { + return cryptomatte_hash_name(name, size); + } + std::string cryptomatte_hash_name(std::string const& name) { + return cryptomatte_hash_name(name.c_str(), name.size()); + } + + void SaveCryptomatte() { +#ifdef RPR_EXR_EXPORT_ENABLED + if (m_cryptomatteAovs && + m_numSamples == m_maxSamples) { + + std::string outputPath = m_cryptomatteOutputPath; + std::string filename = TfGetBaseName(outputPath); + if (filename.empty()) { + TF_WARN("Cryptomatte output path should be a path to .exr file"); + outputPath = TfStringCatPaths(outputPath, "cryptomatte.exr"); + } else if (!TfStringEndsWith(outputPath, ".exr")) { + TF_WARN("Cryptomatte output path should be a path to .exr file"); + outputPath += ".exr"; + } + + if (!CreateIntermediateDirectories(outputPath)) { + fprintf(stderr, "Failed to save cryptomatte aov: cannot create intermediate directories - %s\n", outputPath.c_str()); + return; + } + + // Generate manifests + std::string objectManifestEncoded; + std::string materialManifestEncoded; + + if (auto shapes = RprUsdGetListInfo(m_rprContext.get(), RPR_CONTEXT_LIST_CREATED_SHAPES)) { + json objectManifest; + json materialManifest; + for (size_t iShape = 0; iShape < shapes.size; ++iShape) { + auto shape = RprUsdGetRprObject(shapes.data[iShape]); + if (auto name = RprUsdGetListInfo(shape, RPR_SHAPE_NAME)) { + objectManifest[name.data.get()] = cryptomatte_hash_name(name.data.get(), name.size - 1); + } + + if (rpr_material_node rprMaterialNode = RprUsdGetInfo(shape, RPR_SHAPE_MATERIAL)) { + auto name = RprUsdGetListInfo( + [rprMaterialNode](size_t size, void* data, size_t* size_ret) { + return rprMaterialNodeGetInfo(rprMaterialNode, RPR_MATERIAL_NODE_NAME, size, data, size_ret); + } + ); + if (name) { + materialManifest[name.data.get()] = cryptomatte_hash_name(name.data.get(), name.size - 1); + } + } + } + objectManifestEncoded = objectManifest.dump(); + materialManifestEncoded = materialManifest.dump(); + } + + try { + namespace exr = OPENEXR_IMF_NAMESPACE; + exr::FrameBuffer exrFb; + exr::Header exrHeader(m_viewportSize[0], m_viewportSize[1]); + exrHeader.compression() = exr::ZIPS_COMPRESSION; + + const int kNumComponents = 4; + const char* kComponentNames[kNumComponents] = {".R", ".G", ".B", ".A"}; + + size_t linesize = m_viewportSize[0] * kNumComponents * sizeof(float); + size_t layersize = m_viewportSize[1] * linesize; + std::unique_ptr flipBuffer; + if (m_isOutputFlipped) { + flipBuffer = std::make_unique(layersize); + } + + std::vector> cryptomatteLayers; + std::vector> previewLayers; + + auto addCryptomatte = [&](const char* name, CryptomatteAov const& cryptomatte, std::string const& manifest) { + std::string nameHash = cryptomatte_hash_name(name).substr(0, 7); + std::string cryptoPrefix = "cryptomatte/" + nameHash + "/"; + exrHeader.insert(cryptoPrefix + "name", exr::StringAttribute(name)); + exrHeader.insert(cryptoPrefix + "hash", exr::StringAttribute("MurmurHash3_32")); + exrHeader.insert(cryptoPrefix + "conversion", exr::StringAttribute("uint32_to_float32")); + exrHeader.insert(cryptoPrefix + "manifest", exr::StringAttribute(manifest)); + + auto addLayer = [&](const char* layerName, char* basePtr) { + for (int iComponent = 0; iComponent < kNumComponents; ++iComponent) { + std::string channelName = TfStringPrintf("%s%s", layerName, kComponentNames[iComponent]); + exrHeader.channels().insert(channelName.c_str(), exr::Channel(exr::FLOAT)); + + char* dataPtr = &basePtr[iComponent * sizeof(float)]; + size_t xStride = kNumComponents * sizeof(float); + size_t yStride = xStride * m_viewportSize[0]; + exrFb.insert(channelName.c_str(), exr::Slice(exr::FLOAT, dataPtr, xStride, yStride)); + } + }; + + for (int i = 0; i < 3; ++i) { + auto rprLayer = cryptomatte.aov[i]->GetResolvedFb(); + cryptomatteLayers.push_back(std::make_unique(layersize)); + if (!rprLayer->GetData(cryptomatteLayers.back().get(), layersize)) { + throw std::runtime_error("failed to get RPR fb data"); + } + + if (m_isOutputFlipped) { + for (int y = 0; y < m_viewportSize[1]; ++y) { + void* src = &cryptomatteLayers.back()[y * linesize]; + void* dst = &flipBuffer[(m_viewportSize[1] - y - 1) * linesize]; + std::memcpy(dst, src, linesize); + } + std::swap(flipBuffer, cryptomatteLayers.back()); + } + + std::string layerName = TfStringPrintf("%s0%d", name, i); + addLayer(layerName.c_str(), cryptomatteLayers.back().get()); + } + + if (m_cryptomattePreviewLayer) { + size_t numPixels = m_viewportSize[0] * m_viewportSize[1]; + previewLayers.push_back(std::make_unique(numPixels)); + std::memset(previewLayers.back().get(), 0, numPixels * sizeof(GfVec4f)); + + size_t channelOffset = cryptomatteLayers.size() - 3; + + GfVec4f* previewLayer = previewLayers.back().get(); + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (size_t iChannel = 0; iChannel < 3; ++iChannel) { + auto channelData = cryptomatteLayers[channelOffset + iChannel].get(); + for (size_t iPixel = begin; iPixel < end; ++iPixel) { + size_t offset = iPixel * kNumComponents * sizeof(float); + + uint32_t id; + float contrib; + UnalignedRead(channelData, &offset, &id); + UnalignedRead(channelData, &offset, &contrib); + GfVec4f color = ColorizeId(id) * contrib; + + UnalignedRead(channelData, &offset, &id); + UnalignedRead(channelData, &offset, &contrib); + color += ColorizeId(id) * contrib; + + previewLayer[iPixel] += color; + } + } + } + ); + + addLayer(name, (char*)previewLayer); + } + }; + + addCryptomatte("CryptoObject", m_cryptomatteAovs->obj, objectManifestEncoded); + addCryptomatte("CryptoMaterial", m_cryptomatteAovs->mat, materialManifestEncoded); + + ArchUnlinkFile(outputPath.c_str()); + exr::OutputFile exrFile(outputPath.c_str(), exrHeader); + exrFile.setFrameBuffer(exrFb); + exrFile.writePixels(m_viewportSize[1]); + } catch (std::exception& e) { + fprintf(stderr, "Failed to save cryptomatte: %s", e.what()); + } + } +#endif // RPR_EXR_EXPORT_ENABLED + } + void BatchRenderImpl(HdRprRenderThread* renderThread) { if (!CommonRenderImplPrologue()) { return; @@ -2424,6 +2674,7 @@ class HdRprApiImpl { RenderImpl(renderThread); } } + SaveCryptomatte(); } catch (std::runtime_error const& e) { TF_RUNTIME_ERROR("Failed to render frame: %s", e.what()); } @@ -2464,12 +2715,8 @@ Don't show this message again? } #endif // BUILD_AS_HOUDINI_PLUGIN - // Create intermediate directories if needed - auto exportDir = TfGetPathName(m_rprSceneExportPath); - if (!exportDir.empty()) { - if (!TfMakeDirs(exportDir, -1, true)) { - fprintf(stderr, "Failed to create output directory\n"); - } + if (!CreateIntermediateDirectories(m_rprSceneExportPath)) { + fprintf(stderr, "Failed to create .rpr export output directory\n"); } uint32_t currentYFlip; @@ -3712,6 +3959,17 @@ Don't show this message again? bool m_rprExportAsSingleFile; bool m_rprExportUseImageCache; + std::string m_cryptomatteOutputPath; + bool m_cryptomattePreviewLayer; + struct CryptomatteAov { + std::shared_ptr aov[3]; + }; + struct CryptomatteAovs { + CryptomatteAov mat; + CryptomatteAov obj; + }; + std::unique_ptr m_cryptomatteAovs; + std::condition_variable* m_presentedConditionVariable = nullptr; bool* m_presentedCondition = nullptr; rprContextFlushFrameBuffers_func m_rprContextFlushFrameBuffers = nullptr; @@ -3836,9 +4094,9 @@ HdRprApiVolume* HdRprApi::CreateVolume( gridSize, voxelSize, gridBBLow, materialParams); } -RprUsdMaterial* HdRprApi::CreateMaterial(HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork) { +RprUsdMaterial* HdRprApi::CreateMaterial(SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork) { m_impl->InitIfNeeded(); - return m_impl->CreateMaterial(sceneDelegate, materialNetwork); + return m_impl->CreateMaterial(materialId, sceneDelegate, materialNetwork); } RprUsdMaterial* HdRprApi::CreatePointsMaterial(VtVec3fArray const& colors) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index 77a38a2a7..103292e12 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -109,7 +109,7 @@ class HdRprApi final { void SetTransform(HdRprApiVolume* volume, GfMatrix4f const& transform); void Release(HdRprApiVolume* volume); - RprUsdMaterial* CreateMaterial(HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork); + RprUsdMaterial* CreateMaterial(SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork); RprUsdMaterial* CreatePointsMaterial(VtVec3fArray const& colors); RprUsdMaterial* CreateDiffuseMaterial(GfVec3f const& color); void Release(RprUsdMaterial* material); diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp index 79e0b191d..1e8ecc996 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp @@ -33,11 +33,14 @@ PXR_NAMESPACE_OPEN_SCOPE static PRM_Name g_materialPath("materialPath", "Material Path"); static PRM_Name g_id("id", "ID"); +static PRM_Name g_cryptomatteName("cryptomatteName", "Cryptomatte Name"); static PRM_Template g_templateList[] = { PRM_Template(PRM_STRING_E, 1, &g_materialPath), PRM_Template(PRM_INT, 1, &g_id, nullptr, nullptr, nullptr, nullptr, nullptr, 1, - "some help"), + "The ID that corresponds to ID on materialId AOV."), + PRM_Template(PRM_STRING_E, 1, &g_cryptomatteName, nullptr, nullptr, nullptr, nullptr, nullptr, 1, + "String used to generate cryptomatte ID. If not specified, the path to a primitive used."), PRM_Template() }; @@ -70,13 +73,16 @@ OP_ERROR LOP_RPRMaterialProperties::cookMyLop(OP_Context &context) { evalString(materialPath, g_materialPath.getToken(), 0, context.getTime()); HUSDmakeValidUsdPath(materialPath, true); - int id = evalInt(g_id.getToken(), 0, context.getTime()); - if (!materialPath.isstring()) { return error(); } SdfPath materialSdfPath(HUSDgetSdfPath(materialPath)); + int id = evalInt(g_id.getToken(), 0, context.getTime()); + + UT_String cryptomatteName; + evalString(cryptomatteName, g_cryptomatteName.getToken(), 0, context.getTime()); + HUSD_AutoWriteLock writelock(editableDataHandle()); HUSD_AutoLayerLock layerlock(writelock); @@ -103,6 +109,9 @@ OP_ERROR LOP_RPRMaterialProperties::cookMyLop(OP_Context &context) { UsdShadeShader surfaceSource = material.ComputeSurfaceSource(RprUsdTokens->rpr); if (surfaceSource) { surfaceSource.CreateInput(RprUsdTokens->id, SdfValueTypeNames->Int).Set(id); + surfaceSource.CreateInput(RprUsdTokens->cryptomatteName, SdfValueTypeNames->String).Set(VtValue(std::string(cryptomatteName))); + } else { + addWarning(LOP_MESSAGE, "Material has no surface source"); } return error(); diff --git a/pxr/imaging/rprUsd/helpers.h b/pxr/imaging/rprUsd/helpers.h index 416faf891..86381199e 100644 --- a/pxr/imaging/rprUsd/helpers.h +++ b/pxr/imaging/rprUsd/helpers.h @@ -23,27 +23,58 @@ PXR_NAMESPACE_OPEN_SCOPE template T RprUsdGetInfo(U* object, R info) { T value = {}; - size_t dummy; - RPR_ERROR_CHECK_THROW(object->GetInfo(info, sizeof(value), &value, &dummy), "Failed to get object info"); + RPR_ERROR_CHECK_THROW(object->GetInfo(info, sizeof(value), &value, nullptr), "Failed to get object info"); return value; } -template -std::string RprUsdGetStringInfo(U* object, R info) { +template +struct Buffer { + std::unique_ptr data; + size_t size; + + explicit operator bool() const { return data && size; } +}; + +template +Buffer RprUsdGetListInfo(GetInfoFunc&& getInfoFunc) { size_t size = 0; - RPR_ERROR_CHECK_THROW(object->GetInfo(info, sizeof(size), nullptr, &size), "Failed to get object info"); + RPR_ERROR_CHECK_THROW(getInfoFunc(sizeof(size), nullptr, &size), "Failed to get object info"); if (size <= 1) { return {}; } - auto buffer = std::make_unique(size); - RPR_ERROR_CHECK_THROW(object->GetInfo(info, size, buffer.get(), &size), "Failed to get object info"); + size_t numElements = size / sizeof(T); + auto buffer = std::make_unique(numElements); + RPR_ERROR_CHECK_THROW(getInfoFunc(size, buffer.get(), nullptr), "Failed to get object info"); - // discard null-terminator - --size; + return {std::move(buffer), numElements}; +} + +template +Buffer RprUsdGetListInfo(U* object, R info) { + return RprUsdGetListInfo([object, info](size_t size, void* data, size_t* size_ret) { return object->GetInfo(info, size, data, size_ret); }); +} - return std::string(buffer.get(), size); +template +std::string RprUsdGetStringInfo(U* object, R info) { + if (auto strBuffer = RprUsdGetListInfo(object, info)) { + // discard null-terminator + --strBuffer.size; + + return std::string(strBuffer.data.get(), strBuffer.size); + } + return {}; +} + +template +Wrapper* RprUsdGetRprObject(typename rpr::RprApiTypeOf::value rprApiObject) { + const void* customPtr = nullptr; + if (rprObjectGetCustomPointer(rprApiObject, &customPtr) != RPR_SUCCESS) { + return nullptr; + } + assert(dynamic_cast(static_cast(customPtr))); + return const_cast(static_cast(customPtr)); } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 48e256215..cdb9c005e 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -356,6 +356,7 @@ void ConvertLegacyHdMaterialNetwork( } // namespace anonymous RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( + SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& legacyNetworkMap, rpr::Context* rprContext, @@ -385,6 +386,7 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( VtValue const& surfaceOutput, VtValue const& displacementOutput, VtValue const& volumeOutput, + const char* cryptomatteName, int materialId) { auto getTerminalRprNode = [](VtValue const& terminalOutput) -> rpr::MaterialNode* { @@ -408,10 +410,14 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( m_uvPrimvarName = TfToken(context.uvPrimvarName); m_displacementScale = std::move(context.displacementScale); - if (m_surfaceNode && materialId >= 0) { - // TODO: add C++ wrapper - auto apiHandle = rpr::GetRprObject(m_surfaceNode); - RPR_ERROR_CHECK(rprMaterialNodeSetID(apiHandle, rpr_uint(materialId)), "Failed to set material node id"); + if (m_surfaceNode) { + if (materialId >= 0) { + // TODO: add C++ wrapper + auto apiHandle = rpr::GetRprObject(m_surfaceNode); + RPR_ERROR_CHECK(rprMaterialNodeSetID(apiHandle, rpr_uint(materialId)), "Failed to set material node id"); + } + + RPR_ERROR_CHECK(m_surfaceNode->SetName(cryptomatteName), "Failed to set material name"); } return m_volumeNode || m_surfaceNode || m_displacementNode; @@ -523,7 +529,8 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( auto surfaceOutput = getTerminalOutput(HdMaterialTerminalTokens->surface); auto displacementOutput = getTerminalOutput(HdMaterialTerminalTokens->displacement); - int materialId = -1; + int materialRprId = -1; + std::string const* cryptomatteName = nullptr; auto surfaceTerminalIt = network.terminals.find(HdMaterialTerminalTokens->surface); if (surfaceTerminalIt != network.terminals.end()) { @@ -538,13 +545,26 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( auto& value = idIt->second; if (value.IsHolding()) { - materialId = value.UncheckedGet(); + materialRprId = value.UncheckedGet(); + } + } + + auto cryptomatteNameIt = parameters.find(RprUsdTokens->cryptomatteName); + if (cryptomatteNameIt != parameters.end()) { + auto& value = cryptomatteNameIt->second; + + if (value.IsHolding()) { + cryptomatteName = &value.UncheckedGet(); } } } } - return out->Finalize(context, surfaceOutput, displacementOutput, volumeOutput, materialId) ? out.release() : nullptr; + if (!cryptomatteName) { + cryptomatteName = &materialId.GetString(); + } + + return out->Finalize(context, surfaceOutput, displacementOutput, volumeOutput, cryptomatteName->c_str(), materialRprId) ? out.release() : nullptr; } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/rprUsd/materialRegistry.h b/pxr/imaging/rprUsd/materialRegistry.h index c1c0f3dbf..a1f35ead4 100644 --- a/pxr/imaging/rprUsd/materialRegistry.h +++ b/pxr/imaging/rprUsd/materialRegistry.h @@ -62,6 +62,7 @@ class RprUsdMaterialRegistry { RPRUSD_API RprUsdMaterial* CreateMaterial( + SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& networkMap, rpr::Context* rprContext, diff --git a/pxr/imaging/rprUsd/tokens.h b/pxr/imaging/rprUsd/tokens.h index 053776dd6..d5881bdb7 100644 --- a/pxr/imaging/rprUsd/tokens.h +++ b/pxr/imaging/rprUsd/tokens.h @@ -23,7 +23,8 @@ PXR_NAMESPACE_OPEN_SCOPE #define RPRUSD_TOKENS \ (rpr) \ /* UsdShadeShader */ \ - ((id, "rpr:id")) + ((id, "rpr:id")) \ + ((cryptomatteName, "rpr:cryptomatteName")) TF_DECLARE_PUBLIC_TOKENS(RprUsdTokens, RPRUSD_API, RPRUSD_TOKENS); From 31d0ad62151140277fc8c35a9469c4d82b8335af Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 27 May 2021 19:24:42 +0300 Subject: [PATCH 37/50] buildmaster: version update to 2.0.43 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 3e7c6849b..da9f8f912 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "42") +set(HD_RPR_PATCH_VERSION "43") From bc9e9537a9a2143f2cc5acc64af8c3af258bba28 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 27 May 2021 20:06:50 +0300 Subject: [PATCH 38/50] Add support of deformation motion blur (#471) PURPOSE Adds support of deformation motion blur EFFECT OF CHANGE Added support of deformation motion blur in the Full quality. New geometry render setting introduced - "Geometry Time Samples". The number of sub-frame samples to compute when rendering deformation motion blur over the shutter open time. The default is 1 (sample only at the start of the shutter time), giving no deformation blur by default. If you want rapidly deforming geometry to blur properly, you must increase this value to 2 or more. Note that this value is limited by the number of sub-samples available in the USD stage being rendered. Set to 0 to get all sub-samples available in the USD stage. --- pxr/imaging/plugin/hdRpr/mesh.cpp | 219 +++++++++--------- pxr/imaging/plugin/hdRpr/mesh.h | 14 +- pxr/imaging/plugin/hdRpr/primvarUtil.cpp | 4 + pxr/imaging/plugin/hdRpr/primvarUtil.h | 94 ++++++++ .../python/generateGeometrySettingFiles.py | 8 + pxr/imaging/plugin/hdRpr/rprApi.cpp | 189 ++++++++++++--- pxr/imaging/plugin/hdRpr/rprApi.h | 3 +- 7 files changed, 371 insertions(+), 160 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index d2b8d888b..dadfc64bf 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -73,43 +73,6 @@ void HdRprMesh::_InitRepr(TfToken const& reprName, // No-op } -template -bool HdRprMesh::GetPrimvarData(TfToken const& name, - HdSceneDelegate* sceneDelegate, - std::map const& primvarDescsPerInterpolation, - VtArray& out_data, - VtIntArray& out_indices) { - out_data.clear(); - out_indices.clear(); - - for (auto& primvarDescsEntry : primvarDescsPerInterpolation) { - for (auto& pv : primvarDescsEntry.second) { - if (pv.name == name) { - auto value = GetPrimvar(sceneDelegate, name); - if (value.IsHolding>()) { - out_data = value.UncheckedGet>(); - if (primvarDescsEntry.first == HdInterpolationFaceVarying) { - out_indices.reserve(m_faceVertexIndices.size()); - for (int i = 0; i < m_faceVertexIndices.size(); ++i) { - out_indices.push_back(i); - } - } else if (primvarDescsEntry.first == HdInterpolationConstant) { - out_indices = VtIntArray(m_faceVertexIndices.size(), 0); - } - return true; - } - - TF_RUNTIME_ERROR("Failed to load %s primvar data: unexpected underlying type - %s", name.GetText(), value.GetTypeName().c_str()); - return false; - } - } - } - - return false; -} -template bool HdRprMesh::GetPrimvarData(TfToken const&, HdSceneDelegate*, std::map const&, VtArray&, VtIntArray&); -template bool HdRprMesh::GetPrimvarData(TfToken const&, HdSceneDelegate*, std::map const&, VtArray&, VtIntArray&); - RprUsdMaterial const* HdRprMesh::GetFallbackMaterial( HdSceneDelegate* sceneDelegate, HdRprApi* rprApi, @@ -163,6 +126,56 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, bool newMesh = false; + std::map primvarDescsPerInterpolation; + + bool isRefineLevelDirty = false; + if (*dirtyBits & HdChangeTracker::DirtyDisplayStyle) { + m_displayStyle = sceneDelegate->GetDisplayStyle(id); + if (m_refineLevel != m_displayStyle.refineLevel) { + isRefineLevelDirty = true; + m_refineLevel = m_displayStyle.refineLevel; + } + } + + bool isIgnoreContourDirty = false; + bool isVisibilityMaskDirty = false; + bool isIdDirty = false; + if (*dirtyBits & HdChangeTracker::DirtyPrimvar) { + HdRprGeometrySettings geomSettings = {}; + geomSettings.visibilityMask = kVisibleAll; + HdRprFillPrimvarDescsPerInterpolation(sceneDelegate, id, &primvarDescsPerInterpolation); + HdRprParseGeometrySettings(sceneDelegate, id, primvarDescsPerInterpolation, &geomSettings); + + if (m_refineLevel != geomSettings.subdivisionLevel) { + m_refineLevel = geomSettings.subdivisionLevel; + isRefineLevelDirty = true; + } + + if (m_visibilityMask != geomSettings.visibilityMask) { + m_visibilityMask = geomSettings.visibilityMask; + isVisibilityMaskDirty = true; + } + + if (m_id != geomSettings.id) { + m_id = geomSettings.id; + isIdDirty = true; + } + + if (m_ignoreContour != geomSettings.ignoreContour) { + m_ignoreContour = geomSettings.ignoreContour; + isIgnoreContourDirty = true; + } + + if (m_cryptomatteName != geomSettings.cryptomatteName) { + m_cryptomatteName = geomSettings.cryptomatteName; + } + + if (m_numGeometrySamples != geomSettings.numGeometrySamples) { + m_numGeometrySamples = geomSettings.numGeometrySamples; + *dirtyBits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals; + } + } + bool pointsIsComputed = false; auto extComputationDescs = sceneDelegate->GetExtComputationPrimvarDescriptors(id, HdInterpolationVertex); for (auto& desc : extComputationDescs) { @@ -171,10 +184,11 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, desc.name)) { + // TODO: deformation motion blur for UsdSkel auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate); auto pointValueIt = valueStore.find(desc.name); if (pointValueIt != valueStore.end()) { - m_points = pointValueIt->second.Get(); + m_pointSamples = {pointValueIt->second.Get()}; m_normalsValid = false; pointsIsComputed = true; @@ -187,10 +201,11 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, if (!pointsIsComputed && HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) { - VtValue pointsValue = sceneDelegate->Get(id, HdTokens->points); - m_points = pointsValue.Get(); - m_normalsValid = false; + if (!HdRprSamplePrimvar(id, HdTokens->points, sceneDelegate, m_numGeometrySamples, &m_pointSamples)) { + m_pointSamples.clear(); + } + m_normalsValid = false; newMesh = true; } @@ -279,11 +294,16 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, newMesh = true; } - std::map primvarDescsPerInterpolation; - if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->normals)) { HdRprFillPrimvarDescsPerInterpolation(sceneDelegate, id, &primvarDescsPerInterpolation); - m_authoredNormals = GetPrimvarData(HdTokens->normals, sceneDelegate, primvarDescsPerInterpolation, m_normals, m_normalIndices); + HdInterpolation interpolation; + m_authoredNormals = HdRprSamplePrimvar(id, HdTokens->normals, sceneDelegate, primvarDescsPerInterpolation, m_numGeometrySamples, &m_normalSamples, &interpolation); + if (m_authoredNormals) { + HdRprGetPrimvarIndices(interpolation, m_faceVertexIndices, &m_normalIndices); + } else { + m_normalSamples.clear(); + m_normalIndices.clear(); + } newMesh = true; } @@ -323,7 +343,14 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, *uvPrimvarName)) { HdRprFillPrimvarDescsPerInterpolation(sceneDelegate, id, &primvarDescsPerInterpolation); - GetPrimvarData(*uvPrimvarName, sceneDelegate, primvarDescsPerInterpolation, m_uvs, m_uvIndices); + + HdInterpolation interpolation; + if (HdRprSamplePrimvar(id, *uvPrimvarName, sceneDelegate, primvarDescsPerInterpolation, m_numGeometrySamples, &m_uvSamples, &interpolation)) { + HdRprGetPrimvarIndices(interpolation, m_faceVertexIndices, &m_uvIndices); + } else { + m_uvSamples.clear(); + m_uvIndices.clear(); + } newMesh = true; } @@ -336,51 +363,6 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, //////////////////////////////////////////////////////////////////////// // 2. Resolve drawstyles - bool isRefineLevelDirty = false; - if (*dirtyBits & HdChangeTracker::DirtyDisplayStyle) { - m_displayStyle = sceneDelegate->GetDisplayStyle(id); - if (m_refineLevel != m_displayStyle.refineLevel) { - isRefineLevelDirty = true; - m_refineLevel = m_displayStyle.refineLevel; - } - } - - bool isIgnoreContourDirty = false; - bool isVisibilityMaskDirty = false; - bool isIdDirty = false; - if (*dirtyBits & HdChangeTracker::DirtyPrimvar) { - HdRprGeometrySettings geomSettings = {}; - geomSettings.visibilityMask = kVisibleAll; - HdRprFillPrimvarDescsPerInterpolation(sceneDelegate, id, &primvarDescsPerInterpolation); - HdRprParseGeometrySettings(sceneDelegate, id, primvarDescsPerInterpolation, &geomSettings); - - if (m_refineLevel != geomSettings.subdivisionLevel) { - m_refineLevel = geomSettings.subdivisionLevel; - isRefineLevelDirty = true; - } - - if (m_visibilityMask != geomSettings.visibilityMask) { - m_visibilityMask = geomSettings.visibilityMask; - isVisibilityMaskDirty = true; - } - - if (m_id != geomSettings.id) { - m_id = geomSettings.id; - isIdDirty = true; - } - - if (m_ignoreContour != geomSettings.ignoreContour) { - m_ignoreContour = geomSettings.ignoreContour; - isIgnoreContourDirty = true; - } - - if (m_cryptomatteName != geomSettings.cryptomatteName) { - m_cryptomatteName = geomSettings.cryptomatteName; - } - } - - isIdDirty |= *dirtyBits & HdChangeTracker::DirtyPrimID; - m_smoothNormals = !m_displayStyle.flatShadingEnabled; // Don't compute smooth normals on a refined mesh. They are implicitly smooth. if (m_enableSubdiv && m_refineLevel != 0) { @@ -395,7 +377,10 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (!m_normalsValid) { - m_normals = Hd_SmoothNormals::ComputeSmoothNormals(&m_adjacency, m_points.size(), m_points.cdata()); + m_normalSamples.clear(); + for (auto& points : m_pointSamples) { + m_normalSamples.push_back(Hd_SmoothNormals::ComputeSmoothNormals(&m_adjacency, points.size(), points.cdata())); + } m_normalsValid = true; newMesh = true; @@ -424,7 +409,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, m_rprMeshes.clear(); if (m_geomSubsets.empty()) { - if (auto rprMesh = rprApi->CreateMesh(m_points, m_faceVertexIndices, m_normals, m_normalIndices, m_uvs, m_uvIndices, m_faceVertexCounts, m_topology.GetOrientation())) { + if (auto rprMesh = rprApi->CreateMesh(m_pointSamples, m_faceVertexIndices, m_normalSamples, m_normalIndices, m_uvSamples, m_uvIndices, m_faceVertexCounts, m_topology.GetOrientation())) { m_rprMeshes.push_back(rprMesh); } } else { @@ -450,24 +435,24 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, continue; } - VtVec3fArray subsetPoints; - VtVec3fArray subsetNormals; - VtVec2fArray subsetUv; + VtArray subsetPointSamples(m_pointSamples.size()); + VtArray subsetNormalSamples(m_normalSamples.size()); + VtArray subsetUvSamples(m_uvSamples.size()); VtIntArray subsetNormalIndices; VtIntArray subsetUvIndices; VtIntArray subsetIndexes; VtIntArray subsetVertexPerFace; subsetVertexPerFace.reserve(subset.indices.size()); - vertexIndexRemapping.reserve(m_points.size()); - std::fill(vertexIndexRemapping.begin(), vertexIndexRemapping.begin() + m_points.size(), -1); + vertexIndexRemapping.reserve(m_pointSamples.front().size()); + std::fill(vertexIndexRemapping.begin(), vertexIndexRemapping.begin() + m_pointSamples.front().size(), -1); if (!m_normalIndices.empty()) { - normalIndexRemapping.reserve(m_normals.size()); - std::fill(normalIndexRemapping.begin(), normalIndexRemapping.begin() + m_normals.size(), -1); + normalIndexRemapping.reserve(m_normalSamples.front().size()); + std::fill(normalIndexRemapping.begin(), normalIndexRemapping.begin() + m_normalSamples.front().size(), -1); } if (!m_uvIndices.empty()) { - uvIndexRemapping.reserve(m_uvs.size()); - std::fill(uvIndexRemapping.begin(), uvIndexRemapping.begin() + m_uvs.size(), -1); + uvIndexRemapping.reserve(m_uvSamples.front().size()); + std::fill(uvIndexRemapping.begin(), uvIndexRemapping.begin() + m_uvSamples.front().size(), -1); } for (auto faceIndex : subset.indices) { @@ -482,44 +467,54 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, bool newPoint = subsetPointIndex == -1; if (newPoint) { - subsetPointIndex = static_cast(subsetPoints.size()); + subsetPointIndex = static_cast(subsetPointSamples.front().size()); vertexIndexRemapping[pointIndex] = subsetPointIndex; - subsetPoints.push_back(m_points[pointIndex]); + for (int sampleIndex = 0; sampleIndex < m_pointSamples.size(); ++sampleIndex) { + subsetPointSamples[sampleIndex].push_back(m_pointSamples[sampleIndex][pointIndex]); + } } subsetIndexes.push_back(subsetPointIndex); - if (!m_normals.empty()) { + if (!m_normalSamples.empty()) { if (m_normalIndices.empty()) { if (newPoint) { - subsetNormals.push_back(m_normals[pointIndex]); + for (int sampleIndex = 0; sampleIndex < m_normalSamples.size(); ++sampleIndex) { + subsetNormalSamples[sampleIndex].push_back(m_normalSamples[sampleIndex][pointIndex]); + } } } else { const int normalIndex = m_normalIndices[faceIndexesOffset + i]; int subsetNormalIndex = normalIndexRemapping[normalIndex]; if (subsetNormalIndex == -1) { - subsetNormalIndex = static_cast(subsetNormals.size()); + subsetNormalIndex = static_cast(subsetNormalSamples.front().size()); normalIndexRemapping[normalIndex] = subsetNormalIndex; - subsetNormals.push_back(m_normals[normalIndex]); + for (int sampleIndex = 0; sampleIndex < m_normalSamples.size(); ++sampleIndex) { + subsetNormalSamples[sampleIndex].push_back(m_normalSamples[sampleIndex][normalIndex]); + } } subsetNormalIndices.push_back(subsetNormalIndex); } } - if (!m_uvs.empty()) { + if (!m_uvSamples.empty()) { if (m_uvIndices.empty()) { if (newPoint) { - subsetUv.push_back(m_uvs[pointIndex]); + for (int sampleIndex = 0; sampleIndex < m_uvSamples.size(); ++sampleIndex) { + subsetUvSamples[sampleIndex].push_back(m_uvSamples[sampleIndex][pointIndex]); + } } } else { const int uvIndex = m_uvIndices[faceIndexesOffset + i]; int subsetuvIndex = uvIndexRemapping[uvIndex]; if (subsetuvIndex == -1) { - subsetuvIndex = static_cast(subsetUv.size()); + subsetuvIndex = static_cast(subsetUvSamples.front().size()); uvIndexRemapping[uvIndex] = subsetuvIndex; - subsetUv.push_back(m_uvs[uvIndex]); + for (int sampleIndex = 0; sampleIndex < m_uvSamples.size(); ++sampleIndex) { + subsetUvSamples[sampleIndex].push_back(m_uvSamples[sampleIndex][uvIndex]); + } } subsetUvIndices.push_back(subsetuvIndex); } @@ -527,7 +522,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } - if (auto rprMesh = rprApi->CreateMesh(subsetPoints, subsetIndexes, subsetNormals, subsetNormalIndices, subsetUv, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) { + if (auto rprMesh = rprApi->CreateMesh(subsetPointSamples, subsetIndexes, subsetNormalSamples, subsetNormalIndices, subsetUvSamples, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) { m_rprMeshes.push_back(rprMesh); ++it; } else { diff --git a/pxr/imaging/plugin/hdRpr/mesh.h b/pxr/imaging/plugin/hdRpr/mesh.h index dd2419fa8..51b9b268a 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.h +++ b/pxr/imaging/plugin/hdRpr/mesh.h @@ -51,13 +51,6 @@ class HdRprMesh final : public HdRprBaseRprim { void _InitRepr(TfToken const& reprName, HdDirtyBits* dirtyBits) override; private: - template - bool GetPrimvarData(TfToken const& name, - HdSceneDelegate* sceneDelegate, - std::map const& primvarDescsPerInterpolation, - VtArray& out_data, - VtIntArray& out_indices); - RprUsdMaterial const* GetFallbackMaterial( HdSceneDelegate* sceneDelegate, HdRprApi* rprApi, @@ -74,7 +67,7 @@ class HdRprMesh final : public HdRprBaseRprim { HdMeshTopology m_topology; HdGeomSubsets m_geomSubsets; - VtVec3fArray m_points; + VtArray m_pointSamples; VtIntArray m_faceVertexCounts; VtIntArray m_faceVertexIndices; bool m_enableSubdiv = false; @@ -82,13 +75,13 @@ class HdRprMesh final : public HdRprBaseRprim { Hd_VertexAdjacency m_adjacency; bool m_adjacencyValid = false; - VtVec3fArray m_normals; + VtArray m_normalSamples; VtIntArray m_normalIndices; bool m_normalsValid = false; bool m_authoredNormals = false; bool m_smoothNormals = false; - VtVec2fArray m_uvs; + VtArray m_uvSamples; VtIntArray m_uvIndices; HdDisplayStyle m_displayStyle; @@ -97,6 +90,7 @@ class HdRprMesh final : public HdRprBaseRprim { int m_id = -1; bool m_ignoreContour; std::string m_cryptomatteName; + size_t m_numGeometrySamples = 1; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp index 8b00f85aa..3f8ad890f 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp @@ -21,6 +21,7 @@ TF_DEFINE_PRIVATE_TOKENS(HdRprGeometryPrimvarTokens, ((subdivisionLevel, "rpr:subdivisionLevel")) ((ignoreContour, "rpr:ignoreContour")) ((cryptomatteName, "rpr:cryptomatteName")) + ((geomSamples, "rpr:geomSamples")) ((visibilityPrimary, "rpr:visibilityPrimary")) ((visibilityShadow, "rpr:visibilityShadow")) ((visibilityReflection, "rpr:visibilityReflection")) @@ -63,6 +64,9 @@ void HdRprParseGeometrySettings( HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->ignoreContour, sceneDelegate, id, &geomSettings->ignoreContour); } else if (desc.name == HdRprGeometryPrimvarTokens->cryptomatteName) { HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->cryptomatteName, sceneDelegate, id, &geomSettings->cryptomatteName); + } else if (desc.name == HdRprGeometryPrimvarTokens->geomSamples) { + HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->geomSamples, sceneDelegate, id, &geomSettings->numGeometrySamples); + geomSettings->numGeometrySamples = std::max(1, geomSettings->numGeometrySamples); } else if (desc.name == HdRprGeometryPrimvarTokens->visibilityPrimary) { setVisibilityFlag(HdRprGeometryPrimvarTokens->visibilityPrimary, kVisiblePrimary); } else if (desc.name == HdRprGeometryPrimvarTokens->visibilityShadow) { diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.h b/pxr/imaging/plugin/hdRpr/primvarUtil.h index 51dfdd2e7..c3ba792b4 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.h +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.h @@ -41,6 +41,7 @@ struct HdRprGeometrySettings { uint32_t visibilityMask = 0; bool ignoreContour = false; std::string cryptomatteName; + int numGeometrySamples = 1; }; void HdRprParseGeometrySettings( @@ -73,6 +74,99 @@ bool HdRprGetConstantPrimvar(TfToken const& name, HdSceneDelegate* sceneDelegate return false; } +template +bool HdRprSamplePrimvar( + SdfPath const& id, + TfToken const& key, + HdSceneDelegate* sceneDelegate, + size_t maxSampleCount, + VtArray* sampleValuesPtr) { + std::vector sampleTimes(maxSampleCount); + std::vector sampleVtValues(maxSampleCount); + + size_t authoredSampleCount = sceneDelegate->SamplePrimvar(id, key, maxSampleCount, sampleTimes.data(), sampleVtValues.data()); + if (!authoredSampleCount) { + return false; + } + + if (authoredSampleCount < maxSampleCount) { + sampleTimes.resize(authoredSampleCount); + sampleVtValues.resize(authoredSampleCount); + } + + if (sampleTimes.size() > 1) { + float baselineTimeStep = sampleTimes[1] - sampleTimes[0]; + for (size_t i = 1; i < sampleTimes.size() - 1; ++i) { + float timeStep = sampleTimes[i + 1] - sampleTimes[i]; + if (std::abs(baselineTimeStep - timeStep) > 1e-6f) { + // Definitely an issue but we can at least use such data with the current API, so just log a warning + TF_WARN("[%s] RPR does not support non-linear in time sub-frame primvar samples", id.GetText()); + break; + } + } + } + + size_t baselineSize = 0; + + auto& sampleValues = *sampleValuesPtr; + sampleValues.resize(sampleVtValues.size()); + for (size_t i = 0; i < sampleVtValues.size(); ++i) { + if (sampleVtValues[i].IsHolding()) { + sampleValues[i] = sampleVtValues[i].UncheckedGet(); + + if (i == 0) { + baselineSize = sampleValues[i].size(); + } else if (baselineSize != sampleValues[i].size()) { + TF_RUNTIME_ERROR("[%s] RPR does not support non-uniform sub-frame samples - %s", id.GetText(), key.GetText()); + return false; + } + } else { + TF_RUNTIME_ERROR("[%s] Failed to sample %s primvar data: unexpected underlying type - %s", id.GetText(), key.GetText(), sampleVtValues[i].GetTypeName().c_str()); + return false; + } + } + + return true; +} + +template +bool HdRprSamplePrimvar( + SdfPath const& id, + TfToken const& key, + HdSceneDelegate* sceneDelegate, + std::map const& primvarDescsPerInterpolation, + size_t maxSampleCount, + VtArray* sampleValues, + HdInterpolation* interpolation) { + + for (auto& primvarDescsEntry : primvarDescsPerInterpolation) { + for (auto& pv : primvarDescsEntry.second) { + if (pv.name == key) { + if (!HdRprSamplePrimvar(id, key, sceneDelegate, maxSampleCount, sampleValues)) { + return false; + } + + *interpolation = primvarDescsEntry.first; + return true; + } + } + } + + return false; +} + +inline void HdRprGetPrimvarIndices(HdInterpolation interpolation, VtIntArray const& faceIndices, VtIntArray* out_indices) { + out_indices->clear(); + if (interpolation == HdInterpolationFaceVarying) { + out_indices->reserve(faceIndices.size()); + for (int i = 0; i < faceIndices.size(); ++i) { + out_indices->push_back(i); + } + } else if (interpolation == HdInterpolationConstant) { + *out_indices = VtIntArray(faceIndices.size(), 0); + } +} + PXR_NAMESPACE_CLOSE_SCOPE #endif // HDRPR_PRIMVAR_UTIL_H diff --git a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py index 98a986186..9ce5b174f 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py @@ -45,6 +45,14 @@ 'c_type': 'std::string', 'help': 'String used to generate cryptomatte ID. If not specified, the path to a primitive used.' }, + { + 'name': 'primvars:rpr:geomSamples', + 'ui_name': 'Geometry Time Samples', + 'defaultValue': 1, + 'minValue': 1, + 'maxValue': 1 ** 16, + 'help': 'The number of sub-frame samples to compute when rendering deformation motion blur over the shutter open time. The default is 1 (sample only at the start of the shutter time), giving no deformation blur by default. If you want rapidly deforming geometry to blur properly, you must increase this value to 2 or more. Note that this value is limited by the number of sub-samples available in the USD file being rendered.' + }, { 'folder': 'Visibility Settings', 'settings': visibility_flag_settings diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index d038173ef..d7c957942 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -144,6 +144,44 @@ GfVec4f ColorizeId(uint32_t id) { }; } +template +std::unique_ptr MergeSamples(VtArray>* samples, size_t requiredNumSamples, rpr_float const** rprData, size_t* rprDataSize) { + if (samples->empty()) { + *rprData = nullptr; + *rprDataSize = 0; + return nullptr; + } + + if (samples->size() != requiredNumSamples) { + samples->resize(requiredNumSamples, [backElem=samples->back()](auto begin, auto end) { + for (auto it = begin; it != end; ++it) { + *it = backElem; + } + }); + } + + const size_t numSampleValues = samples->cdata()[0].size(); + auto mergedSamples = std::make_unique(requiredNumSamples * numSampleValues); + + for (size_t i = 0; i < requiredNumSamples; ++i) { + size_t offset = i * numSampleValues; + VtArray const& values = samples->cdata()[i]; + std::copy(values.cbegin(), values.cend(), mergedSamples.get() + offset); + + if (values.size() != numSampleValues) { + TF_RUNTIME_ERROR("Non-uniform size between samples: %zu vs %zu", samples->size(), numSampleValues); + *rprData = nullptr; + *rprDataSize = 0; + return nullptr; + } + } + + *rprData = (rpr_float const*)mergedSamples.get(); + *rprDataSize = requiredNumSamples * numSampleValues; + + return mergedSamples; +} + } // namespace anonymous TfToken GetRprLpeAovName(rpr::Aov aov) { @@ -333,33 +371,51 @@ class HdRprApiImpl { } } - rpr::Shape* CreateMesh(const VtVec3fArray& points, const VtIntArray& pointIndexes, - VtVec3fArray normals, const VtIntArray& normalIndexes, - VtVec2fArray uvs, const VtIntArray& uvIndexes, - const VtIntArray& vpf, TfToken const& polygonWinding = HdTokens->rightHanded) { + rpr::Shape* CreateMesh(VtVec3fArray const& points, VtIntArray const& pointIndices, + VtVec3fArray const& normals, VtIntArray const& normalIndices, + VtVec2fArray const& uvs, VtIntArray const& uvIndices, + VtIntArray const& vpf, TfToken const& polygonWinding = HdTokens->rightHanded) { + VtArray pointSamples; + VtArray normalSamples; + VtArray uvSamples; + + if (!points.empty()) pointSamples.push_back(points); + if (!normals.empty()) normalSamples.push_back(normals); + if (!uvs.empty()) uvSamples.push_back(uvs); + + return CreateMesh(pointSamples, pointIndices, normalSamples, normalIndices, uvSamples, uvIndices, vpf, polygonWinding); + } + + rpr::Shape* CreateMesh(VtArray pointSamples, VtIntArray const& pointIndices, + VtArray normalSamples, VtIntArray const& normalIndices, + VtArray uvSamples, VtIntArray const& uvIndices, + VtIntArray const& vpf, TfToken const& polygonWinding) { if (!m_rprContext) { return nullptr; } - VtIntArray newIndexes, newVpf; - SplitPolygons(pointIndexes, vpf, newIndexes, newVpf); - ConvertIndices(&newIndexes, newVpf, polygonWinding); + VtIntArray newIndices, newVpf; + SplitPolygons(pointIndices, vpf, newIndices, newVpf); + ConvertIndices(&newIndices, newVpf, polygonWinding); - VtIntArray newNormalIndexes; - if (normals.empty()) { + VtIntArray newNormalIndices; + if (normalSamples.empty()) { if (m_rprContextMetadata.pluginType == kPluginHybrid) { // XXX (Hybrid): we need to generate geometry normals by ourself + VtVec3fArray normals; normals.reserve(newVpf.size()); - newNormalIndexes.clear(); - newNormalIndexes.reserve(newIndexes.size()); + newNormalIndices.clear(); + newNormalIndices.reserve(newIndices.size()); + + auto& points = pointSamples[0]; size_t indicesOffset = 0u; for (auto numVerticesPerFace : newVpf) { for (int i = 0; i < numVerticesPerFace; ++i) { - newNormalIndexes.push_back(normals.size()); + newNormalIndices.push_back(normals.size()); } - auto indices = &newIndexes[indicesOffset]; + auto indices = &newIndices[indicesOffset]; indicesOffset += numVerticesPerFace; auto p0 = points[indices[0]]; @@ -373,52 +429,106 @@ class HdRprApiImpl { GfNormalize(&normal); normals.push_back(normal); } + + normalSamples.push_back(normals); } } else { - if (!normalIndexes.empty()) { - SplitPolygons(normalIndexes, vpf, newNormalIndexes); - ConvertIndices(&newNormalIndexes, newVpf, polygonWinding); + if (!normalIndices.empty()) { + SplitPolygons(normalIndices, vpf, newNormalIndices); + ConvertIndices(&newNormalIndices, newVpf, polygonWinding); } else { - newNormalIndexes = newIndexes; + newNormalIndices = newIndices; } } - VtIntArray newUvIndexes; - if (uvs.empty()) { + VtIntArray newUvIndices; + if (uvSamples.empty()) { if (m_rprContextMetadata.pluginType == kPluginHybrid) { - newUvIndexes = newIndexes; - uvs = VtVec2fArray(points.size(), GfVec2f(0.0f)); + newUvIndices = newIndices; + VtVec2fArray uvs(pointSamples[0].size(), GfVec2f(0.0f)); + uvSamples.push_back(uvs); } } else { - if (!uvIndexes.empty()) { - SplitPolygons(uvIndexes, vpf, newUvIndexes); - ConvertIndices(&newUvIndexes, newVpf, polygonWinding); + if (!uvIndices.empty()) { + SplitPolygons(uvIndices, vpf, newUvIndices); + ConvertIndices(&newUvIndices, newVpf, polygonWinding); } else { - newUvIndexes = newIndexes; + newUvIndices = newIndices; } } - auto normalIndicesData = !newNormalIndexes.empty() ? newNormalIndexes.data() : newIndexes.data(); - if (normals.empty()) { + auto normalIndicesData = !newNormalIndices.empty() ? newNormalIndices.data() : newIndices.data(); + if (normalSamples.empty()) { normalIndicesData = nullptr; } - auto uvIndicesData = !newUvIndexes.empty() ? newUvIndexes.data() : uvIndexes.data(); - if (uvs.empty()) { + auto uvIndicesData = !newUvIndices.empty() ? newUvIndices.data() : uvIndices.data(); + if (uvSamples.empty()) { uvIndicesData = nullptr; } + rpr_float const* pointsData = nullptr; + rpr_float const* normalsData = nullptr; + rpr_float const* uvsData = nullptr; + size_t numPoints = 0; + size_t numNormals = 0; + size_t numUvs = 0; + + std::vector meshProperties(1, rpr_mesh_info(0)); + + std::unique_ptr mergedPoints; + std::unique_ptr mergedNormals; + std::unique_ptr mergedUvs; + + size_t numMeshSamples = std::max(std::max(pointSamples.size(), normalSamples.size()), uvSamples.size()); + + // XXX (RPR): Only Northstar supports deformation motion blur. Use only the first sample for all other plugins. + if (m_rprContextMetadata.pluginType != kPluginNorthstar) { + numMeshSamples = 1; + } + + if (numMeshSamples > 1) { + meshProperties[0] = (rpr_mesh_info)RPR_MESH_MOTION_DIMENSION; + meshProperties[1] = (rpr_mesh_info)numMeshSamples; + meshProperties[2] = (rpr_mesh_info)0; + + mergedPoints = MergeSamples(&pointSamples, numMeshSamples, &pointsData, &numPoints); + mergedNormals = MergeSamples(&normalSamples, numMeshSamples, &normalsData, &numNormals); + mergedUvs = MergeSamples(&uvSamples, numMeshSamples, &uvsData, &numUvs); + + } else { + if (pointSamples.empty()) { + return nullptr; + } + pointsData = (rpr_float const*)pointSamples[0].cdata(); + numPoints = pointSamples[0].size(); + + if (!normalSamples.empty()) { + normalsData = (rpr_float const*)normalSamples[0].data(); + numNormals = normalSamples[0].size(); + } + + if (!uvSamples.empty()) { + uvsData = (rpr_float const*)uvSamples[0].data(); + numUvs = uvSamples[0].size(); + } + } + + rpr_int texCoordStride = sizeof(GfVec2f); + rpr_int texCoordIdxStride = sizeof(rpr_int); + LockGuard rprLock(m_rprContext->GetMutex()); rpr::Status status; auto mesh = m_rprContext->CreateShape( - (rpr_float const*)points.data(), points.size(), sizeof(GfVec3f), - (rpr_float const*)(normals.data()), normals.size(), sizeof(GfVec3f), - (rpr_float const*)(uvs.data()), uvs.size(), sizeof(GfVec2f), - newIndexes.data(), sizeof(rpr_int), + pointsData, numPoints, sizeof(GfVec3f), + normalsData, numNormals, sizeof(GfVec3f), + nullptr, 0, 0, + 1, &uvsData, &numUvs, &texCoordStride, + newIndices.data(), sizeof(rpr_int), normalIndicesData, sizeof(rpr_int), - uvIndicesData, sizeof(rpr_int), - newVpf.data(), newVpf.size(), &status); + &uvIndicesData, &texCoordIdxStride, + newVpf.data(), newVpf.size(), meshProperties.data(), &status); if (!mesh) { RPR_ERROR_CHECK(status, "Failed to create mesh"); return nullptr; @@ -3983,9 +4093,14 @@ HdRprApi::~HdRprApi() { delete m_impl; } -rpr::Shape* HdRprApi::CreateMesh(const VtVec3fArray& points, const VtIntArray& pointIndexes, const VtVec3fArray& normals, const VtIntArray& normalIndexes, const VtVec2fArray& uv, const VtIntArray& uvIndexes, const VtIntArray& vpf, TfToken const& polygonWinding) { +rpr::Shape* HdRprApi::CreateMesh(VtArray const& pointSamples, VtIntArray const& pointIndexes, VtArray const& normalSamples, VtIntArray const& normalIndexes, VtArray const& uvSamples, VtIntArray const& uvIndexes, VtIntArray const& vpf, TfToken const& polygonWinding) { + m_impl->InitIfNeeded(); + return m_impl->CreateMesh(pointSamples, pointIndexes, normalSamples, normalIndexes, uvSamples, uvIndexes, vpf, polygonWinding); +} + +rpr::Shape* HdRprApi::CreateMesh(VtVec3fArray const& points, VtIntArray const& pointIndexes, VtVec3fArray const& normals, VtIntArray const& normalIndexes, VtVec2fArray const& uvs, VtIntArray const& uvIndexes, VtIntArray const& vpf, TfToken const& polygonWinding) { m_impl->InitIfNeeded(); - return m_impl->CreateMesh(points, pointIndexes, normals, normalIndexes, uv, uvIndexes, vpf, polygonWinding); + return m_impl->CreateMesh(points, pointIndexes, normals, normalIndexes, uvs, uvIndexes, vpf, polygonWinding); } rpr::Curve* HdRprApi::CreateCurve(VtVec3fArray const& points, VtIntArray const& indices, VtFloatArray const& radiuses, VtVec2fArray const& uvs, VtIntArray const& segmentPerCurve) { diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index 103292e12..68d1b2f44 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -114,7 +114,8 @@ class HdRprApi final { RprUsdMaterial* CreateDiffuseMaterial(GfVec3f const& color); void Release(RprUsdMaterial* material); - rpr::Shape* CreateMesh(const VtVec3fArray& points, const VtIntArray& pointIndexes, const VtVec3fArray& normals, const VtIntArray& normalIndexes, const VtVec2fArray& uv, const VtIntArray& uvIndexes, const VtIntArray& vpf, TfToken const& polygonWinding); + rpr::Shape* CreateMesh(VtVec3fArray const& points, VtIntArray const& pointIndexes, VtVec3fArray const& normals, VtIntArray const& normalIndexes, VtVec2fArray const& uvs, VtIntArray const& uvIndexes, VtIntArray const& vpf, TfToken const& polygonWinding); + rpr::Shape* CreateMesh(VtArray const& pointSamples, VtIntArray const& pointIndexes, VtArray const& normalSamples, VtIntArray const& normalIndexes, VtArray const& uvSamples, VtIntArray const& uvIndexes, VtIntArray const& vpf, TfToken const& polygonWinding); rpr::Shape* CreateMeshInstance(rpr::Shape* prototypeMesh); void SetMeshRefineLevel(rpr::Shape* mesh, int level); void SetMeshVertexInterpolationRule(rpr::Shape* mesh, TfToken boundaryInterpolation); From d1cff9da6ddec6c283a774651d8185f39ffd9b45 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 27 May 2021 20:09:35 +0300 Subject: [PATCH 39/50] buildmaster: version update to 2.0.44 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index da9f8f912..6cfc019ee 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "43") +set(HD_RPR_PATCH_VERSION "44") From 4b7dc71e271ed9242757cf8f4fee7ae2bda73972 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 28 May 2021 00:24:54 +0300 Subject: [PATCH 40/50] Add support of deformation blur for UsdSkel (#477) PURPOSE To add support of deformation blur of computed geometry. EFFECT OF CHANGE Added support of deformation motion blur of computed geometry in the Full quality. --- pxr/imaging/plugin/hdRpr/mesh.cpp | 33 ++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index dadfc64bf..8a3f81152 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -184,7 +184,37 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, desc.name)) { - // TODO: deformation motion blur for UsdSkel + m_pointSamples.clear(); + +#if PXR_VERSION >= 2105 + HdExtComputationUtils::SampledValueStore<2> valueStore; + HdExtComputationUtils::SampleComputedPrimvarValues({desc}, sceneDelegate, m_numGeometrySamples, &valueStore); + auto pointValueIt = valueStore.find(desc.name); + if (pointValueIt != valueStore.end()) { + auto& sampleValues = pointValueIt->second.values; + VtArray newPointSamples; + newPointSamples.reserve(sampleValues.size()); + for (auto& sampleValue : sampleValues) { + if (sampleValue.IsHolding()) { + newPointSamples.push_back(sampleValue.UncheckedGet()); + } else { + newPointSamples.clear(); + break; + } + } + + if (!newPointSamples.empty()) { + m_pointSamples = std::move(newPointSamples); + m_normalsValid = false; + pointsIsComputed = true; + + newMesh = true; + } + } +#else // PXR_VERSION < 2105 + if (m_numGeometrySamples != 1) { + TF_WARN("UsdSkel deformation motion blur is supported only in USD 21.05+ (current version %d.%d)", PXR_MINOR_VERSION, PXR_PATCH_VERSION); + } auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate); auto pointValueIt = valueStore.find(desc.name); if (pointValueIt != valueStore.end()) { @@ -194,6 +224,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, newMesh = true; } +#endif // PXR_VERSION >= 2105 } break; From 4a5254df463b8575d3baedd7b6ef5b7a9fa3ead5 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Fri, 28 May 2021 00:40:41 +0300 Subject: [PATCH 41/50] buildmaster: version update to 2.0.45 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 6cfc019ee..5f8ce44c0 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "44") +set(HD_RPR_PATCH_VERSION "45") From 2f57b2b40c4f94003a605dc827c975d10a7635f0 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 21 Jun 2021 21:34:22 +0300 Subject: [PATCH 42/50] ToonShader: add color parameter and fix normal map (#479) * Added color parameter: - rename shadow/mid/highlight colors to shadow/mid/highlight tints - add color parameter (to which tints are applied) * Fixed normal map: Use zero GfVec3f as an indicator of empty normal map input value instead of as float3 input --- .../rprUsd/materialNodes/rpr/toonNode.cpp | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp index 15c2ee3d8..a88230024 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/toonNode.cpp @@ -21,15 +21,16 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PRIVATE_TOKENS(_tokens, + (color) (roughness) (normal) - (shadowColor) + (shadowTint) (midLevel) (midLevelMix) - (midColor) + (midTint) (highlightLevel) (highlightLevelMix) - (highlightColor) + (highlightTint) (interpolationMode) (Linear) (None) @@ -76,19 +77,19 @@ class RprUsd_RprToonNode : public RprUsd_MaterialNode { bool SetInput( TfToken const& id, VtValue const& value) override { - if (id == _tokens->shadowColor) { + if (id == _tokens->shadowTint) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_SHADOW); } else if (id == _tokens->midLevel) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_POSITION1); } else if (id == _tokens->midLevelMix) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_RANGE1); - } else if (id == _tokens->midColor) { + } else if (id == _tokens->midTint) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_MID); } else if (id == _tokens->highlightLevel) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_POSITION2); } else if (id == _tokens->highlightLevelMix) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_RANGE2); - } else if (id == _tokens->highlightColor) { + } else if (id == _tokens->highlightTint) { return ProcessInput(id, value, m_rampNode, RPR_MATERIAL_INPUT_HIGHLIGHT); } else if (id == _tokens->interpolationMode) { if (value.IsHolding()) { @@ -98,9 +99,16 @@ class RprUsd_RprToonNode : public RprUsd_MaterialNode { } TF_RUNTIME_ERROR("Input `%s` has invalid type: %s, expected - `Token`", id.GetText(), value.GetTypeName().c_str()); return false; + } else if (id == _tokens->color) { + return ProcessInput(id, value, m_toonClosureNode, RPR_MATERIAL_INPUT_COLOR); } else if (id == _tokens->roughness) { return ProcessInput(id, value, m_toonClosureNode, RPR_MATERIAL_INPUT_ROUGHNESS); } else if (id == _tokens->normal) { + if (value.IsHolding() && + value.UncheckedGet() == GfVec3f(0.0f)) { + return m_toonClosureNode->SetInput(RPR_MATERIAL_INPUT_NORMAL, (rpr::MaterialNode*)nullptr) == RPR_SUCCESS; + } + return ProcessInput(id, value, m_toonClosureNode, RPR_MATERIAL_INPUT_NORMAL); } @@ -121,14 +129,14 @@ class RprUsd_RprToonNode : public RprUsd_MaterialNode { nodeInfo.uiName = "RPR Toon"; nodeInfo.uiFolder = "Shaders"; - nodeInfo.inputs.emplace_back(_tokens->shadowColor, GfVec3f(0.0f)); - + nodeInfo.inputs.emplace_back(_tokens->color, GfVec3f(1.0f)); + nodeInfo.inputs.emplace_back(_tokens->shadowTint, GfVec3f(0.0f)); nodeInfo.inputs.emplace_back(_tokens->midLevel, 0.5f); nodeInfo.inputs.emplace_back(_tokens->midLevelMix, 0.05f); - nodeInfo.inputs.emplace_back(_tokens->midColor, GfVec3f(0.4f)); + nodeInfo.inputs.emplace_back(_tokens->midTint, GfVec3f(0.4f)); nodeInfo.inputs.emplace_back(_tokens->highlightLevel, 0.8f); nodeInfo.inputs.emplace_back(_tokens->highlightLevelMix, 0.05f); - nodeInfo.inputs.emplace_back(_tokens->highlightColor, GfVec3f(0.8f)); + nodeInfo.inputs.emplace_back(_tokens->highlightTint, GfVec3f(0.8f)); RprUsd_RprNodeInput interpolationModeInput(_tokens->interpolationMode, _tokens->None); interpolationModeInput.value = VtValue(0); From 88186a438e7066800fd0de313c99652bf27d9c95 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Mon, 21 Jun 2021 21:45:04 +0300 Subject: [PATCH 43/50] buildmaster: version update to 2.0.46 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 5f8ce44c0..a10a3552c 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "45") +set(HD_RPR_PATCH_VERSION "46") From 5ed3ca2465853e59c559414e6d132694515c3daf Mon Sep 17 00:00:00 2001 From: s1lentssh Date: Thu, 1 Jul 2021 10:00:16 +0300 Subject: [PATCH 44/50] Updated RPR version --- deps/RPR | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/RPR b/deps/RPR index 3b2ac06d9..7afdadba3 160000 --- a/deps/RPR +++ b/deps/RPR @@ -1 +1 @@ -Subproject commit 3b2ac06d9de9de99f5cb7aa1e2bce9579c411767 +Subproject commit 7afdadba35695f36054a314ccbfec646291fbe39 From 9042e0872c54370d604effa37c7a64d41fc765a8 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 1 Jul 2021 10:15:41 +0300 Subject: [PATCH 45/50] buildmaster: version update to 2.0.47 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index a10a3552c..95eb6ca58 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "46") +set(HD_RPR_PATCH_VERSION "47") From deb936d587f11283ff898cb2f323a92e032e5d24 Mon Sep 17 00:00:00 2001 From: bsavery Date: Mon, 5 Jul 2021 21:45:48 -0700 Subject: [PATCH 46/50] Update CHANGELOG.MD --- CHANGELOG.MD | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f315517ad..40210f107 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,44 @@ # Change Log +## Version 2.1 +### New Features: +- Subsurface Scattering and Volume shaders now work in RPR 2.0. This allows the rendering of organic materials, such as skin, which absorb light into their interior. +- Deformation motion blur gives accurate motion blur to objects which are being deformed, for example, a flag flapping in the wind or a ball squashing. Besides, motion blur export has been optimized, and a setting for disabling deformation motion blur has been added. +- The new RPR Toon Shader has been added. This enables cartoon style shading for a non-photorealistic look. Toon shaders can be used in a “simple” mode for just setting a color or a gradient of different colors for shadow vs lit areas of the object. +- Support for USD 21.05 has been added. +- Cryptomatte AOVs can now be exported from Houdini. + + +### Issues Fixed: +- Overbright edges of objects with Uber shaders in metalness mode ― fixed. +- Shaders with high roughness could have artifacts with reflection or refraction ― fixed. +- Users can now override the environment light background color in Houdini. +- The render’s “percent done” statistics could be incorrect if the minimum number of samples had not yet been reached ― fixed. +- An issue with the visibility of distant lights not being respected has been fixed. +- A crash was occurring on macOS in some cases when using the RPR Material Library for the first time ― fixed. +- RPR Materials nodes were not present in Houdini on Linux ― fixed. +- The speed of rendering via Houdini’s Husk utility with multiple render products has been increased. +- .rpr export fixes: + - .rpr export now exports USD depth AOV correctly; + - An issue with creating temporary directories when exporting .rpr files has been fixed; + - The $OS variable can now be used in the output path to change the path based on the operating system. +- Developer changes to hdRPR: + - The hdRPR render delegate can now override the kernel cache path with an environment variable; + - The batch or interactive render mode can now be switched on dynamically. +- MaterialX fixes: + - Logging with the MaterialX loader has been improved; + - Support for the Tangent node has been added; + - Support for the View Direction node has been added; + - Support for the RPR Emissive node has been added; + - The displacement scale has been fixed; + - An issue with the use of the mix node to mix surface shaders has been fixed. + +### Known Issues: +- In RPR 2.0, heterogenous volumes, smoke and fire simulations or VDB files are not yet supported. +- Subsurface scattering and volume shader are currently disabled on macOS due to long compile times. +- Some AOVs may have artifacts on AMD cards with drivers earlier than 21.6.1 + + ## Version 2.0.27 ### New Features: - Support for AMD Radeon™ RX 6700 XT graphics cards has been added. From 074815fd664de04a7b694cb8b6c79c18f351d7a7 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 6 Jul 2021 07:58:11 +0300 Subject: [PATCH 47/50] buildmaster: version update to 2.0.48 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 95eb6ca58..31de8fa03 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "47") +set(HD_RPR_PATCH_VERSION "48") From 9a55aa8589644f4275240087c3b6f051c272f108 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Tue, 6 Jul 2021 18:05:28 +0300 Subject: [PATCH 48/50] Hotfix RPR core (#481) From b0203bca189535615e34023c9efab576056ba30d Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 6 Jul 2021 18:09:38 +0300 Subject: [PATCH 49/50] buildmaster: version update to 2.0.49 --- cmake/defaults/Version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 31de8fa03..a25c1110c 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(HD_RPR_MAJOR_VERSION "2") set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "48") +set(HD_RPR_PATCH_VERSION "49") From 40ebf7b866d470119c5b4d236d6940f4f36f9dd0 Mon Sep 17 00:00:00 2001 From: bsavery Date: Tue, 6 Jul 2021 08:30:48 -0700 Subject: [PATCH 50/50] Update Version.cmake --- cmake/defaults/Version.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index a25c1110c..4ea9235d4 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -23,5 +23,5 @@ # # Versioning information set(HD_RPR_MAJOR_VERSION "2") -set(HD_RPR_MINOR_VERSION "0") -set(HD_RPR_PATCH_VERSION "49") +set(HD_RPR_MINOR_VERSION "2") +set(HD_RPR_PATCH_VERSION "0")