From 17132f1afadd5682bb236430e8dc3256778b3af1 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 17 Nov 2020 20:03:59 +0100 Subject: [PATCH 01/32] buildmaster: version update to 2.0.2 --- 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 3507907d5..bc5cf10c5 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 "1") +set(HD_RPR_PATCH_VERSION "2") From c57d1ef9541e2229c1a3df5dda38811e89502c63 Mon Sep 17 00:00:00 2001 From: hshakula Date: Mon, 23 Nov 2020 13:04:36 +0200 Subject: [PATCH 02/32] Update Houdini's plugin activation utilitiy Starting from Houdini 18.5.402, it does not expand user-defined variables, so we do it manually. --- .../rprHoudini/activateHoudiniPlugin.cpp.in | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in b/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in index d43595eca..c33a4bade 100644 --- a/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in +++ b/pxr/imaging/plugin/rprHoudini/activateHoudiniPlugin.cpp.in @@ -214,12 +214,12 @@ int ActivateHoudiniPlugin() { return EXIT_FAILURE; } - std::map env = { - {"RPR", rprPath}, - {"HOUDINI_PATH", "$RPR/houdini"}, - {"PYTHONPATH", "$RPR/lib/python"}, + std::vector> env = { + {"RPR", ""}, + {"HOUDINI_PATH", "/houdini"}, + {"PYTHONPATH", "/lib/python"}, #if defined(_WIN32) || defined(_WIN64) - {"PATH", "$RPR/lib"} + {"PATH", "/lib"} #endif }; @@ -231,15 +231,9 @@ int ActivateHoudiniPlugin() { packageJson << '{'; packageJson << '\"' << it->first << '\"'; packageJson << ':'; -#if defined(_WIN32) || defined(_WIN64) packageJson << '\"'; - auto path = it->second.string(); - std::replace(path.begin(), path.end(), '\\', '/'); - packageJson << path; + packageJson << rprPath << it->second; packageJson << '\"'; -#else - packageJson << it->second; -#endif packageJson << '}'; if (std::next(it) != env.end()) { packageJson << ','; From b43cbd4f3c6a448f6fbab8ba3ed3fabc897f2a1f Mon Sep 17 00:00:00 2001 From: hshakula Date: Tue, 24 Nov 2020 16:13:32 +0200 Subject: [PATCH 03/32] Update render settings UI * Show adaptive sampling only for Tahoe * Hide interactive max ray depth for hybrid * Show alpha checkbox for all render qualities --- .../hdRpr/python/generateRenderSettingFiles.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index e460333ba..48d9bc817 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -49,6 +49,9 @@ def hidewhen_hybrid(render_setting_categories): def hidewhen_not_northstar(render_setting_categories): return hidewhen_render_quality('!=', 'Northstar', render_setting_categories) +def hidewhen_not_tahoe(render_setting_categories): + return hidewhen_render_quality('!=', 'Full', render_setting_categories) + HYBRID_DISABLED_PLATFORM = 'Darwin' render_setting_categories = [ @@ -160,7 +163,7 @@ def hidewhen_not_northstar(render_setting_categories): { 'name': 'AdaptiveSampling', 'houdini': { - 'hidewhen': hidewhen_hybrid + 'hidewhen': hidewhen_not_tahoe }, 'settings': [ { @@ -267,7 +270,10 @@ def hidewhen_not_northstar(render_setting_categories): 'help': 'Controls value of \'Max Ray Depth\' in interactive mode.', 'defaultValue': 2, 'minValue': 1, - 'maxValue': 50 + 'maxValue': 50, + 'houdini': { + 'hidewhen': hidewhen_hybrid + } }, { 'name': 'interactiveResolutionDownscale', @@ -343,10 +349,7 @@ def hidewhen_not_northstar(render_setting_categories): { 'name': 'enableAlpha', 'ui_name': 'Enable Color Alpha', - 'defaultValue': True, - 'houdini': { - 'hidewhen': hidewhen_hybrid - } + 'defaultValue': True } ] }, @@ -397,7 +400,7 @@ def hidewhen_not_northstar(render_setting_categories): 'ui_name': 'Use Uniform Seed', 'defaultValue': True, 'houdini': { - 'hidewhen': 'renderQuality < 3' + 'hidewhen': hidewhen_hybrid } } ] From 261b24db3e989e16d3f733d5726379a48ef4694d Mon Sep 17 00:00:00 2001 From: hshakula Date: Tue, 24 Nov 2020 16:59:29 +0200 Subject: [PATCH 04/32] Improve ID AOVs Previously, we were not able to distinguish 0 id pixels and void pixels (where no geometry present). By offsetting the AOV index lookup by one we can achieve that void pixels will have -1 id. --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 4 ++-- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 0eca02e52..ee48560ed 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2761,8 +2761,8 @@ Don't show this message again? // * convert float4 texture to uchar4 using RIF // * reinterpret uchar4 data as int32_t (works on little-endian CPU only) m_rprContext->SetAOVindexLookup(rpr_int(i), - float((i >> 0) & 0xFF) / 255.0f, - float((i >> 8) & 0xFF) / 255.0f, + float(((i + 1) >> 0) & 0xFF) / 255.0f, + float(((i + 1) >> 8) & 0xFF) / 255.0f, 0.0f, 0.0f); } } diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 6f1e14f40..0c76a6c47 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -131,7 +131,7 @@ bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { // That's why we interpret the value as int and filling the alpha channel with zeros auto primIdData = reinterpret_cast(dstBuffer); for (size_t i = 0; i < dstBufferSize / sizeof(int); ++i) { - primIdData[i] &= 0xFFFFFF; + primIdData[i] = (primIdData[i] & 0xFFFFFF) - 1; } } From 4b148d16d4bbcd322bdddc0ac50961e2f7f1f2f3 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 24 Nov 2020 19:28:44 +0100 Subject: [PATCH 05/32] buildmaster: version update to 2.0.3 --- 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 bc5cf10c5..4fcfaa988 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 "2") +set(HD_RPR_PATCH_VERSION "3") From 8b9559a6012c0ce453a53d203fe95688f6890b2e Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Tue, 24 Nov 2020 19:43:44 +0100 Subject: [PATCH 06/32] buildmaster: version update to 2.0.4 --- 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 4fcfaa988..477d1ccf2 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 "3") +set(HD_RPR_PATCH_VERSION "4") From 3d91b6e983a85a7bbae1277088561d450412b621 Mon Sep 17 00:00:00 2001 From: hshakula Date: Thu, 26 Nov 2020 18:10:55 +0200 Subject: [PATCH 07/32] Fix UsdPreviewSurface normal UsdPreviewSurface expects normal in tangent space [(-1,-1,-1), (1,1,1)]. --- pxr/imaging/rprUsd/materialNodes/usdNode.cpp | 11 ++++++++++- pxr/imaging/rprUsd/materialNodes/usdNode.h | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp index ff84b8322..155db91b0 100644 --- a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp @@ -145,8 +145,17 @@ bool RprUsd_UsdPreviewSurface::SetInput( if (value.IsHolding()) { if (!m_normalMapNode) { m_normalMapNode.reset(new RprUsd_BaseRuntimeNode(RPR_MATERIAL_NODE_NORMAL_MAP, m_ctx)); + m_normalMapScaleNode = RprUsd_RprArithmeticNode::Create(RPR_MATERIAL_NODE_OP_MUL, m_ctx); + m_normalMapBiasNode = RprUsd_RprArithmeticNode::Create(RPR_MATERIAL_NODE_OP_ADD, m_ctx); } - m_normalMapNode->SetInput(RPR_MATERIAL_INPUT_COLOR, value); + + m_normalMapScaleNode->SetInput(0, value); + m_normalMapScaleNode->SetInput(1, VtValue(GfVec4f(0.5f))); + + m_normalMapBiasNode->SetInput(0, m_normalMapScaleNode->GetOutput()); + m_normalMapBiasNode->SetInput(1, VtValue(GfVec4f(0.5f))); + + m_normalMapNode->SetInput(RPR_MATERIAL_INPUT_COLOR, m_normalMapBiasNode->GetOutput()); auto normalMapOutput = m_normalMapNode->GetOutput(TfToken()); return (SetRprInput(m_rprNode.get(), RPR_MATERIAL_INPUT_UBER_DIFFUSE_NORMAL, normalMapOutput) == RPR_SUCCESS) && diff --git a/pxr/imaging/rprUsd/materialNodes/usdNode.h b/pxr/imaging/rprUsd/materialNodes/usdNode.h index cd10b5503..5089d51e2 100644 --- a/pxr/imaging/rprUsd/materialNodes/usdNode.h +++ b/pxr/imaging/rprUsd/materialNodes/usdNode.h @@ -41,6 +41,9 @@ class RprUsd_UsdPreviewSurface : public RprUsd_BaseRuntimeNode { std::unique_ptr m_emissiveWeightNode; std::unique_ptr m_refractionWeightNode; + + std::unique_ptr m_normalMapScaleNode; + std::unique_ptr m_normalMapBiasNode; std::unique_ptr m_normalMapNode; std::shared_ptr m_displaceNode; From 38e16b7c293a180bf58cd13f9ea4689072267b9d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 26 Nov 2020 13:52:20 -0500 Subject: [PATCH 08/32] Convert textures into a format required by the material graph (#407) PURPOSE Fix unexpected behavior (from the artists point of view) when using single-channel grey textures, dual-channel (red-alpha), and others. EFFECT OF CHANGE More artist-friendly texture appearance, e.g. single-channel greyscale jpegs. --- deps/CMakeLists.txt | 2 +- deps/rprMtlxLoader/rprMtlxLoader.cpp | 11 +- deps/rprMtlxLoader/rprMtlxLoader.h | 3 + pxr/imaging/plugin/hdRpr/rprApi.cpp | 2 +- pxr/imaging/rprUsd/coreImage.cpp | 126 +++++++++++++++++- pxr/imaging/rprUsd/coreImage.h | 4 +- pxr/imaging/rprUsd/imageCache.cpp | 5 +- pxr/imaging/rprUsd/imageCache.h | 3 +- .../rprUsd/materialNodes/materialNode.h | 19 +++ .../materialNodes/rpr/materialXNode.cpp | 14 +- pxr/imaging/rprUsd/materialNodes/usdNode.cpp | 32 +++++ pxr/imaging/rprUsd/materialRegistry.cpp | 24 +--- pxr/imaging/rprUsd/materialRegistry.h | 1 + 13 files changed, 207 insertions(+), 39 deletions(-) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 42de65f06..1e14b577f 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -50,7 +50,7 @@ add_library(cpprpr STATIC ${RPR_CPP_WRAPPER_LOCATION}/RadeonProRenderCpp.cpp ${RPR_CPP_WRAPPER_LOCATION}/tinyxml2.cpp) set_target_properties(cpprpr PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_include_directories(cpprpr PUBLIC ${RPR_CPP_WRAPPER_LOCATION} ${RPRMTLXLOADER_LOCATION}) +target_include_directories(cpprpr PUBLIC ${RPRMTLXLOADER_LOCATION} ${RPR_CPP_WRAPPER_LOCATION}) target_link_libraries(cpprpr PUBLIC rpr MaterialXCore MaterialXFormat) target_compile_definitions(cpprpr PUBLIC RPR_CPPWRAPER_DISABLE_MUTEXLOCK diff --git a/deps/rprMtlxLoader/rprMtlxLoader.cpp b/deps/rprMtlxLoader/rprMtlxLoader.cpp index 700796655..d9b10d570 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.cpp +++ b/deps/rprMtlxLoader/rprMtlxLoader.cpp @@ -367,6 +367,7 @@ struct RprMappedNode : public RprNode { struct RprImageNode : public RprMappedNode { // TODO: support frame ranges + std::string type; std::string file; std::string layer; mx::ValuePtr defaultValue; @@ -379,7 +380,7 @@ struct RprImageNode : public RprMappedNode { // TODO: can we support this in RPR? //std::string filtertype; - RprImageNode(LoaderContext* context); + RprImageNode(std::string const& type, LoaderContext* context); ~RprImageNode() override = default; rpr_status SetInput(mx::Element* inputElement, std::string const& value, std::string const& valueType, LoaderContext* context) override; @@ -824,7 +825,7 @@ Node::Ptr Node::Create(mx::Node* mtlxNode, LoaderContext* context) { }; rprNodeMapping = &s_sqrtMapping; } else if (mtlxNode->getCategory() == "image") { - return std::make_unique(context); + return std::make_unique(mtlxNode->getType(), context); } else if (mtlxNode->getCategory() == "swizzle") { // TODO: implement healthy man swizzle @@ -1371,7 +1372,7 @@ rpr_status RprMappedNode::SetInput(mx::Element* inputElement, std::string const& return RprNode::SetInput(inputIt->second, valueString, valueType, context); } -RprImageNode::RprImageNode(LoaderContext* context) +RprImageNode::RprImageNode(std::string const& type, LoaderContext* context) : RprMappedNode( [context]() { rpr_material_node node = nullptr; @@ -1386,7 +1387,8 @@ RprImageNode::RprImageNode(LoaderContext* context) }; return &s_imageMapping; }() - ) { + ) + , type(type) { } @@ -1995,6 +1997,7 @@ RPRMtlxLoader::Result RPRMtlxLoader::Load( outImageNodes.emplace_back(); auto& outImageNode = outImageNodes.back(); + std::swap(outImageNode.type, imageNode->type); std::swap(outImageNode.file, imageNode->file); std::swap(outImageNode.layer, imageNode->layer); std::swap(outImageNode.defaultValue, imageNode->defaultValue); diff --git a/deps/rprMtlxLoader/rprMtlxLoader.h b/deps/rprMtlxLoader/rprMtlxLoader.h index 9afc5ec59..2e3be5501 100644 --- a/deps/rprMtlxLoader/rprMtlxLoader.h +++ b/deps/rprMtlxLoader/rprMtlxLoader.h @@ -41,6 +41,9 @@ class RPRMtlxLoader { static const size_t kInvalidRootNodeIndex = size_t(-1); struct ImageNode { + /// MaterialX type + std::string type; + /// The URI of an image file. /// It's responsibility of the loader user to setup rpr_image and bind it to rprNode std::string file; diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index ee48560ed..435b858b5 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -804,7 +804,7 @@ class HdRprApiImpl { LockGuard rprLock(m_rprContext->GetMutex()); - auto image = std::unique_ptr(RprUsdCoreImage::Create(m_rprContext.get(), path)); + auto image = std::unique_ptr(RprUsdCoreImage::Create(m_rprContext.get(), path, 0)); if (!image) { return nullptr; } diff --git a/pxr/imaging/rprUsd/coreImage.cpp b/pxr/imaging/rprUsd/coreImage.cpp index 89824c0c4..6e1d49e3f 100644 --- a/pxr/imaging/rprUsd/coreImage.cpp +++ b/pxr/imaging/rprUsd/coreImage.cpp @@ -38,7 +38,98 @@ rpr::ImageDesc GetRprImageDesc(rpr::ImageFormat format, uint32_t width, uint32_t return desc; } -rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData) { +template +std::unique_ptr _ConvertTexture(GlfUVTextureData* textureData, rpr::ImageFormat const& srcFormat, uint32_t dstNumComponents, PixelConverterFunc&& converter) { + uint8_t* src = textureData->GetRawBuffer(); + + size_t srcPixelStride = srcFormat.num_components * sizeof(ComponentT); + size_t dstPixelStride = dstNumComponents * sizeof(ComponentT); + + size_t numPixels = size_t(textureData->ResizedWidth()) * textureData->ResizedHeight(); + auto dstData = std::make_unique(numPixels * dstPixelStride); + uint8_t* dst = dstData.get(); + + for (size_t i = 0; i < numPixels; ++i) { + converter((ComponentT*)(dst + i * dstPixelStride), (ComponentT*)(src + i * srcPixelStride)); + } + + return dstData; +} + +template +struct WhiteColor { + const T value = static_cast(1); +}; + +template <> struct WhiteColor { + const uint8_t value = 255u; +}; + +template +std::unique_ptr ConvertTexture(GlfUVTextureData* textureData, rpr::ImageFormat const& format, uint32_t dstNumComponents) { + if (dstNumComponents < format.num_components) { + // Trim excessive channels + return _ConvertTexture(textureData, format, dstNumComponents, + [=](ComponentT* dst, ComponentT* src) { + for (size_t i = 0; i < dstNumComponents; ++i) { + dst[i] = src[i]; + } + } + ); + } + + if (format.num_components == 1) { + // Expand to a required amount of channels. Example: greyscale texture that is stored as single-channel. + if (dstNumComponents == 4) { + // r -> rrr1 + return _ConvertTexture(textureData, format, dstNumComponents, + [](ComponentT* dst, ComponentT* src) { + dst[0] = dst[1] = dst[2] = src[0]; + dst[3] = WhiteColor{}.value; + } + ); + } else { + return _ConvertTexture(textureData, format, dstNumComponents, + [=](ComponentT* dst, ComponentT* src) { + for (size_t i = 0; i < dstNumComponents; ++i) { + dst[i] = src[0]; + } + } + ); + } + } else if (format.num_components == 2) { + if (dstNumComponents == 4) { + // rg -> rrrg + return _ConvertTexture(textureData, format, dstNumComponents, + [](ComponentT* dst, ComponentT* src) { + dst[0] = dst[1] = dst[2] = src[0]; + dst[3] = src[1]; + } + ); + } else { + // rg -> rrr + return _ConvertTexture(textureData, format, dstNumComponents, + [](ComponentT* dst, ComponentT* src) { + dst[0] = dst[1] = dst[2] = src[0]; + } + ); + } + } else if (format.num_components == 3) { + // rgb -> rgb1 + return _ConvertTexture(textureData, format, dstNumComponents, + [](ComponentT* dst, ComponentT* src) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = WhiteColor{}.value; + } + ); + } + + return nullptr; +} + +rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData, uint32_t numComponentsRequired) { rpr::ImageFormat format = {}; #if PXR_VERSION >= 2011 @@ -81,8 +172,28 @@ rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData) } rpr::ImageDesc desc = GetRprImageDesc(format, textureData->ResizedWidth(), textureData->ResizedHeight()); + auto textureBuffer = textureData->GetRawBuffer(); + + std::unique_ptr convertedData; + if (numComponentsRequired != 0 && + numComponentsRequired != format.num_components) { + if (format.type == RPR_COMPONENT_TYPE_UINT8) { + convertedData = ConvertTexture(textureData, format, numComponentsRequired); + } else if (format.type == RPR_COMPONENT_TYPE_FLOAT16) { + convertedData = ConvertTexture(textureData, format, numComponentsRequired); + } else if (format.type == RPR_COMPONENT_TYPE_FLOAT32) { + convertedData = ConvertTexture(textureData, format, numComponentsRequired); + } + + if (convertedData) { + textureBuffer = convertedData.get(); + format.num_components = numComponentsRequired; + desc = GetRprImageDesc(format, textureData->ResizedWidth(), textureData->ResizedHeight()); + } + } + rpr::Status status; - auto rprImage = context->CreateImage(format, desc, textureData->GetRawBuffer(), &status); + auto rprImage = context->CreateImage(format, desc, textureBuffer, &status); if (!rprImage) { RPR_ERROR_CHECK(status, "Failed to create image from data", context); return nullptr; @@ -93,13 +204,13 @@ rpr::Image* CreateRprImage(rpr::Context* context, GlfUVTextureData* textureData) } // namespace anonymous -RprUsdCoreImage* RprUsdCoreImage::Create(rpr::Context* context, std::string const& path) { +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)) { return nullptr; } - return Create(context, {{0, textureData.operator->()}}); + return Create(context, {{0, textureData.operator->()}}, numComponentsRequired); } RprUsdCoreImage* RprUsdCoreImage::Create(rpr::Context* context, uint32_t width, uint32_t height, rpr::ImageFormat format, void const* data, rpr::Status* status) { @@ -113,7 +224,8 @@ RprUsdCoreImage* RprUsdCoreImage::Create(rpr::Context* context, uint32_t width, RprUsdCoreImage* RprUsdCoreImage::Create( rpr::Context* context, - std::vector const& tiles) { + std::vector const& tiles, + uint32_t numComponentsRequired) { if (tiles.empty()) { return nullptr; @@ -121,7 +233,7 @@ RprUsdCoreImage* RprUsdCoreImage::Create( if (tiles.size() == 1 && tiles[0].id == 0) { // Single non-UDIM tile - auto rprImage = CreateRprImage(context, tiles[0].textureData); + auto rprImage = CreateRprImage(context, tiles[0].textureData, numComponentsRequired); if (!rprImage) { return nullptr; } @@ -137,7 +249,7 @@ RprUsdCoreImage* RprUsdCoreImage::Create( continue; } - auto rprImage = CreateRprImage(context, tile.textureData); + auto rprImage = CreateRprImage(context, tile.textureData, numComponentsRequired); if (!rprImage) { continue; } diff --git a/pxr/imaging/rprUsd/coreImage.h b/pxr/imaging/rprUsd/coreImage.h index 7711f2a84..ae64eb6d8 100644 --- a/pxr/imaging/rprUsd/coreImage.h +++ b/pxr/imaging/rprUsd/coreImage.h @@ -26,7 +26,7 @@ PXR_NAMESPACE_OPEN_SCOPE class RprUsdCoreImage { public: RPRUSD_API - static RprUsdCoreImage* Create(rpr::Context* context, std::string const& path); + static RprUsdCoreImage* Create(rpr::Context* context, std::string const& path, uint32_t numComponentsRequired); struct UDIMTile { uint32_t id; @@ -35,7 +35,7 @@ class RprUsdCoreImage { UDIMTile(uint32_t id, GlfUVTextureData* textureData) : id(id), textureData(textureData) {} }; RPRUSD_API - static RprUsdCoreImage* Create(rpr::Context* context, std::vector const& textureData); + static RprUsdCoreImage* Create(rpr::Context* context, std::vector const& textureData, uint32_t numComponentsRequired); RPRUSD_API static RprUsdCoreImage* Create(rpr::Context* context, uint32_t width, uint32_t height, rpr::ImageFormat format, void const* data, rpr::Status* status = nullptr); diff --git a/pxr/imaging/rprUsd/imageCache.cpp b/pxr/imaging/rprUsd/imageCache.cpp index c6bbe58ad..f1b989483 100644 --- a/pxr/imaging/rprUsd/imageCache.cpp +++ b/pxr/imaging/rprUsd/imageCache.cpp @@ -42,7 +42,8 @@ RprUsdImageCache::GetImage( std::string const& path, std::string const& colorspace, rpr::ImageWrapType wrapType, - std::vector const& tiles) { + std::vector const& tiles, + uint32_t numComponentsRequired) { if (!wrapType) { wrapType = RPR_IMAGE_WRAP_TYPE_REPEAT; } @@ -64,7 +65,7 @@ RprUsdImageCache::GetImage( } } - auto coreImage = RprUsdCoreImage::Create(m_context, tiles); + auto coreImage = RprUsdCoreImage::Create(m_context, tiles, numComponentsRequired); if (!coreImage) { return nullptr; } diff --git a/pxr/imaging/rprUsd/imageCache.h b/pxr/imaging/rprUsd/imageCache.h index 7b18f1e93..c4919cb7d 100644 --- a/pxr/imaging/rprUsd/imageCache.h +++ b/pxr/imaging/rprUsd/imageCache.h @@ -32,7 +32,8 @@ class RprUsdImageCache { std::string const& path, std::string const& colorspace, rpr::ImageWrapType wrapType, - std::vector const& data = {}); + std::vector const& data, + uint32_t numComponentsRequired); private: rpr::Context* m_context; diff --git a/pxr/imaging/rprUsd/materialNodes/materialNode.h b/pxr/imaging/rprUsd/materialNodes/materialNode.h index 71170915d..222fb7eaa 100644 --- a/pxr/imaging/rprUsd/materialNodes/materialNode.h +++ b/pxr/imaging/rprUsd/materialNodes/materialNode.h @@ -24,7 +24,26 @@ PXR_NAMESPACE_OPEN_SCOPE class RprUsdImageCache; +struct RprUsd_MaterialNetwork { + struct Connection { + SdfPath upstreamNode; + TfToken upstreamOutputName; + }; + + struct Node { + TfToken nodeTypeId; + std::map parameters; + std::map inputConnections; + }; + + std::map nodes; + std::map terminals; +}; + struct RprUsd_MaterialBuilderContext { + RprUsd_MaterialNetwork const* hdMaterialNetwork; + SdfPath const* currentNodePath; + rpr::Context* rprContext; RprUsdImageCache* imageCache; diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp index 6a69f2913..84633bc9b 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp @@ -212,7 +212,7 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { } else { // Find the only existing output - RPRMtlxLoader::OutputType outputType; + RPRMtlxLoader::OutputType outputType = RPRMtlxLoader::kOutputNone; for (int i = 0; i < RPRMtlxLoader::kOutputsTotal; ++i) { if (mtlx.rootNodeIndices[i] != RPRMtlxLoader::Result::kInvalidRootNodeIndex) { outputType = RPRMtlxLoader::OutputType(i); @@ -268,6 +268,18 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { } } + if (mtlxImageNode.type == "float") { + textureCommit.numComponentsRequired = 1; + } else if (mtlxImageNode.type == "vector2" || mtlxImageNode.type == "color2") { + textureCommit.numComponentsRequired = 2; + } else if (mtlxImageNode.type == "vector3" || mtlxImageNode.type == "color3") { + textureCommit.numComponentsRequired = 3; + } else if (mtlxImageNode.type == "vector4" || mtlxImageNode.type == "color4") { + textureCommit.numComponentsRequired = 4; + } else { + TF_WARN("Invalid image materialX type: %s", mtlxImageNode.type.c_str()); + } + rpr_material_node rprImageNode = mtlxImageNode.rprNode; textureCommit.setTextureCallback = [retainedImagesPtr, rprImageNode](std::shared_ptr const& image) { if (!image) return; diff --git a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp index 155db91b0..020911f28 100644 --- a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp @@ -291,6 +291,38 @@ RprUsd_UsdUVTexture::RprUsd_UsdUVTexture( } }; + // Analyze material graph and find out the minimum required amount of components required + textureCommit.numComponentsRequired = 0; + for (auto& entry : m_ctx->hdMaterialNetwork->nodes) { + for (auto& connection : entry.second.inputConnections) { + if (connection.second.upstreamNode == *m_ctx->currentNodePath) { + uint32_t numComponentsRequired = 0; + if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->rgba) { + numComponentsRequired = 4; + } else if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->rgb) { + numComponentsRequired = 3; + } else if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->r) { + numComponentsRequired = 1; + } else if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->g) { + numComponentsRequired = 2; + } else if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->b) { + numComponentsRequired = 3; + } else if (connection.second.upstreamOutputName == RprUsd_UsdUVTextureTokens->a) { + numComponentsRequired = 4; + } + textureCommit.numComponentsRequired = std::max(textureCommit.numComponentsRequired, numComponentsRequired); + + if (textureCommit.numComponentsRequired == 4) { + break; + } + } + } + + if (textureCommit.numComponentsRequired == 4) { + break; + } + } + // Texture loading is postponed to allow multi-threading loading. // RprUsdMaterialRegistry::GetInstance().CommitTexture(std::move(textureCommit)); diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 33ae6f5b6..16813cef3 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -144,7 +144,7 @@ void RprUsdMaterialRegistry::CommitResources( std::string formatString; for (size_t i = 0; i < m_textureCommits.size(); ++i) { auto& commit = m_textureCommits[i]; - if (auto rprImage = imageCache->GetImage(commit.filepath, commit.colorspace, commit.wrapType)) { + if (auto rprImage = imageCache->GetImage(commit.filepath, commit.colorspace, commit.wrapType, {}, 0)) { commit.setTextureCallback(rprImage); continue; } @@ -198,7 +198,7 @@ void RprUsdMaterialRegistry::CommitResources( } auto& commit = m_textureCommits[i]; - auto coreImage = imageCache->GetImage(commit.filepath, commit.colorspace, commit.wrapType, tiles); + auto coreImage = imageCache->GetImage(commit.filepath, commit.colorspace, commit.wrapType, tiles, commit.numComponentsRequired); commit.setTextureCallback(coreImage); } @@ -300,24 +300,6 @@ void DumpMaterialNetwork(HdMaterialNetworkMap const& networkMap) { } } -// Structures are taken from hdSt/materialNetwork.cpp - -struct RprUsd_MaterialNetwork { - struct Connection { - SdfPath upstreamNode; - TfToken upstreamOutputName; - }; - - struct Node { - TfToken nodeTypeId; - std::map parameters; - std::map inputConnections; - }; - - std::map nodes; - std::map terminals; -}; - void ConvertLegacyHdMaterialNetwork( HdMaterialNetworkMap const& hdNetworkMap, RprUsd_MaterialNetwork *result) { @@ -383,6 +365,7 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( ConvertLegacyHdMaterialNetwork(legacyNetworkMap, &network); RprUsd_MaterialBuilderContext context = {}; + context.hdMaterialNetwork = &network; context.rprContext = rprContext; context.imageCache = imageCache; context.mtlxLoader = m_mtlxLoader.get(); @@ -435,6 +418,7 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( for (auto& entry : network.nodes) { auto& nodePath = entry.first; auto& node = entry.second; + context.currentNodePath = &nodePath; try { // Check if we have registered node that match nodeTypeId diff --git a/pxr/imaging/rprUsd/materialRegistry.h b/pxr/imaging/rprUsd/materialRegistry.h index 737efb608..3ecb83e75 100644 --- a/pxr/imaging/rprUsd/materialRegistry.h +++ b/pxr/imaging/rprUsd/materialRegistry.h @@ -86,6 +86,7 @@ class RprUsdMaterialRegistry { std::string filepath; std::string colorspace; rpr::ImageWrapType wrapType; + uint32_t numComponentsRequired = 0; std::function const&)> setTextureCallback; }; From 243d5422ecbb1b777926c15e3d38ee61daee277f Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 26 Nov 2020 13:52:50 -0500 Subject: [PATCH 09/32] Add mtlx-string inputs for rpr_materialx_node (#408) PURPOSE To allow using rpr_materialx_node without forcible saving .mtlx file to the disk. EFFECT OF CHANGE Add a way to pass MaterialX as a string. --- .../rprUsd/materialNodes/materialNode.h | 2 +- .../materialNodes/rpr/materialXNode.cpp | 91 +++++++++++++------ .../rprUsd/materialNodes/rpr/materialXNode.h | 2 + pxr/imaging/rprUsd/materialNodes/usdNode.cpp | 16 +++- pxr/imaging/rprUsd/materialRegistry.cpp | 2 +- 5 files changed, 80 insertions(+), 33 deletions(-) diff --git a/pxr/imaging/rprUsd/materialNodes/materialNode.h b/pxr/imaging/rprUsd/materialNodes/materialNode.h index 222fb7eaa..9f0c0e836 100644 --- a/pxr/imaging/rprUsd/materialNodes/materialNode.h +++ b/pxr/imaging/rprUsd/materialNodes/materialNode.h @@ -47,7 +47,7 @@ struct RprUsd_MaterialBuilderContext { rpr::Context* rprContext; RprUsdImageCache* imageCache; - TfToken uvPrimvarName; + std::string uvPrimvarName; bool isShadowCatcher; bool isReflectionCatcher; diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp index 84633bc9b..a05094cde 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.cpp @@ -36,6 +36,20 @@ static rpr_material_node ReleaseOutputNodeOwnership(RPRMtlxLoader::Result* mtlx, return ret; } +template +static bool ReadInput(TfToken const& inputId, VtValue const& inputValue, T* dst) { + if (inputValue.IsHolding()) { + *dst = inputValue.UncheckedGet(); + return true; + } else { + TF_RUNTIME_ERROR("[%s] %s input should be of %s type: %s", + RprUsdRprMaterialXNodeTokens->rpr_materialx_node.GetText(), + inputId.GetText(), ArchGetDemangled().c_str(), + inputValue.GetTypeName().c_str()); + return false; + } +} + class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { public: RprUsd_RprMaterialXNode(RprUsd_MaterialBuilderContext* ctx) @@ -81,19 +95,20 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { RprUsdRprMaterialXNodeTokens->rpr_materialx_node.GetText(), value.GetTypeName().c_str()); return false; } + } else if (inputId == RprUsdRprMaterialXNodeTokens->string) { + bool ret = ReadInput(inputId, value, &m_mtlxString); + if (ret) { ResetNodeOutput(); } + return ret; + } else if (inputId == RprUsdRprMaterialXNodeTokens->basePath) { + bool ret = ReadInput(inputId, value, &m_mtlxBasePath); + if (ret) { ResetNodeOutput(); } + return ret; } else if (inputId == RprUsdRprMaterialXNodeTokens->surfaceElement) { return SetRenderElement(RPRMtlxLoader::kOutputSurface, value); } else if (inputId == RprUsdRprMaterialXNodeTokens->displacementElement) { return SetRenderElement(RPRMtlxLoader::kOutputDisplacement, value); } else if (inputId == RprUsdRprMaterialXNodeTokens->stPrimvarName) { - if (value.IsHolding()) { - m_ctx->uvPrimvarName = TfToken(value.UncheckedGet()); - return true; - } else { - TF_RUNTIME_ERROR("[%s] file input should be of string type: %s", - RprUsdRprMaterialXNodeTokens->rpr_materialx_node.GetText(), value.GetTypeName().c_str()); - return false; - } + return ReadInput(inputId, value, &m_ctx->uvPrimvarName); } TF_RUNTIME_ERROR("[%s] Unknown input %s", @@ -125,13 +140,21 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { } bool UpdateNodeOutput() { - auto basePath = TfGetPathName(m_mtlxFilepath); + auto basePath = !m_mtlxBasePath.empty() ? m_mtlxBasePath : TfGetPathName(m_mtlxFilepath); + if (basePath.empty()) { + TF_WARN("[rpr_materialx_node] no base path specified, image loading might be broken"); + } if (m_ctx->mtlxLoader) { RPRMtlxLoader::Result mtlx; try { auto mtlxDoc = MaterialX::createDocument(); - MaterialX::readFromXmlFile(mtlxDoc, m_mtlxFilepath); + if (!m_mtlxFilepath.empty()) { + MaterialX::readFromXmlFile(mtlxDoc, m_mtlxFilepath); + } + if (!m_mtlxString.empty()) { + MaterialX::readFromXmlString(mtlxDoc, m_mtlxString); + } mtlxDoc->importLibrary(m_ctx->mtlxLoader->GetStdlib()); rpr_material_system matSys; @@ -301,25 +324,29 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { return m_surfaceNode || m_displacementNode; } - std::ifstream mtlxFile(m_mtlxFilepath); - if (!mtlxFile.good()) { - TF_RUNTIME_ERROR("Failed to open \"%s\" file", m_mtlxFilepath.c_str()); - return false; - } + rpr::Status status; + if (!m_mtlxString.empty()) { + m_surfaceNode.reset(m_ctx->rprContext->CreateMaterialXNode(m_mtlxString.c_str(), basePath.c_str(), 0, nullptr, nullptr, &status)); + } else { + std::ifstream mtlxFile(m_mtlxFilepath); + if (!mtlxFile.good()) { + TF_RUNTIME_ERROR("Failed to open \"%s\" file", m_mtlxFilepath.c_str()); + return false; + } - mtlxFile.seekg(0, std::ios::end); - auto fileSize = mtlxFile.tellg(); - if (fileSize == 0) { - TF_RUNTIME_ERROR("Empty file: \"%s\"", m_mtlxFilepath.c_str()); - return false; - } + mtlxFile.seekg(0, std::ios::end); + auto fileSize = mtlxFile.tellg(); + if (fileSize == 0) { + TF_RUNTIME_ERROR("Empty file: \"%s\"", m_mtlxFilepath.c_str()); + return false; + } - auto xmlData = std::make_unique(fileSize); - mtlxFile.seekg(0); - mtlxFile.read(&xmlData[0], fileSize); + auto xmlData = std::make_unique(fileSize); + mtlxFile.seekg(0); + mtlxFile.read(&xmlData[0], fileSize); - rpr::Status status; - m_surfaceNode.reset(m_ctx->rprContext->CreateMaterialXNode(xmlData.get(), basePath.c_str(), 0, nullptr, nullptr, &status)); + m_surfaceNode.reset(m_ctx->rprContext->CreateMaterialXNode(xmlData.get(), basePath.c_str(), 0, nullptr, nullptr, &status)); + } if (!m_surfaceNode) { RPR_ERROR_CHECK(status, "Failed to create materialX node", m_ctx->rprContext); @@ -340,6 +367,16 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { fileInput.uiName = "File"; nodeInfo.inputs.push_back(fileInput); + RprUsd_RprNodeInput stringInput(RprUsdMaterialNodeElement::kString); + stringInput.name = RprUsdRprMaterialXNodeTokens->string.GetText(); + stringInput.uiName = ""; // hide from UI + nodeInfo.inputs.push_back(stringInput); + + RprUsd_RprNodeInput basePathInput(RprUsdMaterialNodeElement::kString); + basePathInput.name = RprUsdRprMaterialXNodeTokens->basePath.GetText(); + basePathInput.uiName = ""; // hide from UI + nodeInfo.inputs.push_back(basePathInput); + RprUsd_RprNodeInput stPrimvarNameInput(RprUsdMaterialNodeElement::kString); stPrimvarNameInput.name = RprUsdRprMaterialXNodeTokens->stPrimvarName.GetText(); stPrimvarNameInput.uiName = "UV Primvar Name"; @@ -370,6 +407,8 @@ class RprUsd_RprMaterialXNode : public RprUsd_MaterialNode { private: RprUsd_MaterialBuilderContext* m_ctx; std::string m_mtlxFilepath; + std::string m_mtlxString; + std::string m_mtlxBasePath; std::string m_selectedRenderElements[RPRMtlxLoader::kOutputsTotal]; bool m_isDirty = true; diff --git a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.h b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.h index 90e1f61d5..21539e124 100644 --- a/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.h +++ b/pxr/imaging/rprUsd/materialNodes/rpr/materialXNode.h @@ -22,6 +22,8 @@ PXR_NAMESPACE_OPEN_SCOPE #define RPRUSD_RPR_MATERIALX_NODE_TOKENS \ (rpr_materialx_node) \ (file) \ + (string) \ + (basePath) \ (surfaceElement) \ (displacementElement) \ (stPrimvarName) diff --git a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp index 020911f28..5d7d09677 100644 --- a/pxr/imaging/rprUsd/materialNodes/usdNode.cpp +++ b/pxr/imaging/rprUsd/materialNodes/usdNode.cpp @@ -443,11 +443,17 @@ RprUsd_UsdPrimvarReader::RprUsd_UsdPrimvarReader( // it outputs actual UVs so that the user can manipulate it in any way. auto varnameNameIt = hydraParameters.find(UsdPrimvarReaderTokens->varname); - if (varnameNameIt != hydraParameters.end() && - varnameNameIt->second.IsHolding()) { - auto& varname = varnameNameIt->second.UncheckedGet(); - if (!varname.IsEmpty()) { - ctx->uvPrimvarName = varname; + if (varnameNameIt != hydraParameters.end()) { + if (varnameNameIt->second.IsHolding()) { + auto& varname = varnameNameIt->second.UncheckedGet(); + if (!varname.IsEmpty()) { + ctx->uvPrimvarName = varname.GetString(); + } + } else if (varnameNameIt->second.IsHolding()) { + auto& varname = varnameNameIt->second.UncheckedGet(); + if (!varname.empty()) { + ctx->uvPrimvarName = varname; + } } } diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 16813cef3..9f9d38e01 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -397,7 +397,7 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( m_isShadowCatcher = context.isShadowCatcher; m_isReflectionCatcher = context.isReflectionCatcher; - m_uvPrimvarName = std::move(context.uvPrimvarName); + m_uvPrimvarName = TfToken(context.uvPrimvarName); m_displacementScale = std::move(context.displacementScale); return m_volumeNode || m_surfaceNode || m_displacementNode; From d99c4fe0d47c4a5136bbd9ff50868a5bc7378a61 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 26 Nov 2020 19:58:50 +0100 Subject: [PATCH 10/32] buildmaster: version update to 2.0.5 --- 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 477d1ccf2..e9e0f0dd9 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 "4") +set(HD_RPR_PATCH_VERSION "5") From 32cbd91adb02f9b3fe2b3d4649f818a4231f9b9f Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 27 Nov 2020 18:21:02 -0500 Subject: [PATCH 11/32] Expose contour rendering mode (#396) PURPOSE Support contour rendering with Northstar. EFFECT OF CHANGE Added new render mode - Contour, and its render settings (linewidth of a particular edge detection feature and others). Added new geometry setting - Ignore Contour, that controls whether contour should be extracted for a mesh or not. --- pxr/imaging/plugin/hdRpr/mesh.cpp | 12 + pxr/imaging/plugin/hdRpr/mesh.h | 1 + pxr/imaging/plugin/hdRpr/primvarUtil.cpp | 3 + pxr/imaging/plugin/hdRpr/primvarUtil.h | 1 + .../plugin/hdRpr/python/commonSettings.py | 4 +- .../python/generateGeometrySettingFiles.py | 12 +- .../python/generateRenderSettingFiles.py | 228 ++++++++++---- .../plugin/hdRpr/python/houdiniDsGenerator.py | 285 ++++++++++-------- pxr/imaging/plugin/hdRpr/rprApi.cpp | 246 ++++++++++++--- pxr/imaging/plugin/hdRpr/rprApi.h | 1 + 10 files changed, 565 insertions(+), 228 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index 780dfa816..8504b6ed8 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -360,6 +360,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } + bool isIgnoreContourDirty = false; bool isVisibilityMaskDirty = false; if (*dirtyBits & HdChangeTracker::DirtyPrimvar) { HdRprGeometrySettings geomSettings = {}; @@ -376,6 +377,11 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, m_visibilityMask = geomSettings.visibilityMask; isVisibilityMaskDirty = true; } + + if (m_ignoreContour != geomSettings.ignoreContour) { + m_ignoreContour = geomSettings.ignoreContour; + isIgnoreContourDirty = true; + } } m_smoothNormals = m_displayStyle.flatShadingEnabled; @@ -696,6 +702,12 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } + if (newMesh || isIgnoreContourDirty) { + for (auto& rprMesh : m_rprMeshes) { + rprApi->SetMeshIgnoreContour(rprMesh, m_ignoreContour); + } + } + if (updateTransform) { for (auto& rprMesh : m_rprMeshes) { rprApi->SetTransform(rprMesh, m_transformSamples.count, m_transformSamples.times.data(), m_transformSamples.values.data()); diff --git a/pxr/imaging/plugin/hdRpr/mesh.h b/pxr/imaging/plugin/hdRpr/mesh.h index 212216766..37a7a602b 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.h +++ b/pxr/imaging/plugin/hdRpr/mesh.h @@ -97,6 +97,7 @@ class HdRprMesh final : public HdRprBaseRprim { int m_refineLevel = 0; uint32_t m_visibilityMask; + bool m_ignoreContour; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp index c08d1c393..c1cd3bb0f 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp @@ -18,6 +18,7 @@ PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PRIVATE_TOKENS(HdRprGeometryPrimvarTokens, ((subdivisionLevel, "rpr:subdivisionLevel")) + ((ignoreContour, "rpr:ignoreContour")) ((visibilityPrimary, "rpr:visibilityPrimary")) ((visibilityShadow, "rpr:visibilityShadow")) ((visibilityReflection, "rpr:visibilityReflection")) @@ -54,6 +55,8 @@ void HdRprParseGeometrySettings( if (HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->subdivisionLevel, sceneDelegate, id, &subdivisionLevel)) { geomSettings->subdivisionLevel = std::max(0, std::min(subdivisionLevel, 7)); } + } else if (desc.name == HdRprGeometryPrimvarTokens->ignoreContour) { + HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->ignoreContour, sceneDelegate, id, &geomSettings->ignoreContour); } 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 a92d41ef0..5f9aa2c83 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.h +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.h @@ -38,6 +38,7 @@ bool HdRprIsValidPrimvarSize( struct HdRprGeometrySettings { uint32_t visibilityMask = 0; int subdivisionLevel = 0; + bool ignoreContour = false; }; void HdRprParseGeometrySettings( diff --git a/pxr/imaging/plugin/hdRpr/python/commonSettings.py b/pxr/imaging/plugin/hdRpr/python/commonSettings.py index c0cd479f8..7b2d614ff 100644 --- a/pxr/imaging/plugin/hdRpr/python/commonSettings.py +++ b/pxr/imaging/plugin/hdRpr/python/commonSettings.py @@ -75,10 +75,10 @@ ] class SettingValue(object): - def __init__(self, key, ui_name=None, disabled_platform=None): + def __init__(self, key, ui_name=None, enable_py_condition=None): self._key = key self._ui_name = ui_name - self.disabled_platform = disabled_platform + self.enable_py_condition = enable_py_condition def __eq__(self, obj): return self._key == obj diff --git a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py index 743ec86fa..344b6526c 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py @@ -24,8 +24,18 @@ 'defaultValue': 0, 'minValue': 0, 'maxValue': 7 + }, + { + 'name': 'primvars:rpr:ignoreContour', + 'ui_name': 'Ignore Contour', + 'defaultValue': False, + 'help': 'Whether to extract contour for a mesh or not' + }, + { + 'folder': 'Visibility Settings', + 'settings': visibility_flag_settings } - ] + visibility_flag_settings + ] } ] diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 48d9bc817..0997c8a93 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -52,7 +52,8 @@ def hidewhen_not_northstar(render_setting_categories): def hidewhen_not_tahoe(render_setting_categories): return hidewhen_render_quality('!=', 'Full', render_setting_categories) -HYBRID_DISABLED_PLATFORM = 'Darwin' +HYBRID_IS_AVAILABLE_PY_CONDITION = 'platform.system() != "Darwin"' +NORTHSTAR_ENABLED_PY_CONDITION = 'hou.pwd().parm("renderQuality").evalAsString() == "Northstar"' render_setting_categories = [ { @@ -64,9 +65,9 @@ def hidewhen_not_tahoe(render_setting_categories): 'help': 'Render restart might be required', 'defaultValue': 'Northstar', 'values': [ - SettingValue('Low', disabled_platform=HYBRID_DISABLED_PLATFORM), - SettingValue('Medium', disabled_platform=HYBRID_DISABLED_PLATFORM), - SettingValue('High', disabled_platform=HYBRID_DISABLED_PLATFORM), + SettingValue('Low', enable_py_condition=HYBRID_IS_AVAILABLE_PY_CONDITION), + SettingValue('Medium', enable_py_condition=HYBRID_IS_AVAILABLE_PY_CONDITION), + SettingValue('High', enable_py_condition=HYBRID_IS_AVAILABLE_PY_CONDITION), SettingValue('Full', 'Full (Legacy)'), SettingValue('Northstar', 'Full') ] @@ -89,7 +90,8 @@ def hidewhen_not_tahoe(render_setting_categories): SettingValue('Normal'), SettingValue('Texcoord'), SettingValue('Ambient Occlusion'), - SettingValue('Diffuse') + SettingValue('Diffuse'), + SettingValue('Contour', enable_py_condition=NORTHSTAR_ENABLED_PY_CONDITION), ] }, { @@ -101,6 +103,111 @@ def hidewhen_not_tahoe(render_setting_categories): 'houdini': { 'hidewhen': 'renderMode != "AmbientOcclusion"' } + }, + { + 'folder': 'Contour Settings', + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + }, + 'settings': [ + { + 'name': 'contourAntialiasing', + 'ui_name': 'Antialiasing', + 'defaultValue': 1.0, + 'minValue': 0.0, + 'maxValue': 1.0, + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + } + }, + { + 'name': 'contourUseNormal', + 'ui_name': 'Use Normal', + 'defaultValue': True, + 'help': 'Whether to use geometry normals for edge detection or not', + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + } + }, + { + 'name': 'contourLinewidthNormal', + 'ui_name': 'Linewidth Normal', + 'defaultValue': 1.0, + 'minValue': 0.0, + 'maxValue': 100.0, + 'help': 'Linewidth of edges detected via normals', + 'houdini': { + 'hidewhen': ['renderMode != "Contour"', 'contourUseNormal == 0'] + } + }, + { + 'name': 'contourNormalThreshold', + 'ui_name': 'Normal Threshold', + 'defaultValue': 45.0, + 'minValue': 0.0, + 'maxValue': 180.0, + 'houdini': { + 'hidewhen': ['renderMode != "Contour"', 'contourUseNormal == 0'] + } + }, + { + 'name': 'contourUsePrimId', + 'ui_name': 'Use Primitive Id', + 'defaultValue': True, + 'help': 'Whether to use primitive Id for edge detection or not', + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + } + }, + { + 'name': 'contourLinewidthPrimId', + 'ui_name': 'Linewidth Primitive Id', + 'defaultValue': 1.0, + 'minValue': 0.0, + 'maxValue': 100.0, + 'help': 'Linewidth of edges detected via primitive Id', + 'houdini': { + 'hidewhen': ['renderMode != "Contour"', 'contourUsePrimId == 0'] + } + }, + { + 'name': 'contourUseMaterialId', + 'ui_name': 'Use Material Id', + 'defaultValue': True, + 'help': 'Whether to use material Id for edge detection or not', + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + } + }, + { + 'name': 'contourLinewidthMaterialId', + 'ui_name': 'Linewidth Material Id', + 'defaultValue': 1.0, + 'minValue': 0.0, + 'maxValue': 100.0, + 'help': 'Linewidth of edges detected via material Id', + 'houdini': { + 'hidewhen': ['renderMode != "Contour"', 'contourUseMaterialId == 0'] + } + }, + { + 'name': 'contourDebug', + 'ui_name': 'Debug', + 'defaultValue': False, + 'help': 'Whether to show colored outlines according to used features or not.\\n' + 'Colors legend:\\n' + ' * red - primitive Id\\n' + ' * green - material Id\\n' + ' * blue - normal\\n' + ' * yellow - primitive Id + material Id\\n' + ' * magenta - primitive Id + normal\\n' + ' * cyan - material Id + normal\\n' + ' * black - all', + 'houdini': { + 'hidewhen': 'renderMode != "Contour"' + } + } + ] } ], 'houdini': { @@ -605,29 +712,29 @@ class HdRprConfig {{ dirty_flags_offset = 1 - rs_public_token_definitions = '' - rs_tokens_declaration = '#define HDRPR_RENDER_SETTINGS_TOKENS \\\n' - rs_category_dirty_flags = '' - rs_get_set_method_declarations = '' - rs_variables_declaration = '' - rs_mapped_values_enum = '' - rs_range_definitions = '' - rs_list_initialization = '' - rs_sync = '' - rs_get_set_method_definitions = '' - rs_set_default_values = '' - rs_validate_values = '' + rs_public_token_definitions = [] + rs_tokens_declaration = ['#define HDRPR_RENDER_SETTINGS_TOKENS \\\n'] + rs_category_dirty_flags = [] + rs_get_set_method_declarations = [] + rs_variables_declaration = [] + rs_mapped_values_enum = [] + rs_range_definitions = [] + rs_list_initialization = [] + rs_sync = [] + rs_get_set_method_definitions = [] + rs_set_default_values = [] + rs_validate_values = [] for category in render_setting_categories: disabled_category = False category_name = category['name'] dirty_flag = 'Dirty{}'.format(category_name) - rs_category_dirty_flags += ' {} = 1 << {},\n'.format(dirty_flag, dirty_flags_offset) + rs_category_dirty_flags.append(' {} = 1 << {},\n'.format(dirty_flag, dirty_flags_offset)) dirty_flags_offset += 1 - for setting in category['settings']: + def process_setting(setting): name = setting['name'] - rs_tokens_declaration += ' ({}) \\\n'.format(name) + rs_tokens_declaration.append(' ({}) \\\n'.format(name)) name_title = camel_case_capitalize(name) @@ -645,62 +752,62 @@ class HdRprConfig {{ value_tokens_list_name = '__{}Tokens'.format(name_title) value_tokens_name = 'HdRpr{}Tokens'.format(name_title) - rs_mapped_values_enum += '#define ' + value_tokens_list_name + rs_mapped_values_enum.append('#define ' + value_tokens_list_name) for value in setting['values']: - rs_mapped_values_enum += ' ({})'.format(value.get_key()) - rs_mapped_values_enum += '\n' + rs_mapped_values_enum.append(' ({})'.format(value.get_key())) + rs_mapped_values_enum.append('\n') - rs_mapped_values_enum += 'TF_DECLARE_PUBLIC_TOKENS({}, {});\n\n'.format(value_tokens_name, value_tokens_list_name) - rs_public_token_definitions += 'TF_DEFINE_PUBLIC_TOKENS({}, {});\n'.format(value_tokens_name, value_tokens_list_name) + rs_mapped_values_enum.append('TF_DECLARE_PUBLIC_TOKENS({}, {});\n\n'.format(value_tokens_name, value_tokens_list_name)) + rs_public_token_definitions.append('TF_DEFINE_PUBLIC_TOKENS({}, {});\n'.format(value_tokens_name, value_tokens_list_name)) type_str = 'TfToken' c_type_str = type_str default_value = next(value for value in setting['values'] if value == default_value) - rs_get_set_method_declarations += ' void Set{}({} {});\n'.format(name_title, c_type_str, name) - rs_get_set_method_declarations += ' {} const& Get{}() const {{ return m_prefData.{}; }}\n\n'.format(type_str, name_title, name) + rs_get_set_method_declarations.append(' void Set{}({} {});\n'.format(name_title, c_type_str, name)) + rs_get_set_method_declarations.append(' {} const& Get{}() const {{ return m_prefData.{}; }}\n\n'.format(type_str, name_title, name)) - rs_variables_declaration += ' {} {};\n'.format(type_str, name) + rs_variables_declaration.append(' {} {};\n'.format(type_str, name)) if isinstance(default_value, bool): - rs_sync += ' Set{name_title}(getBoolSetting(HdRprRenderSettingsTokens->{name}, k{name_title}Default));\n'.format(name_title=name_title, name=name) + rs_sync.append(' Set{name_title}(getBoolSetting(HdRprRenderSettingsTokens->{name}, k{name_title}Default));\n'.format(name_title=name_title, name=name)) else: - rs_sync += ' Set{name_title}(renderDelegate->GetRenderSetting(HdRprRenderSettingsTokens->{name}, k{name_title}Default));\n'.format(name_title=name_title, name=name) + rs_sync.append(' Set{name_title}(renderDelegate->GetRenderSetting(HdRprRenderSettingsTokens->{name}, k{name_title}Default));\n'.format(name_title=name_title, name=name)) if 'values' in setting: - rs_range_definitions += '#define k{name_title}Default {value_tokens_name}->{value}'.format(name_title=name_title, value_tokens_name=value_tokens_name, value=default_value.get_key()) + rs_range_definitions.append('#define k{name_title}Default {value_tokens_name}->{value}'.format(name_title=name_title, value_tokens_name=value_tokens_name, value=default_value.get_key())) else: value_str = str(default_value) if isinstance(default_value, bool): value_str = value_str.lower() - rs_range_definitions += 'const {type} k{name_title}Default = {type}({value});\n'.format(type=type_str, name_title=name_title, value=value_str) + rs_range_definitions.append('const {type} k{name_title}Default = {type}({value});\n'.format(type=type_str, name_title=name_title, value=value_str)) set_validation = '' if 'minValue' in setting or 'maxValue' in setting: - rs_validate_values += ' ' + rs_validate_values.append(' ') if 'minValue' in setting: - rs_range_definitions += 'const {type} k{name_title}Min = {type}({value});\n'.format(type=type_str, name_title=name_title, value=setting['minValue']) + rs_range_definitions.append('const {type} k{name_title}Min = {type}({value});\n'.format(type=type_str, name_title=name_title, value=setting['minValue'])) set_validation += ' if ({name} < k{name_title}Min) {{ return; }}\n'.format(name=name, name_title=name_title) - rs_validate_values += '&& {name} < k{name_title}Min'.format(name=name, name_title=name_title) + rs_validate_values.append('&& {name} < k{name_title}Min'.format(name=name, name_title=name_title)) if 'maxValue' in setting: - rs_range_definitions += 'const {type} k{name_title}Max = {type}({value});\n'.format(type=type_str, name_title=name_title, value=setting['maxValue']) + rs_range_definitions.append('const {type} k{name_title}Max = {type}({value});\n'.format(type=type_str, name_title=name_title, value=setting['maxValue'])) set_validation += ' if ({name} > k{name_title}Max) {{ return; }}\n'.format(name=name, name_title=name_title) - rs_validate_values += '&& {name} > k{name_title}Max'.format(name=name, name_title=name_title) + rs_validate_values.append('&& {name} > k{name_title}Max'.format(name=name, name_title=name_title)) if 'minValue' in setting or 'maxValue' in setting: - rs_validate_values += '\n' - rs_range_definitions += '\n' + rs_validate_values.append('\n') + rs_range_definitions.append('\n') if 'values' in setting: value_range = value_tokens_name + '->allTokens' set_validation += ' if (std::find({range}.begin(), {range}.end(), {name}) == {range}.end()) return;\n'.format(range=value_range, name=name) if 'ui_name' in setting: - rs_list_initialization += ' settingDescs.push_back({{"{}", HdRprRenderSettingsTokens->{}, VtValue(k{}Default)}});\n'.format(setting['ui_name'], name, name_title) + rs_list_initialization.append(' settingDescs.push_back({{"{}", HdRprRenderSettingsTokens->{}, VtValue(k{}Default)}});\n'.format(setting['ui_name'], name, name_title)) if disabled_category: - rs_get_set_method_definitions += 'void HdRprConfig::Set{name_title}({c_type} {name}) {{ /* Platform no-op */ }}'.format(name_title=name_title, c_type=c_type_str, name=name) + rs_get_set_method_definitions.append('void HdRprConfig::Set{name_title}({c_type} {name}) {{ /* Platform no-op */ }}'.format(name_title=name_title, c_type=c_type_str, name=name)) else: - rs_get_set_method_definitions += ( + rs_get_set_method_definitions.append(( ''' void HdRprConfig::Set{name_title}({c_type} {name}) {{ {set_validation} @@ -709,31 +816,38 @@ class HdRprConfig {{ m_dirtyFlags |= {dirty_flag}; }} }} -''').format(name_title=name_title, c_type=c_type_str, name=name, dirty_flag=dirty_flag, set_validation=set_validation) +''').format(name_title=name_title, c_type=c_type_str, name=name, dirty_flag=dirty_flag, set_validation=set_validation)) + + rs_set_default_values.append(' {name} = k{name_title}Default;\n'.format(name=name, name_title=name_title)) - rs_set_default_values += ' {name} = k{name_title}Default;\n'.format(name=name, name_title=name_title) + for setting in category['settings']: + if 'folder' in setting: + for sub_setting in setting['settings']: + process_setting(sub_setting) + else: + process_setting(setting) - rs_tokens_declaration += '\nTF_DECLARE_PUBLIC_TOKENS(HdRprRenderSettingsTokens, HDRPR_RENDER_SETTINGS_TOKENS);\n' + rs_tokens_declaration.append('\nTF_DECLARE_PUBLIC_TOKENS(HdRprRenderSettingsTokens, HDRPR_RENDER_SETTINGS_TOKENS);\n') header_dst_path = os.path.join(install_path, 'config.h') header_file = open(header_dst_path, 'w') header_file.write(header_template.format( - rs_tokens_declaration=rs_tokens_declaration, - rs_category_dirty_flags=rs_category_dirty_flags, - rs_get_set_method_declarations=rs_get_set_method_declarations, - rs_variables_declaration=rs_variables_declaration, - rs_mapped_values_enum=rs_mapped_values_enum)) + rs_tokens_declaration=''.join(rs_tokens_declaration), + rs_category_dirty_flags=''.join(rs_category_dirty_flags), + rs_get_set_method_declarations=''.join(rs_get_set_method_declarations), + rs_variables_declaration=''.join(rs_variables_declaration), + rs_mapped_values_enum=''.join(rs_mapped_values_enum))) cpp_dst_path = os.path.join(install_path, 'config.cpp') cpp_file = open(cpp_dst_path, 'w') cpp_file.write(cpp_template.format( - rs_public_token_definitions=rs_public_token_definitions, - rs_range_definitions=rs_range_definitions, - rs_list_initialization=rs_list_initialization, - rs_sync=rs_sync, - rs_get_set_method_definitions=rs_get_set_method_definitions, - rs_set_default_values=rs_set_default_values, - rs_validate_values=rs_validate_values)) + rs_public_token_definitions=''.join(rs_public_token_definitions), + rs_range_definitions=''.join(rs_range_definitions), + rs_list_initialization=''.join(rs_list_initialization), + rs_sync=''.join(rs_sync), + rs_get_set_method_definitions=''.join(rs_get_set_method_definitions), + rs_set_default_values=''.join(rs_set_default_values), + rs_validate_values=''.join(rs_validate_values))) if generate_ds_files: generate_houdini_ds(install_path, 'Global', render_setting_categories) diff --git a/pxr/imaging/plugin/hdRpr/python/houdiniDsGenerator.py b/pxr/imaging/plugin/hdRpr/python/houdiniDsGenerator.py index 76236d15c..d55edb5ad 100644 --- a/pxr/imaging/plugin/hdRpr/python/houdiniDsGenerator.py +++ b/pxr/imaging/plugin/hdRpr/python/houdiniDsGenerator.py @@ -44,143 +44,170 @@ ''' ) -def generate_houdini_ds(install_path, ds_name, settings): - import hou +def _get_valid_houdini_param_name(name): + if all(c.isalnum() or c == '_' for c in name): + return name + else: + import hou + return hou.encode(name) + +def _get_houdini_hidewhen_string(conditions, settings): + houdini_hidewhen_conditions = [] + for condition in conditions: + if condition and callable(condition): + condition = condition(settings) + if condition: + if isinstance(condition, str): + houdini_hidewhen_conditions.append(condition) + elif isinstance(condition, list): + houdini_hidewhen_conditions.extend(condition); + + houdini_hidewhen = '' + if houdini_hidewhen_conditions: + houdini_hidewhen += 'hidewhen "' + for condition in houdini_hidewhen_conditions: + houdini_hidewhen += '{{ {} }} '.format(condition) + houdini_hidewhen += '"' + return houdini_hidewhen + +def _generate_ds_setting(setting, spare_category, global_hidewhen, settings): + if not 'ui_name' in setting: + return '' + + houdini_settings = setting.get('houdini', {}) + houdini_hidewhen = _get_houdini_hidewhen_string((houdini_settings.get('hidewhen'), global_hidewhen), settings) + + def CreateHoudiniParam(name, label, htype, default, values=[], tags=[], disablewhen_conditions=[], size=None, valid_range=None, help_msg=None): + param = 'parm {\n' + param += ' name "{}"\n'.format(_get_valid_houdini_param_name(name)) + param += ' label "{}"\n'.format(label) + param += ' type {}\n'.format(htype) + if size: param += ' size {}\n'.format(size) + param += ' default {{ {} }}\n'.format(default) + for tag in tags: + param += ' parmtag {{ {} }}\n'.format(tag) + if values: + param += ' menu {\n' + param += ' ' + values + '\n' + param += ' }\n' + if houdini_hidewhen: + param += ' {}\n'.format(houdini_hidewhen) + if disablewhen_conditions: + param += ' disablewhen "' + for condition in disablewhen_conditions: + param += '{{ {} }} '.format(condition) + param += '"\n' + if valid_range: + param += ' range {{ {}! {} }}\n'.format(valid_range[0], valid_range[1]) + if help_msg: + param += ' help "{}"\n'.format(help_msg) + param += '}\n' + + return param + + name = setting['name'] + + control_param_name = _get_valid_houdini_param_name(name + '_control') + + render_param_values = None + default_value = setting['defaultValue'] + c_type_str = type(default_value).__name__ + controlled_type = c_type_str + if c_type_str == 'str': + c_type_str = 'string' + controlled_type = 'string' + render_param_type = c_type_str + render_param_default = default_value + if isinstance(default_value, bool): + render_param_type = 'toggle' + render_param_default = 1 if default_value else 0 + elif 'values' in setting: + default_value = next(value for value in setting['values'] if value == default_value) + render_param_default = '"{}"'.format(default_value.get_key()) + render_param_type = 'string' + c_type_str = 'token' + + is_values_constant = True + for value in setting['values']: + if value.enable_py_condition: + is_values_constant = False + break + + render_param_values = '' + if is_values_constant: + for value in setting['values']: + render_param_values += '"{}" "{}"\n'.format(value.get_key(), value.get_ui_name()) + else: + render_param_values += '[ "import platform" ]\n' + render_param_values += '[ "menu_values = []" ]\n' + for value in setting['values']: + expression = 'menu_values.extend([\\"{}\\", \\"{}\\"])'.format(value.get_key(), value.get_ui_name()) + + if value.enable_py_condition: + enable_condition = value.enable_py_condition.replace('"', '\\"') + expression = 'if {}: {}'.format(enable_condition, expression) + + render_param_values += '[ "{}" ]\n'.format(expression) + render_param_values += '[ "return menu_values" ]\n'.format(expression) + render_param_values += 'language python\n' + + if 'type' in houdini_settings: + render_param_type = houdini_settings['type'] + + render_param_range = None + if 'minValue' in setting and 'maxValue' in setting and not 'values' in setting: + render_param_range = (setting['minValue'], setting['maxValue']) + + houdini_param_label = setting['ui_name'] + + houdini_params = control_param_template.format( + name=control_param_name, + label=houdini_param_label, + controlled_type=controlled_type, + hidewhen=houdini_hidewhen) + houdini_params += CreateHoudiniParam(name, houdini_param_label, render_param_type, render_param_default, + values=render_param_values, + tags=[ + '"spare_category" "{}"'.format(spare_category), + '"uiscope" "viewport"', + '"usdvaluetype" "{}"'.format(c_type_str) + ] + houdini_settings.get('custom_tags', []), + disablewhen_conditions=[ + control_param_name + ' == block', + control_param_name + ' == none', + ], + size=1, + valid_range=render_param_range, + help_msg=setting.get('help', None)) + + return houdini_params +def generate_houdini_ds(install_path, ds_name, settings): houdini_params = '' for category in settings: - disabled_category = False - category_name = category['name'] + category_hidewhen = None + if 'houdini' in category: + category_hidewhen = category['houdini'].get('hidewhen') for setting in category['settings']: - if not 'ui_name' in setting: - continue - - houdini_hidewhen_conditions = [] - def add_hidewhen_condition(condition): - if condition and callable(condition): - condition = condition(settings) - if condition: - if isinstance(condition, str): - houdini_hidewhen_conditions.append(condition) - elif isinstance(condition, list): - houdini_hidewhen_conditions.extend(condition); - - if 'houdini' in category: - add_hidewhen_condition(category['houdini'].get('hidewhen')) - - houdini_settings = setting.get('houdini', {}) - houdini_param_label = setting['ui_name'] - add_hidewhen_condition(houdini_settings.get('hidewhen')) - - houdini_hidewhen = '' - if houdini_hidewhen_conditions: - houdini_hidewhen += 'hidewhen "' - for condition in houdini_hidewhen_conditions: - houdini_hidewhen += '{{ {} }} '.format(condition) - houdini_hidewhen += '"' - - def CreateHoudiniParam(name, label, htype, default, values=[], tags=[], disablewhen_conditions=[], size=None, valid_range=None, help_msg=None): - param = 'parm {\n' - param += ' name "{}"\n'.format(hou.encode(name)) - param += ' label "{}"\n'.format(label) - param += ' type {}\n'.format(htype) - if size: param += ' size {}\n'.format(size) - param += ' default {{ {} }}\n'.format(default) - for tag in tags: - param += ' parmtag {{ {} }}\n'.format(tag) - if values: - param += ' menu {\n' - param += ' ' + values + '\n' - param += ' }\n' - if disabled_category: - param += ' invisible\n' + if 'folder' in setting: + houdini_params += 'groupcollapsible {\n' + houdini_params += ' name "{}"\n'.format(setting['folder'].replace(' ', '')) + houdini_params += ' label "{}"\n'.format(setting['folder']) + + houdini_settings = setting.get('houdini', {}) + houdini_hidewhen = _get_houdini_hidewhen_string((houdini_settings.get('hidewhen'), category_hidewhen), settings) if houdini_hidewhen: - param += ' {}\n'.format(houdini_hidewhen) - if disablewhen_conditions: - param += ' disablewhen "' - for condition in disablewhen_conditions: - param += '{{ {} }} '.format(condition) - param += '"\n' - if valid_range: - param += ' range {{ {}! {} }}\n'.format(valid_range[0], valid_range[1]) - if help_msg: - param += ' help "{}"\n'.format(help_msg) - param += '}\n' - - return param - - name = setting['name'] - - control_param_name = hou.encode(name + '_control') - - render_param_values = None - default_value = setting['defaultValue'] - c_type_str = type(default_value).__name__ - controlled_type = c_type_str - if c_type_str == 'str': - c_type_str = 'string' - controlled_type = 'string' - render_param_type = c_type_str - render_param_default = default_value - if isinstance(default_value, bool): - render_param_type = 'toggle' - render_param_default = 1 if default_value else 0 - elif 'values' in setting: - default_value = next(value for value in setting['values'] if value == default_value) - render_param_default = '"{}"'.format(default_value.get_key()) - render_param_type = 'string' - c_type_str = 'token' - - is_values_constant = True - for value in setting['values']: - if value.disabled_platform: - is_values_constant = False - break - - render_param_values = '' - if is_values_constant: - for value in setting['values']: - render_param_values += '"{}" "{}"\n'.format(value.get_key(), value.get_ui_name()) - else: - render_param_values += '[ "import platform" ]\n' - render_param_values += '[ "menu_values = []" ]\n' - for value in setting['values']: - expression = 'menu_values.extend([\\"{}\\", \\"{}\\"])'.format(value.get_key(), value.get_ui_name()) - if value.disabled_platform: - expression = 'if platform.system() != \\"{}\\": {}'.format(value.disabled_platform, expression) - render_param_values += '[ "{}" ]\n'.format(expression) - render_param_values += '[ "return menu_values" ]\n'.format(expression) - render_param_values += 'language python\n' - - if 'type' in houdini_settings: - render_param_type = houdini_settings['type'] - - render_param_range = None - if 'minValue' in setting and 'maxValue' in setting and not 'values' in setting: - render_param_range = (setting['minValue'], setting['maxValue']) - - houdini_params += control_param_template.format( - name=control_param_name, - label=houdini_param_label, - controlled_type=controlled_type, - hidewhen=houdini_hidewhen) - houdini_params += CreateHoudiniParam(name, houdini_param_label, render_param_type, render_param_default, - values=render_param_values, - tags=[ - '"spare_category" "{}"'.format(category_name), - '"uiscope" "viewport"', - '"usdvaluetype" "{}"'.format(c_type_str) - ] + houdini_settings.get('custom_tags', []), - disablewhen_conditions=[ - control_param_name + ' == block', - control_param_name + ' == none', - ], - size=1, - valid_range=render_param_range, - help_msg=setting.get('help', None)) + houdini_params += ' {}\n'.format(houdini_hidewhen) + + + for sub_setting in setting['settings']: + houdini_params += _generate_ds_setting(sub_setting, category_name, category_hidewhen, settings) + houdini_params += '}\n' + else: + houdini_params += _generate_ds_setting(setting, category_name, category_hidewhen, settings) if houdini_params: houdini_ds_dst_path = os.path.join(install_path, 'HdRprPlugin_{}.ds'.format(ds_name)) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 435b858b5..70dd3e73d 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -276,6 +276,13 @@ class HdRprApiImpl { try { InitRpr(); InitRif(); + + { + HdRprConfig* config; + auto configInstanceLock = HdRprConfig::GetInstance(&config); + UpdateSettings(*config, true); + } + InitScene(); InitCamera(); InitAovs(); @@ -560,6 +567,16 @@ class HdRprApiImpl { RPR_ERROR_CHECK(mesh->SetObjectID(id), "Failed to set mesh id"); } + void SetMeshIgnoreContour(rpr::Shape* mesh, bool ignoreContour) { + if (m_rprContextMetadata.pluginType == kPluginNorthstar) { + LockGuard rprLock(m_rprContext->GetMutex()); + // TODO: update C++ wrapper + RPR_ERROR_CHECK(rprShapeSetContourIgnore(rpr::GetRprObject(mesh), ignoreContour), "Failed to set shape contour ignore"); + + m_dirtyFlags |= ChangeTracker::DirtyScene; + } + } + rpr::Curve* CreateCurve(VtVec3fArray const& points, VtIntArray const& indices, VtFloatArray const& radiuses, VtVec2fArray const& uvs, VtIntArray const& segmentPerCurve) { if (!m_rprContext) { return nullptr; @@ -1469,6 +1486,68 @@ class HdRprApiImpl { return it->second; } + void UpdateRenderMode(HdRprConfig const& preferences, bool force) { + if (!preferences.IsDirty(HdRprConfig::DirtyRenderMode) && !force) { + return; + } + m_dirtyFlags |= ChangeTracker::DirtyScene; + + auto& renderMode = preferences.GetRenderMode(); + + if (m_rprContextMetadata.pluginType == kPluginNorthstar) { + if (renderMode == HdRprRenderModeTokens->Contour) { + if (!m_contourAovs) { + m_contourAovs = std::make_unique(); + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_DEBUG_ENABLED, preferences.GetContourDebug()), "Failed to set contour debug"); + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_ANTIALIASING, preferences.GetContourAntialiasing()), "Failed to set contour antialiasing"); + + if (preferences.GetContourUseNormal()) { + if (!m_contourAovs->normal) { + m_contourAovs->normal = CreateAov(HdAovTokens->normal); + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_NORMAL, preferences.GetContourLinewidthNormal()), "Failed to set contour normal linewidth"); + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_NORMAL_THRESHOLD, preferences.GetContourNormalThreshold()), "Failed to set contour normal threshold"); + } else { + m_contourAovs->normal = nullptr; + } + + if (preferences.GetContourUsePrimId()) { + if (!m_contourAovs->primId) { + m_contourAovs->primId = CreateAov(HdAovTokens->primId); + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_OBJECTID, preferences.GetContourLinewidthPrimId()), "Failed to set contour primId linewidth"); + } else { + m_contourAovs->primId = nullptr; + } + + if (preferences.GetContourUseMaterialId()) { + if (!m_contourAovs->materialId) { + m_contourAovs->materialId = CreateAov(HdRprAovTokens->materialId); + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_OBJECTID, preferences.GetContourLinewidthPrimId()), "Failed to set contour primId linewidth"); + } else { + m_contourAovs->materialId = nullptr; + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_GPUINTEGRATOR, "gpucontour"), "Failed to set gpuintegrator"); + return; + } else { + m_contourAovs = nullptr; + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_GPUINTEGRATOR, "gpusimple"), "Failed to set gpuintegrator"); + } + } + + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_RENDER_MODE, GetRprRenderMode(renderMode)), "Failed to set render mode"); + if (renderMode == HdRprRenderModeTokens->AmbientOcclusion) { + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_AO_RAY_LENGTH, preferences.GetAoRadius()), "Failed to set ambient occlusion radius"); + } + } + void UpdateTahoeSettings(HdRprConfig const& preferences, bool force) { if (preferences.IsDirty(HdRprConfig::DirtyAdaptiveSampling) || force) { m_varianceThreshold = preferences.GetVarianceThreshold(); @@ -1478,7 +1557,7 @@ class HdRprApiImpl { if (IsAdaptiveSamplingEnabled()) { if (!m_internalAovs.count(HdRprAovTokens->variance)) { - if (auto aov = CreateAov(HdRprAovTokens->variance, m_viewportSize[0], m_viewportSize[1])) { + if (auto aov = CreateAov(HdRprAovTokens->variance)) { m_internalAovs.emplace(HdRprAovTokens->variance, std::move(aov)); } else { TF_RUNTIME_ERROR("Failed to create variance AOV, adaptive sampling will not work"); @@ -1527,14 +1606,7 @@ class HdRprApiImpl { } } - if (preferences.IsDirty(HdRprConfig::DirtyRenderMode) || force) { - auto& renderMode = preferences.GetRenderMode(); - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_RENDER_MODE, GetRprRenderMode(renderMode)), "Failed to set render mode"); - if (renderMode == HdRprRenderModeTokens->AmbientOcclusion) { - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_AO_RAY_LENGTH, preferences.GetAoRadius()), "Failed to set ambient occlusion radius"); - } - m_dirtyFlags |= ChangeTracker::DirtyScene; - } + UpdateRenderMode(preferences, force); if (preferences.IsDirty(HdRprConfig::DirtySeed) || force) { m_isUniformSeed = preferences.GetUniformSeed(); @@ -1594,18 +1666,19 @@ class HdRprApiImpl { } } - if (preferences.IsDirty(HdRprConfig::DirtyAlpha) || force) { - m_isAlphaEnabled = preferences.GetEnableAlpha(); - - UpdateColorAlpha(); - } - if (m_rprContextMetadata.pluginType == kPluginTahoe || m_rprContextMetadata.pluginType == kPluginNorthstar) { UpdateTahoeSettings(preferences, force); } else if (m_rprContextMetadata.pluginType == kPluginHybrid) { UpdateHybridSettings(preferences, force); } + + if (preferences.IsDirty(HdRprConfig::DirtyAlpha) || force || + (m_rprContextMetadata.pluginType == kPluginNorthstar && preferences.IsDirty(HdRprConfig::DirtyRenderMode))) { + m_isAlphaEnabled = preferences.GetEnableAlpha(); + + UpdateColorAlpha(); + } } void UpdateCamera(RenderSetting const& aspectRatioPolicy, RenderSetting const& instantaneousShutter) { @@ -2037,6 +2110,17 @@ class HdRprApiImpl { } } + if (m_contourAovs) { + // In contour rendering mode we must render with RPR_CONTEXT_ITERATIONS=1 + if (isMaximizingContextIterations) { + isMaximizingContextIterations = false; + if (m_isRenderUpdateCallbackEnabled) { + m_isRenderUpdateCallbackEnabled = false; + RPR_ERROR_CHECK_THROW(m_rprContext->SetParameter(RPR_CONTEXT_RENDER_UPDATE_CALLBACK_FUNC, (void*)nullptr), "Failed to disable RUC func"); + } + } + } + // Though if adaptive sampling is enabled in a batch session we first render m_minSamples samples // and after that render 1 sample at a time because we want to query the current amount of // active pixels as often as possible @@ -2153,6 +2237,16 @@ class HdRprApiImpl { EnableRenderUpdateCallback(RenderUpdateCallback); + const bool progressivelyIncreaseSamplesPerIter = + // Progressively increasing RPR_CONTEXT_ITERATIONS makes sense only for Northstar + // because, first, it highly improves its performance (internal optimization) + // and, second, it supports render update callback that allows us too resolve intermediate results + m_rprContextMetadata.pluginType == kPluginNorthstar && + // in interactive mode we want to be able to abort ASAP + !m_isInteractive && + // in contour rendering mode we must render only with RPR_CONTEXT_ITERATIONS=1 + !m_contourAovs; + while (!IsConverged()) { // In interactive mode, always render at least one frame, otherwise // disturbing full-screen-flickering will be visible or @@ -2200,8 +2294,7 @@ class HdRprApiImpl { m_numSamples += m_numSamplesPerIter; - if (!m_isInteractive && m_rprContextMetadata.pluginType == kPluginNorthstar && m_numSamples > 1) { - // Progressively increase RPR_CONTEXT_ITERATIONS because it highly improves Northstar's performance + if (progressivelyIncreaseSamplesPerIter && m_numSamples > 1) { m_numSamplesPerIter *= 2; // Make sure we will not oversample the image @@ -2211,9 +2304,12 @@ class HdRprApiImpl { RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_ITERATIONS, m_numSamplesPerIter), "Failed to set context iterations"); } - // Enable resolves in the render update callback after RPR_CONTEXT_ITERATIONS gets high enough - if (m_numSamplesPerIter >= 32) { - m_resolveMode = kResolveInRenderUpdateCallback; + if (m_isRenderUpdateCallbackEnabled) { + // Enable resolves in the render update callback after RPR_CONTEXT_ITERATIONS gets high enough + // to get interactive updates even when RPR_CONTEXT_ITERATIONS huge + if (m_numSamplesPerIter >= 32) { + m_resolveMode = kResolveInRenderUpdateCallback; + } } } } @@ -2246,8 +2342,7 @@ class HdRprApiImpl { } void RenderFrame(HdRprRenderThread* renderThread) { - if (!m_rprContext || - m_aovRegistry.empty()) { + if (!m_rprContext) { return; } @@ -2266,6 +2361,10 @@ class HdRprApiImpl { return ExportRpr(); } + if (m_aovRegistry.empty()) { + return; + } + if (m_state == kStateRender) { try { if (m_delegate->IsBatch()) { @@ -2473,6 +2572,24 @@ Don't show this message again? } config["aovs"] = configAovs; + if (m_contourAovs) { + HdRprConfig* rprConfig; + auto configInstanceLock = HdRprConfig::GetInstance(&rprConfig); + + json contour; + contour["object.id"] = int(rprConfig->GetContourUsePrimId()); + contour["material.id"] = int(rprConfig->GetContourUseMaterialId()); + contour["normal"] = int(rprConfig->GetContourUseNormal()); + contour["threshold.normal"] = rprConfig->GetContourNormalThreshold(); + contour["linewidth.objid"] = rprConfig->GetContourLinewidthPrimId(); + contour["linewidth.matid"] = rprConfig->GetContourLinewidthMaterialId(); + contour["linewidth.normal"] = rprConfig->GetContourLinewidthNormal(); + contour["antialiasing"] = rprConfig->GetContourAntialiasing(); + contour["debug"] = rprConfig->GetContourDebug(); + + config["contour"] = contour; + } + configFile << config; } catch (json::exception& e) { fprintf(stderr, "Failed to fill config file: %s\n", configFilename.c_str()); @@ -2767,12 +2884,6 @@ Don't show this message again? } } - { - HdRprConfig* config; - auto configInstanceLock = HdRprConfig::GetInstance(&config); - UpdateSettings(*config, true); - } - m_imageCache.reset(new RprUsdImageCache(m_rprContext.get())); m_isAbortingEnabled.store(false); @@ -3049,6 +3160,26 @@ Don't show this message again? if (!colorAov) return; } + // Force disable alpha for some render modes when we render with Northstar + if (m_rprContextMetadata.pluginType == kPluginNorthstar) { + // Contour rendering should not have an alpha, + // it might cause missed contours (just for the user, not in actual data) + if (m_contourAovs) { + m_isAlphaEnabled = false; + } else { + auto currentRenderMode = RprUsdGetInfo(m_rprContext.get(), RPR_CONTEXT_RENDER_MODE); + + // XXX (RPRNEXT-343): opacity is always zero when such render modes are active: + if (currentRenderMode == RPR_RENDER_MODE_NORMAL || + currentRenderMode == RPR_RENDER_MODE_POSITION || + currentRenderMode == RPR_RENDER_MODE_TEXCOORD || + currentRenderMode == RPR_RENDER_MODE_WIREFRAME || + currentRenderMode == RPR_RENDER_MODE_MATERIAL_INDEX) { + m_isAlphaEnabled = false; + } + } + } + if (m_isAlphaEnabled) { auto opacityAov = GetAov(HdRprAovTokens->opacity, m_viewportSize[0], m_viewportSize[1], HdFormatFloat32Vec4); if (opacityAov) { @@ -3072,7 +3203,7 @@ Don't show this message again? return aov; } - std::shared_ptr CreateAov(TfToken const& aovName, int width = 0, int height = 0, HdFormat format = HdFormatFloat32Vec4) { + std::shared_ptr CreateAov(TfToken const& aovName, int width, int height, HdFormat format) { if (!m_rprContext || width < 0 || height < 0 || format == HdFormatInvalid || HdDataSizeOfFormat(format) == 0) { @@ -3095,6 +3226,9 @@ Don't show this message again? try { if (!aov) { + HdRprApiAov* newAov = nullptr; + std::function aovCustomDestructor; + if (aovName == HdAovTokens->color) { auto rawColorAov = GetAov(HdRprAovTokens->rawColor, width, height, HdFormatFloat32Vec4); if (!rawColorAov) { @@ -3102,12 +3236,12 @@ Don't show this message again? return nullptr; } - auto colorAov = std::make_shared(format, std::move(rawColorAov), m_rprContext.get(), m_rprContextMetadata); - UpdateColorAlpha(colorAov.get()); + auto colorAov = new HdRprApiColorAov(format, std::move(rawColorAov), m_rprContext.get(), m_rprContextMetadata); + UpdateColorAlpha(colorAov); - aov = colorAov; + newAov = colorAov; } else if (aovName == HdAovTokens->normal) { - aov = std::make_shared(width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiNormalAov(width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else if (aovName == HdAovTokens->depth) { auto worldCoordinateAov = GetAov(HdRprAovTokens->worldCoordinate, width, height, HdFormatFloat32Vec4); if (!worldCoordinateAov) { @@ -3115,24 +3249,36 @@ Don't show this message again? return nullptr; } - aov = std::make_shared(format, std::move(worldCoordinateAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiDepthAov(format, std::move(worldCoordinateAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else if (TfStringStartsWith(aovName.GetString(), "lpe")) { - auto aovPtr = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); - aov = std::shared_ptr(aovPtr, [this](HdRprApiAov* aov) { + newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + aovCustomDestructor = [this](HdRprApiAov* aov) { // Each LPE AOV reserves RPR's LPE AOV id (RPR_AOV_LPE_0, ...) // As soon as LPE AOV is released we want to return reserved id to the pool m_lpeAovPool.push_back(GetRprLpeAovName(aov->GetAovFb()->GetAovId())); + m_dirtyFlags |= ChangeTracker::DirtyAOVRegistry; delete aov; - }); + }; } else { if (!aovDesc.computed) { - aov = std::make_shared(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else { TF_CODING_ERROR("Failed to create %s AOV: unprocessed computed AOV", aovName.GetText()); - return nullptr; } } + if (!newAov) { + return nullptr; + } + + if (!aovCustomDestructor) { + aovCustomDestructor = [this](HdRprApiAov* aov) { + m_dirtyFlags |= ChangeTracker::DirtyAOVRegistry; + delete aov; + }; + } + + aov = std::shared_ptr(newAov, std::move(aovCustomDestructor)); m_aovRegistry[aovName] = aov; m_dirtyFlags |= ChangeTracker::DirtyAOVRegistry; } else { @@ -3145,6 +3291,17 @@ Don't show this message again? return aov; } + std::shared_ptr CreateAov(TfToken const& aovName) { + auto iter = m_aovRegistry.find(aovName); + if (iter != m_aovRegistry.end()) { + if (auto aov = iter->second.lock()) { + return aov; + } + } + + return CreateAov(aovName, m_viewportSize[0], m_viewportSize[1], HdFormatFloat32Vec4); + } + HdRprApiColorAov* GetColorAov() { std::shared_ptr retainedAov; auto colorAovIter = m_aovRegistry.find(HdAovTokens->color); @@ -3347,6 +3504,13 @@ Don't show this message again? HdRenderPassAovBindingVector m_aovBindings; std::vector m_lpeAovPool; + struct ContourRenderModeAovs { + std::shared_ptr normal; + std::shared_ptr primId; + std::shared_ptr materialId; + }; + std::unique_ptr m_contourAovs; + struct OutputRenderBuffer { HdRenderPassAovBinding const* aovBinding; TfToken aovName; @@ -3634,6 +3798,10 @@ void HdRprApi::SetMeshId(rpr::Shape* mesh, uint32_t id) { m_impl->SetMeshId(mesh, id); } +void HdRprApi::SetMeshIgnoreContour(rpr::Shape* mesh, bool ignoreContour) { + m_impl->SetMeshIgnoreContour(mesh, ignoreContour); +} + void HdRprApi::SetCurveMaterial(rpr::Curve* curve, RprUsdMaterial const* material) { m_impl->SetCurveMaterial(curve, material); } diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index e2023ad4c..605ca672e 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -121,6 +121,7 @@ class HdRprApi final { void SetMeshMaterial(rpr::Shape* mesh, RprUsdMaterial const* material, bool displacementEnabled); void SetMeshVisibility(rpr::Shape* mesh, uint32_t visibilityMask); void SetMeshId(rpr::Shape* mesh, uint32_t id); + void SetMeshIgnoreContour(rpr::Shape* mesh, bool ignoreContour); void Release(rpr::Shape* shape); rpr::Curve* CreateCurve(VtVec3fArray const& points, VtIntArray const& indices, VtFloatArray const& radiuses, VtVec2fArray const& uvs, VtIntArray const& segmentPerCurve); From 4a893217c4c3203d4e82fd7f16551a84d1386387 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Sat, 28 Nov 2020 00:28:53 +0100 Subject: [PATCH 12/32] buildmaster: version update to 2.0.6 --- 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 e9e0f0dd9..a68c8c9c5 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 "5") +set(HD_RPR_PATCH_VERSION "6") From f435b1005c755bf8301158e066e79a533a56d5da Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 27 Nov 2020 18:39:47 -0500 Subject: [PATCH 13/32] Add a way to override material IDs (#410) PURPOSE To allow the user to control the material ID that is rendered on the corresponding AOV. EFFECT OF CHANGE Added new LOP node (RPR Material Properties) for overriding material ID. --- pxr/imaging/plugin/rprHoudini/CMakeLists.txt | 3 + .../rprHoudini/LOP_RPRMaterialProperties.cpp | 105 ++++++++++++++++++ .../rprHoudini/LOP_RPRMaterialProperties.h | 37 ++++++ pxr/imaging/plugin/rprHoudini/plugin.cpp | 2 + pxr/imaging/rprUsd/CMakeLists.txt | 1 + pxr/imaging/rprUsd/materialRegistry.cpp | 34 +++++- pxr/imaging/rprUsd/tokens.cpp | 21 ++++ pxr/imaging/rprUsd/tokens.h | 33 ++++++ 8 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp create mode 100644 pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.h create mode 100644 pxr/imaging/rprUsd/tokens.cpp create mode 100644 pxr/imaging/rprUsd/tokens.h diff --git a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt index b4e1f4678..6d185deff 100644 --- a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt +++ b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt @@ -6,6 +6,8 @@ add_library(RPR_for_Houdini SHARED plugin.cpp VOP_RPRMaterial.h VOP_RPRMaterial.cpp + LOP_RPRMaterialProperties.h + LOP_RPRMaterialProperties.cpp LOP_RPRExportHelper.h LOP_RPRExportHelper.cpp) @@ -13,6 +15,7 @@ target_link_libraries(RPR_for_Houdini arch usd usdGeom + usdShade usdRender rprUsd Houdini) diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp new file mode 100644 index 000000000..b1ed1a037 --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp @@ -0,0 +1,105 @@ +/************************************************************************ +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 "LOP_RPRMaterialProperties.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +static PRM_Name g_materialPath("materialPath", "Material Path"); +static PRM_Name g_id("id", "ID"); + +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"), + PRM_Template() +}; + +void LOP_RPRMaterialProperties::Register(OP_OperatorTable* table) { + auto opOperator = new OP_Operator( + "rpr_LOP_RPRMaterialProperties", + "RPR Material Properties", + [](OP_Network *net, const char *name, OP_Operator *op) -> OP_Node* { + return new LOP_RPRMaterialProperties(net, name, op); + }, + g_templateList, + 0u, + (unsigned)1); + opOperator->setIconName("RPR"); + + table->addOperator(opOperator); +} + +LOP_RPRMaterialProperties::LOP_RPRMaterialProperties(OP_Network *net, const char *name, OP_Operator *op) + : LOP_Node(net, name, op) { + +} + +OP_ERROR LOP_RPRMaterialProperties::cookMyLop(OP_Context &context) { + if (cookModifyInput(context) >= UT_ERROR_FATAL) { + return error(); + } + + UT_String materialPath; + 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)); + + HUSD_AutoWriteLock writelock(editableDataHandle()); + HUSD_AutoLayerLock layerlock(writelock); + + UsdStageRefPtr stage = writelock.data()->stage(); + + UsdPrim materialPrim = stage->GetPrimAtPath(materialSdfPath); + if (!materialPrim) { + addError(LOP_MESSAGE, TfStringPrintf("Material with %s path does not exist", materialPath.c_str()).c_str()); + return error(); + } + + UsdShadeMaterial material(materialPrim); + if (!material) { + addError(LOP_MESSAGE, TfStringPrintf("Specified path does not point to a material: %s", materialPrim.GetPrimTypeInfo().GetTypeName().GetText()).c_str()); + return error(); + } + + UsdShadeShader surfaceSource = material.ComputeSurfaceSource(RprUsdTokens->rpr); + if (surfaceSource) { + surfaceSource.CreateInput(RprUsdTokens->id, SdfValueTypeNames->Int).Set(id); + } + + return error(); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.h b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.h new file mode 100644 index 000000000..211002d67 --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.h @@ -0,0 +1,37 @@ +/************************************************************************ +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. +************************************************************************/ + +#ifndef RPR_LOP_RPRMATERIALPROPERTIES_H +#define RPR_LOP_RPRMATERIALPROPERTIES_H + +#include "pxr/pxr.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// This node allows to set RPR specific properties on materials +class LOP_RPRMaterialProperties : public LOP_Node { +public: + LOP_RPRMaterialProperties(OP_Network *net, const char *name, OP_Operator *op); + ~LOP_RPRMaterialProperties() override = default; + + static void Register(OP_OperatorTable *table); + +protected: + OP_ERROR cookMyLop(OP_Context &context) override; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // RPR_LOP_RPRMATERIALPROPERTIES_H diff --git a/pxr/imaging/plugin/rprHoudini/plugin.cpp b/pxr/imaging/plugin/rprHoudini/plugin.cpp index 382ec71fb..ad8505c02 100644 --- a/pxr/imaging/plugin/rprHoudini/plugin.cpp +++ b/pxr/imaging/plugin/rprHoudini/plugin.cpp @@ -13,6 +13,7 @@ limitations under the License. #include "VOP_RPRMaterial.h" #include "LOP_RPRExportHelper.h" +#include "LOP_RPRMaterialProperties.h" #include "pxr/imaging/rprUsd/materialRegistry.h" #include @@ -34,4 +35,5 @@ void newVopOperator(OP_OperatorTable* io_table) { void newLopOperator(OP_OperatorTable *table) { PXR_NAMESPACE_USING_DIRECTIVE LOP_RPRExportHelper::Register(table); + LOP_RPRMaterialProperties::Register(table); } diff --git a/pxr/imaging/rprUsd/CMakeLists.txt b/pxr/imaging/rprUsd/CMakeLists.txt index a29e21570..38b9b5ec1 100644 --- a/pxr/imaging/rprUsd/CMakeLists.txt +++ b/pxr/imaging/rprUsd/CMakeLists.txt @@ -19,6 +19,7 @@ pxr_library(rprUsd PUBLIC_CLASSES util config + tokens contextHelpers coreImage debugCodes diff --git a/pxr/imaging/rprUsd/materialRegistry.cpp b/pxr/imaging/rprUsd/materialRegistry.cpp index 9f9d38e01..707a5cfc0 100644 --- a/pxr/imaging/rprUsd/materialRegistry.cpp +++ b/pxr/imaging/rprUsd/materialRegistry.cpp @@ -18,6 +18,8 @@ limitations under the License. #include "pxr/imaging/rprUsd/imageCache.h" #include "pxr/imaging/rprUsd/debugCodes.h" #include "pxr/imaging/rprUsd/material.h" +#include "pxr/imaging/rprUsd/tokens.h" +#include "pxr/imaging/rprUsd/error.h" #include "pxr/imaging/rprUsd/util.h" #include "pxr/base/tf/instantiateSingleton.h" #include "pxr/base/tf/staticTokens.h" @@ -377,7 +379,8 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( bool Finalize(RprUsd_MaterialBuilderContext& context, VtValue const& surfaceOutput, VtValue const& displacementOutput, - VtValue const& volumeOutput) { + VtValue const& volumeOutput, + int materialId) { auto getTerminalRprNode = [](VtValue const& terminalOutput) -> rpr::MaterialNode* { if (!terminalOutput.IsEmpty()) { @@ -400,6 +403,12 @@ 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"); + } + return m_volumeNode || m_surfaceNode || m_displacementNode; } }; @@ -509,7 +518,28 @@ RprUsdMaterial* RprUsdMaterialRegistry::CreateMaterial( auto surfaceOutput = getTerminalOutput(HdMaterialTerminalTokens->surface); auto displacementOutput = getTerminalOutput(HdMaterialTerminalTokens->displacement); - return out->Finalize(context, surfaceOutput, displacementOutput, volumeOutput) ? out.release() : nullptr; + int materialId = -1; + + auto surfaceTerminalIt = network.terminals.find(HdMaterialTerminalTokens->surface); + if (surfaceTerminalIt != network.terminals.end()) { + auto& surfaceNodePath = surfaceTerminalIt->second.upstreamNode; + + auto surfaceNodeIt = network.nodes.find(surfaceNodePath); + if (surfaceNodeIt != network.nodes.end()) { + auto& parameters = surfaceNodeIt->second.parameters; + + auto idIt = parameters.find(RprUsdTokens->id); + if (idIt != parameters.end()) { + auto& value = idIt->second; + + if (value.IsHolding()) { + materialId = value.UncheckedGet(); + } + } + } + } + + return out->Finalize(context, surfaceOutput, displacementOutput, volumeOutput, materialId) ? out.release() : nullptr; } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/rprUsd/tokens.cpp b/pxr/imaging/rprUsd/tokens.cpp new file mode 100644 index 000000000..c1a3d1464 --- /dev/null +++ b/pxr/imaging/rprUsd/tokens.cpp @@ -0,0 +1,21 @@ +/************************************************************************ +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 "pxr/imaging/rprUsd/tokens.h" + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_PUBLIC_TOKENS(RprUsdTokens, RPRUSD_TOKENS); + +PXR_NAMESPACE_CLOSE_SCOPE + diff --git a/pxr/imaging/rprUsd/tokens.h b/pxr/imaging/rprUsd/tokens.h new file mode 100644 index 000000000..053776dd6 --- /dev/null +++ b/pxr/imaging/rprUsd/tokens.h @@ -0,0 +1,33 @@ +/************************************************************************ +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. +************************************************************************/ + +#ifndef PXR_IMAGING_RPRUSD_TOKENS_H +#define PXR_IMAGING_RPRUSD_TOKENS_H + +#include "pxr/pxr.h" +#include "pxr/imaging/rprUsd/api.h" +#include "pxr/base/tf/staticTokens.h" + +PXR_NAMESPACE_OPEN_SCOPE + +#define RPRUSD_TOKENS \ + (rpr) \ + /* UsdShadeShader */ \ + ((id, "rpr:id")) + + +TF_DECLARE_PUBLIC_TOKENS(RprUsdTokens, RPRUSD_API, RPRUSD_TOKENS); + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif //PXR_IMAGING_RPRUSD_TOKENS_H From 03785b4643a55e0da36b2982bb4cb0ce7b3a682b Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 27 Nov 2020 18:40:58 -0500 Subject: [PATCH 14/32] Reduce the number of python processes when generating files on build (#412) PURPOSE To speed up the build time. EFFECT OF CHANGE Faster plugin building. --- pxr/imaging/plugin/hdRpr/CMakeLists.txt | 6 ++---- .../plugin/hdRpr/python/generateFiles.py | 19 ++++++++----------- .../python/generateGeometrySettingFiles.py | 11 +++-------- .../hdRpr/python/generateLightSettingFiles.py | 11 +++-------- .../python/generateRenderSettingFiles.py | 9 ++------- 5 files changed, 18 insertions(+), 38 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/CMakeLists.txt index 896aebd5c..c3f7d8f09 100644 --- a/pxr/imaging/plugin/hdRpr/CMakeLists.txt +++ b/pxr/imaging/plugin/hdRpr/CMakeLists.txt @@ -29,7 +29,7 @@ endif(HoudiniUSD_FOUND) set(GEN_SCRIPT_PYTHON ${PYTHON_EXECUTABLE}) set(GENERATION_SCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python) set(GEN_SCRIPT ${GENERATION_SCRIPTS_DIR}/generateFiles.py) -set(GEN_SCRIPT_ARGS \"${GENERATION_SCRIPTS_DIR}\" \"${CMAKE_CURRENT_BINARY_DIR}\") +set(GEN_SCRIPT_ARGS \"${CMAKE_CURRENT_BINARY_DIR}\") set(GENERATED_FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h ${CMAKE_CURRENT_BINARY_DIR}/config.cpp) @@ -39,7 +39,7 @@ set(GENERATION_DEPENDENT_FILES ${GEN_SCRIPT} ${GENERATION_SCRIPTS_DIR}/generateRenderSettingFiles.py ${GENERATION_SCRIPTS_DIR}/generateGeometrySettingFiles.py) if(HoudiniUSD_FOUND) - set(GEN_SCRIPT_ARGS --houdini_root \"${HOUDINI_ROOT}\" ${GEN_SCRIPT_ARGS}) + set(GEN_SCRIPT_ARGS --for_houdini ${GEN_SCRIPT_ARGS}) set(GENERATED_FILES ${GENERATED_FILES} ${CMAKE_CURRENT_BINARY_DIR}/HdRprPlugin_Light.ds ${CMAKE_CURRENT_BINARY_DIR}/HdRprPlugin_Global.ds @@ -62,8 +62,6 @@ if(HoudiniUSD_FOUND) }\")") endif() -set(GEN_SCRIPT_ARGS --python_exe "\"${GEN_SCRIPT_PYTHON}\"" ${GEN_SCRIPT_ARGS}) - add_custom_command( COMMAND ${GEN_SCRIPT_PYTHON} ${GEN_SCRIPT} ${GEN_SCRIPT_ARGS} DEPENDS ${GENERATION_DEPENDENT_FILES} diff --git a/pxr/imaging/plugin/hdRpr/python/generateFiles.py b/pxr/imaging/plugin/hdRpr/python/generateFiles.py index 3a36eee70..0a4f37279 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateFiles.py @@ -9,22 +9,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import subprocess import argparse import os +import generateGeometrySettingFiles +import generateRenderSettingFiles +import generateLightSettingFiles + if __name__ == "__main__": p = argparse.ArgumentParser() - p.add_argument('scripts_dir', help="Directory with scripts") p.add_argument("install", help="The install root for generated files.") - p.add_argument("--houdini_root", help="The install root for generated files.") - p.add_argument('--python_exe', help="Directory with scripts") + p.add_argument("--for_houdini", action="store_true") args = p.parse_args() - generate_ds_files = [] - if args.houdini_root: - generate_ds_files = ['--generate_ds_files'] - - subprocess.check_call([args.python_exe, os.path.join(args.scripts_dir, 'generateLightSettingFiles.py'), args.install] + generate_ds_files) - subprocess.check_call([args.python_exe, os.path.join(args.scripts_dir, 'generateGeometrySettingFiles.py'), args.install] + generate_ds_files) - subprocess.check_call([args.python_exe, os.path.join(args.scripts_dir, 'generateRenderSettingFiles.py'), args.install] + generate_ds_files) + generateGeometrySettingFiles.generate(args.install, args.for_houdini) + generateRenderSettingFiles.generate(args.install, args.for_houdini) + generateLightSettingFiles.generate(args.install, args.for_houdini) diff --git a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py index 344b6526c..88ece54a3 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py @@ -39,11 +39,6 @@ } ] -if __name__ == "__main__": - p = argparse.ArgumentParser() - p.add_argument("install", help="The install root for generated files.") - p.add_argument("--generate_ds_files", default=False, action='store_true') - args = p.parse_args() - - if args.generate_ds_files: - generate_houdini_ds(args.install, 'Geometry', geometry_settings) +def generate(install, generate_ds_files): + if generate_ds_files: + generate_houdini_ds(install, 'Geometry', geometry_settings) diff --git a/pxr/imaging/plugin/hdRpr/python/generateLightSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateLightSettingFiles.py index 50ddfcf7d..3174de482 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateLightSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateLightSettingFiles.py @@ -28,11 +28,6 @@ } ] -if __name__ == "__main__": - p = argparse.ArgumentParser() - p.add_argument("install", help="The install root for generated files.") - p.add_argument("--generate_ds_files", default=False, action='store_true') - args = p.parse_args() - - if args.generate_ds_files: - generate_houdini_ds(args.install, 'Light', light_settings) +def generate(install, generate_ds_files): + if generate_ds_files: + generate_houdini_ds(install, 'Light', light_settings) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 0997c8a93..70596cbea 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -853,10 +853,5 @@ def process_setting(setting): generate_houdini_ds(install_path, 'Global', render_setting_categories) -if __name__ == "__main__": - p = argparse.ArgumentParser() - p.add_argument("install", help="The install root for generated files.") - p.add_argument("--generate_ds_files", default=False, action='store_true') - args = p.parse_args() - - generate_render_setting_files(args.install, args.generate_ds_files) +def generate(install, generate_ds_files): + generate_render_setting_files(install, generate_ds_files) From eda3b4021407047be4765fb2eaf5acd50a1f6fb3 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Sat, 28 Nov 2020 00:43:59 +0100 Subject: [PATCH 15/32] buildmaster: version update to 2.0.7 --- 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 a68c8c9c5..00f584426 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 "6") +set(HD_RPR_PATCH_VERSION "7") From fac85a7e45a4e61b76fe8e372c7eb4df64b926b3 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 30 Nov 2020 13:38:21 -0500 Subject: [PATCH 16/32] Add a way to override mesh ID (#411) PURPOSE To allow the user to control the object ID that is rendered on the corresponding AOV. EFFECT OF CHANGE Added ID parameter to the Render Geometry Settings LOP node. --- pxr/imaging/plugin/hdRpr/mesh.cpp | 21 ++++++++++++++++--- pxr/imaging/plugin/hdRpr/mesh.h | 3 ++- pxr/imaging/plugin/hdRpr/primvarUtil.cpp | 5 ++++- pxr/imaging/plugin/hdRpr/primvarUtil.h | 3 ++- .../python/generateGeometrySettingFiles.py | 7 +++++++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index 8504b6ed8..ffcab2162 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -362,6 +362,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, bool isIgnoreContourDirty = false; bool isVisibilityMaskDirty = false; + bool isIdDirty = false; if (*dirtyBits & HdChangeTracker::DirtyPrimvar) { HdRprGeometrySettings geomSettings = {}; geomSettings.visibilityMask = kVisibleAll; @@ -378,6 +379,11 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, isVisibilityMaskDirty = true; } + if (m_id != geomSettings.id) { + m_id = geomSettings.id; + isIdDirty = true; + } + if (m_ignoreContour != geomSettings.ignoreContour) { m_ignoreContour = geomSettings.ignoreContour; isIgnoreContourDirty = true; @@ -426,7 +432,6 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, 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())) { - rprApi->SetMeshId(rprMesh, GetPrimId()); m_rprMeshes.push_back(rprMesh); } } else { @@ -530,7 +535,6 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (auto rprMesh = rprApi->CreateMesh(subsetPoints, subsetIndexes, subsetNormals, subsetNormalIndices, subsetUv, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) { - rprApi->SetMeshId(rprMesh, GetPrimId()); m_rprMeshes.push_back(rprMesh); ++it; } else { @@ -670,7 +674,6 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, int32_t meshId = GetPrimId(); for (int j = meshInstances.size(); j < newNumInstances; ++j) { meshInstances.push_back(rprApi->CreateMeshInstance(m_rprMeshes[i])); - rprApi->SetMeshId(meshInstances.back(), meshId); } } } @@ -702,6 +705,18 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } + if (newMesh || isIdDirty) { + uint32_t id = m_id >= 0 ? uint32_t(m_id) : GetPrimId(); + for (auto& rprMesh : m_rprMeshes) { + rprApi->SetMeshId(rprMesh, id); + } + for (auto& instances : m_rprMeshInstances) { + for (auto& rprMesh : instances) { + rprApi->SetMeshId(rprMesh, id); + } + } + } + if (newMesh || isIgnoreContourDirty) { for (auto& rprMesh : m_rprMeshes) { rprApi->SetMeshIgnoreContour(rprMesh, m_ignoreContour); diff --git a/pxr/imaging/plugin/hdRpr/mesh.h b/pxr/imaging/plugin/hdRpr/mesh.h index 37a7a602b..e45262a24 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.h +++ b/pxr/imaging/plugin/hdRpr/mesh.h @@ -96,7 +96,8 @@ class HdRprMesh final : public HdRprBaseRprim { HdDisplayStyle m_displayStyle; int m_refineLevel = 0; - uint32_t m_visibilityMask; + int m_id = -1; + uint32_t m_visibilityMask = 0; bool m_ignoreContour; }; diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp index c1cd3bb0f..b8b3f28f5 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.cpp +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.cpp @@ -17,6 +17,7 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PRIVATE_TOKENS(HdRprGeometryPrimvarTokens, + ((id, "rpr:id")) ((subdivisionLevel, "rpr:subdivisionLevel")) ((ignoreContour, "rpr:ignoreContour")) ((visibilityPrimary, "rpr:visibilityPrimary")) @@ -50,7 +51,9 @@ void HdRprParseGeometrySettings( }; for (auto& desc : constantPrimvarDescs) { - if (desc.name == HdRprGeometryPrimvarTokens->subdivisionLevel) { + if (desc.name == HdRprGeometryPrimvarTokens->id) { + HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->id, sceneDelegate, id, &geomSettings->id); + } else if (desc.name == HdRprGeometryPrimvarTokens->subdivisionLevel) { int subdivisionLevel; if (HdRprGetConstantPrimvar(HdRprGeometryPrimvarTokens->subdivisionLevel, sceneDelegate, id, &subdivisionLevel)) { geomSettings->subdivisionLevel = std::max(0, std::min(subdivisionLevel, 7)); diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.h b/pxr/imaging/plugin/hdRpr/primvarUtil.h index 5f9aa2c83..5eaba948d 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.h +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.h @@ -36,8 +36,9 @@ bool HdRprIsValidPrimvarSize( size_t vertexInterpolationSize); struct HdRprGeometrySettings { - uint32_t visibilityMask = 0; + int id = -1; int subdivisionLevel = 0; + uint32_t visibilityMask = 0; bool ignoreContour = false; }; diff --git a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py index 88ece54a3..2234374b7 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateGeometrySettingFiles.py @@ -18,6 +18,13 @@ { 'name': 'Mesh', 'settings': [ + { + 'name': 'primvars:rpr:id', + 'ui_name': 'ID', + 'defaultValue': 0, + 'minValue': 0, + 'maxValue': 1 ** 16 + }, { 'name': 'primvars:rpr:subdivisionLevel', 'ui_name': 'Subidivision Level', From f902231cd7df73336bd86c1d570ee75d0b569e74 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Mon, 30 Nov 2020 13:39:05 -0500 Subject: [PATCH 17/32] Create denoise AOVs lazily (#413) PURPOSE For a better user experience, we were preallocating denoise AOVs in advance to allow the user to enable/disable denoising without resetting AOVs at any time. For Northstar, creating additional denoise AOVs (albedo, normal) critically affects its performance. For Tahoe, it was only memory overhead, the performance penalty was miserable. EFFECT OF CHANGE Highly reduce time to first pixel for Full (RPR 2.0) render quality when denoise is not enabled. Change denoise usage. Now when denoise is enabled/disabled we clear AOVs Add two settings to control denoise behavior (like in RPR Blender plugin): Denoise Min Iteration - the first iteration on which denoising should be applied. Denoise Iteration Step - denoise use frequency. To denoise on each iteration, set to 1. --- .../python/generateRenderSettingFiles.py | 24 +++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 168 ++++++++++-------- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 92 ++++++---- pxr/imaging/plugin/hdRpr/rprApiAov.h | 8 +- 4 files changed, 187 insertions(+), 105 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 70596cbea..2d496ddfa 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -248,6 +248,30 @@ def hidewhen_not_tahoe(render_setting_categories): '"uiicon" VIEW_display_denoise' ] } + }, + { + 'folder': 'Denoise Settings', + 'houdini': { + 'hidewhen': 'enableDenoising == 0' + }, + 'settings': [ + { + 'name': 'denoiseMinIter', + 'ui_name': 'Denoise Min Iteration', + 'defaultValue': 4, + 'minValue': 1, + 'maxValue': 2 ** 16, + 'help': 'The first iteration on which denoising should be applied.' + }, + { + 'name': 'denoiseIterStep', + 'ui_name': 'Denoise Iteration Step', + 'defaultValue': 32, + 'minValue': 1, + 'maxValue': 2 ** 16, + 'help': 'Denoise use frequency. To denoise on each iteration, set to 1.' + } + ] } ] }, diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 70dd3e73d..1f59df4d1 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1390,6 +1390,9 @@ class HdRprApiImpl { enableDenoise.isDirty = config->IsDirty(HdRprConfig::DirtyDenoise); if (enableDenoise.isDirty) { enableDenoise.value = config->GetEnableDenoising(); + + m_denoiseMinIter = config->GetDenoiseMinIter(); + m_denoiseIterStep = config->GetDenoiseIterStep(); } tonemap.isDirty = config->IsDirty(HdRprConfig::DirtyTonemapping); @@ -1909,14 +1912,6 @@ class HdRprApiImpl { } } - if (m_dirtyFlags & ChangeTracker::DirtyScene || - m_dirtyFlags & ChangeTracker::DirtyAOVRegistry || - m_dirtyFlags & ChangeTracker::DirtyAOVBindings || - m_dirtyFlags & ChangeTracker::DirtyViewport || - IsCameraChanged()) { - clearAovs = true; - } - auto colorAov = GetColorAov(); if (colorAov) { UpdateDenoising(enableDenoise, colorAov); @@ -1926,6 +1921,14 @@ class HdRprApiImpl { } } + if (m_dirtyFlags & ChangeTracker::DirtyScene || + m_dirtyFlags & ChangeTracker::DirtyAOVRegistry || + m_dirtyFlags & ChangeTracker::DirtyAOVBindings || + m_dirtyFlags & ChangeTracker::DirtyViewport || + IsCameraChanged()) { + clearAovs = true; + } + auto rprApi = rprRenderParam->GetRprApi(); m_resolveData.ForAllAovs([=](ResolveData::AovEntry const& e) { e.aov->Update(rprApi, m_rifContext.get()); @@ -1953,12 +1956,14 @@ class HdRprApiImpl { return; } - if (!enableDenoise.isDirty) { + if (!enableDenoise.isDirty || + m_isDenoiseEnabled == enableDenoise.value) { return; } - if (!enableDenoise.value) { - colorAov->DisableDenoise(m_rifContext.get()); + m_isDenoiseEnabled = enableDenoise.value; + if (!m_isDenoiseEnabled) { + colorAov->DeinitDenoise(m_rifContext.get()); return; } @@ -1968,15 +1973,15 @@ class HdRprApiImpl { } if (filterType == rif::FilterType::EawDenoise) { - colorAov->EnableEAWDenoise(m_internalAovs.at(HdRprAovTokens->albedo), - m_internalAovs.at(HdAovTokens->normal), - m_internalAovs.at(HdRprGetCameraDepthAovName()), - m_internalAovs.at(HdAovTokens->primId), - m_internalAovs.at(HdRprAovTokens->worldCoordinate)); + colorAov->InitEAWDenoise(CreateAov(HdRprAovTokens->albedo), + CreateAov(HdAovTokens->normal), + CreateAov(HdRprGetCameraDepthAovName()), + CreateAov(HdAovTokens->primId), + CreateAov(HdRprAovTokens->worldCoordinate)); } else { - colorAov->EnableAIDenoise(m_internalAovs.at(HdRprAovTokens->albedo), - m_internalAovs.at(HdAovTokens->normal), - m_internalAovs.at(HdRprGetCameraDepthAovName())); + colorAov->InitAIDenoise(CreateAov(HdRprAovTokens->albedo), + CreateAov(HdAovTokens->normal), + CreateAov(HdRprGetCameraDepthAovName())); } } @@ -2042,6 +2047,15 @@ class HdRprApiImpl { bool CommonRenderImplPrologue() { if (m_numSamples == 0) { + // Default resolve mode + m_resolveMode = kResolveAfterRender; + + // When we want to have a uniform seed across all frames, + // we need to make sure that RPR_CONTEXT_FRAMECOUNT sequence is the same for all of them + if (m_isUniformSeed) { + m_frameCount = 0; + } + // Disable aborting on the very first sample // // Ideally, aborting the first sample should not be the problem. @@ -2054,15 +2068,6 @@ class HdRprApiImpl { } m_abortRender.store(false); - // Default resolve mode - m_resolveMode = kResolveAfterRender; - - // When we want to have a uniform seed across all frames, - // we need to make sure that RPR_CONTEXT_FRAMECOUNT sequence is the same for all of them - if (m_isUniformSeed && m_numSamples == 0) { - m_frameCount = 0; - } - // If the changes that were made by the user did not reset our AOVs, // we can just resolve them to the current render buffers and we are done with the rendering if (IsConverged()) { @@ -2126,6 +2131,13 @@ class HdRprApiImpl { // active pixels as often as possible const bool isAdaptiveSamplingEnabled = IsAdaptiveSamplingEnabled(); + // In a batch session, we do denoise once at the end + auto rprApi = static_cast(m_delegate->GetRenderParam())->GetRprApi(); + auto colorAov = GetColorAov(); + if (colorAov && m_isDenoiseEnabled) { + colorAov->SetDenoise(false, rprApi, m_rifContext.get()); + } + while (!IsConverged()) { if (renderThread->IsStopRequested()) { break; @@ -2207,6 +2219,10 @@ class HdRprApiImpl { } } + if (m_isDenoiseEnabled) { + colorAov->SetDenoise(true, rprApi, m_rifContext.get()); + } + ResolveFramebuffers(); } @@ -2247,6 +2263,10 @@ class HdRprApiImpl { // in contour rendering mode we must render only with RPR_CONTEXT_ITERATIONS=1 !m_contourAovs; + auto rprApi = static_cast(m_delegate->GetRenderParam())->GetRprApi(); + auto colorAov = GetColorAov(); + int iteration = 0; + while (!IsConverged()) { // In interactive mode, always render at least one frame, otherwise // disturbing full-screen-flickering will be visible or @@ -2260,6 +2280,27 @@ class HdRprApiImpl { IncrementFrameCount(IsAdaptiveSamplingEnabled()); + if (progressivelyIncreaseSamplesPerIter) { + // 1, 1, 2, 4, 8, ... + int numSamplesPerIter = std::max(int(pow(2, int(log2(m_numSamples)))), 1); + + // Make sure we will not oversample the image + int numSamplesLeft = std::min(numSamplesPerIter, m_maxSamples - m_numSamples); + numSamplesPerIter = numSamplesLeft > 0 ? numSamplesLeft : numSamplesPerIter; + if (m_numSamplesPerIter != numSamplesPerIter) { + m_numSamplesPerIter = numSamplesPerIter; + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_ITERATIONS, m_numSamplesPerIter), "Failed to set context iterations"); + + if (m_isRenderUpdateCallbackEnabled) { + // Enable resolves in the render update callback after RPR_CONTEXT_ITERATIONS gets high enough + // to get interactive updates even when RPR_CONTEXT_ITERATIONS huge + if (m_numSamplesPerIter >= 32) { + m_resolveMode = kResolveInRenderUpdateCallback; + } + } + } + } + auto startTime = std::chrono::high_resolution_clock::now(); m_rucData.previousProgress = -1.0f; @@ -2280,7 +2321,29 @@ class HdRprApiImpl { break; } - if (m_resolveMode == kResolveAfterRender) { + bool doDenoisedResolve = false; + if (colorAov) { + if (m_isDenoiseEnabled) { + ++iteration; + if (iteration >= m_denoiseMinIter) { + int relativeIter = iteration - m_denoiseMinIter; + if (relativeIter % m_denoiseIterStep == 0) { + doDenoisedResolve = true; + } + } + + // Always force denoise on the last sample because it's quite hard to match + // the max amount of samples and denoise controls (min iter and iter step) + if (m_numSamples + m_numSamplesPerIter == m_maxSamples) { + doDenoisedResolve = true; + } + } + + colorAov->SetDenoise(doDenoisedResolve, rprApi, m_rifContext.get()); + } + + if (m_resolveMode == kResolveAfterRender || + doDenoisedResolve) { ResolveFramebuffers(); } @@ -2293,25 +2356,6 @@ class HdRprApiImpl { m_isAbortingEnabled.store(true); m_numSamples += m_numSamplesPerIter; - - if (progressivelyIncreaseSamplesPerIter && m_numSamples > 1) { - m_numSamplesPerIter *= 2; - - // Make sure we will not oversample the image - int numSamplesLeft = m_maxSamples - m_numSamples; - m_numSamplesPerIter = std::min(m_numSamplesPerIter, numSamplesLeft); - if (m_numSamplesPerIter > 0) { - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_ITERATIONS, m_numSamplesPerIter), "Failed to set context iterations"); - } - - if (m_isRenderUpdateCallbackEnabled) { - // Enable resolves in the render update callback after RPR_CONTEXT_ITERATIONS gets high enough - // to get interactive updates even when RPR_CONTEXT_ITERATIONS huge - if (m_numSamplesPerIter >= 32) { - m_resolveMode = kResolveInRenderUpdateCallback; - } - } - } } } @@ -2916,30 +2960,6 @@ Don't show this message again? } void InitAovs() { - auto initInternalAov = [this](TfToken const& name) { - auto& aovDesc = HdRprAovRegistry::GetInstance().GetAovDesc(name); - if (auto aov = CreateAov(name, 0, 0, aovDesc.format)) { - m_internalAovs.emplace(name, std::move(aov)); - } - }; - - // We create separate AOVs needed for denoising ASAP - // In such a way, when user enables denoising it will not require to rerender - // but it requires more memory, obviously, it should be taken into an account - rif::FilterType filterType = rif::FilterType::EawDenoise; - if (m_rprContextMetadata.renderDeviceType == RprUsdRenderDeviceType::GPU) { - filterType = rif::FilterType::AIDenoise; - } - - initInternalAov(HdRprGetCameraDepthAovName()); - initInternalAov(HdRprAovTokens->albedo); - initInternalAov(HdAovTokens->color); - initInternalAov(HdAovTokens->normal); - if (filterType == rif::FilterType::EawDenoise) { - initInternalAov(HdAovTokens->primId); - initInternalAov(HdRprAovTokens->worldCoordinate); - } - m_lpeAovPool.clear(); m_lpeAovPool.insert(m_lpeAovPool.begin(), { HdRprAovTokens->lpe0, HdRprAovTokens->lpe1, HdRprAovTokens->lpe2, @@ -3592,6 +3612,10 @@ Don't show this message again? } m_resolveMode = kResolveAfterRender; bool m_isFirstSample = true; + bool m_isDenoiseEnabled = false; + int m_denoiseMinIter; + int m_denoiseIterStep; + GfVec2i m_viewportSize = GfVec2i(0); GfMatrix4d m_cameraProjectionMatrix = GfMatrix4d(1.f); HdRprCamera const* m_hdCamera = nullptr; diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 0c76a6c47..d9662cf25 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -220,7 +220,7 @@ void HdRprApiColorAov::SetOpacityAov(std::shared_ptr opacity) { } } -void HdRprApiColorAov::EnableAIDenoise( +void HdRprApiColorAov::InitAIDenoise( std::shared_ptr albedo, std::shared_ptr normal, std::shared_ptr linearDepth) { @@ -239,11 +239,10 @@ void HdRprApiColorAov::EnableAIDenoise( m_retainedDenoiseInputs[rif::LinearDepth] = linearDepth; m_retainedDenoiseInputs[rif::Albedo] = albedo; - SetFilter(kFilterAIDenoise, true); - SetFilter(kFilterEAWDenoise, false); + m_denoiseFilterType = kFilterAIDenoise; } -void HdRprApiColorAov::EnableEAWDenoise( +void HdRprApiColorAov::InitEAWDenoise( std::shared_ptr albedo, std::shared_ptr normal, std::shared_ptr linearDepth, @@ -266,18 +265,29 @@ void HdRprApiColorAov::EnableEAWDenoise( m_retainedDenoiseInputs[rif::Albedo] = albedo; m_retainedDenoiseInputs[rif::WorldCoordinate] = worldCoordinate; - SetFilter(kFilterEAWDenoise, true); - SetFilter(kFilterAIDenoise, false); + m_denoiseFilterType = kFilterEAWDenoise; } -void HdRprApiColorAov::DisableDenoise(rif::Context* rifContext) { - SetFilter(kFilterEAWDenoise, false); - SetFilter(kFilterAIDenoise, false); - SetFilter(kFilterResample, m_format != HdFormatFloat32Vec4); - +void HdRprApiColorAov::DeinitDenoise(rif::Context* rifContext) { for (auto& retainedInput : m_retainedDenoiseInputs) { retainedInput = nullptr; } + + m_denoiseFilterType = kFilterNone; +} + +void HdRprApiColorAov::SetDenoise(bool enable, HdRprApi const* rprApi, rif::Context* rifContext) { + if (m_denoiseFilterType != kFilterNone) { + SetFilter(m_denoiseFilterType, enable); + SetFilter(m_denoiseFilterType == kFilterAIDenoise ? kFilterEAWDenoise : kFilterAIDenoise, false); + } else { + SetFilter(kFilterAIDenoise, false); + SetFilter(kFilterEAWDenoise, false); + } + + SetFilter(kFilterResample, m_format != HdFormatFloat32Vec4); + + Update(rprApi, rifContext); } void HdRprApiColorAov::SetTonemap(TonemapParams const& params) { @@ -338,15 +348,27 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) m_enabledFilters = kFilterNone; } - m_filter = nullptr; - m_auxFilters.clear(); + // Reuse the previously created filters + std::vector>> filterPool = std::move(m_auxFilters); + if (m_filter) { + filterPool.emplace_back(m_mainFilterType, std::move(m_filter)); + } if ((m_enabledFilters & kFilterAIDenoise) || (m_enabledFilters & kFilterEAWDenoise) || (m_enabledFilters & kFilterComposeOpacity) || (m_enabledFilters & kFilterTonemap)) { - auto addFilter = [this](Filter type, std::unique_ptr filter) { + auto addFilter = [this, &filterPool](Filter type, std::function()> filterCreator) { + std::unique_ptr filter; + + auto it = std::find_if(filterPool.begin(), filterPool.end(), [type](auto& entry) { return type == entry.first; }); + if (it != filterPool.end()) { + filter = std::move(it->second); + } else { + filter = filterCreator(); + } + if (m_filter) { m_auxFilters.emplace_back(m_mainFilterType, std::move(m_filter)); } @@ -356,30 +378,40 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) }; if (m_enabledFilters & kFilterTonemap) { - addFilter(kFilterTonemap, rif::Filter::CreateCustom(RIF_IMAGE_FILTER_PHOTO_LINEAR_TONEMAP, rifContext)); + addFilter(kFilterTonemap, + [rifContext]() { + return rif::Filter::CreateCustom(RIF_IMAGE_FILTER_PHOTO_LINEAR_TONEMAP, rifContext); + } + ); } if ((m_enabledFilters & kFilterAIDenoise) || (m_enabledFilters & kFilterEAWDenoise)) { - auto denoiseFilterType = (m_enabledFilters & kFilterAIDenoise) ? rif::FilterType::AIDenoise : rif::FilterType::EawDenoise; - auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - auto type = (m_enabledFilters & kFilterAIDenoise) ? kFilterAIDenoise : kFilterEAWDenoise; - auto filter = rif::Filter::Create(denoiseFilterType, rifContext, fbDesc.fb_width, fbDesc.fb_height); - addFilter(type, std::move(filter)); + addFilter(type, + [this, rifContext]() { + auto denoiseFilterType = (m_enabledFilters & kFilterAIDenoise) ? rif::FilterType::AIDenoise : rif::FilterType::EawDenoise; + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); + return rif::Filter::Create(denoiseFilterType, rifContext, fbDesc.fb_width, fbDesc.fb_height); + } + ); } if (m_enabledFilters & kFilterComposeOpacity) { - auto filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); - auto opacityComposingKernelCode = std::string(R"( - int2 coord; - GET_COORD_OR_RETURN(coord, GET_BUFFER_SIZE(inputImage)); - vec4 alpha = ReadPixelTyped(alphaImage, coord.x, coord.y); - vec4 color = ReadPixelTyped(inputImage, coord.x, coord.y) * alpha.x; - WritePixelTyped(outputImage, coord.x, coord.y, make_vec4(color.x, color.y, color.z, alpha.x)); - )"); - filter->SetParam("code", opacityComposingKernelCode); - addFilter(kFilterComposeOpacity, std::move(filter)); + addFilter(kFilterComposeOpacity, + [rifContext]() { + auto filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); + auto opacityComposingKernelCode = std::string(R"( + int2 coord; + GET_COORD_OR_RETURN(coord, GET_BUFFER_SIZE(inputImage)); + vec4 alpha = ReadPixelTyped(alphaImage, coord.x, coord.y); + vec4 color = ReadPixelTyped(inputImage, coord.x, coord.y) * alpha.x; + WritePixelTyped(outputImage, coord.x, coord.y, make_vec4(color.x, color.y, color.z, alpha.x)); + )"); + filter->SetParam("code", opacityComposingKernelCode); + return filter; + } + ); } } else if (m_enabledFilters & kFilterResample) { m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_RESAMPLE, rifContext); diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index ed461aa48..ff2111db8 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -85,15 +85,16 @@ class HdRprApiColorAov : public HdRprApiAov { void SetOpacityAov(std::shared_ptr opacity); - void EnableAIDenoise(std::shared_ptr albedo, + void InitAIDenoise(std::shared_ptr albedo, std::shared_ptr normal, std::shared_ptr linearDepth); - void EnableEAWDenoise(std::shared_ptr albedo, + void InitEAWDenoise(std::shared_ptr albedo, std::shared_ptr normal, std::shared_ptr linearDepth, std::shared_ptr objectId, std::shared_ptr worldCoordinate); - void DisableDenoise(rif::Context* rifContext); + void DeinitDenoise(rif::Context* rifContext); + void SetDenoise(bool enable, HdRprApi const* rprApi, rif::Context* rifContext); struct TonemapParams { bool enable; @@ -140,6 +141,7 @@ class HdRprApiColorAov : public HdRprApiAov { std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; std::shared_ptr m_retainedDenoiseInputs[rif::MaxInput]; + Filter m_denoiseFilterType = kFilterNone; Filter m_mainFilterType = kFilterNone; std::vector>> m_auxFilters; From 858ec3e8466dbbfe909792229668fa13cf068a0e Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Mon, 30 Nov 2020 19:43:52 +0100 Subject: [PATCH 18/32] buildmaster: version update to 2.0.8 --- 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 00f584426..e737d0a15 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 "7") +set(HD_RPR_PATCH_VERSION "8") From c2c8dc641ad8a9c3f781db43452922c55e60670d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Wed, 2 Dec 2020 18:16:48 +0200 Subject: [PATCH 19/32] Improve .rpr export (#414) PURPOSE Speed up .rpr export and reduce output size. EFFECT OF CHANGE Export .rpr sequence within a single process Create RPR context only one time Incrementally update scene instead of resyncing from scratch on each frame Export .rpr with RPRLOADSTORE_EXPORTFLAG_EXTERNALFILES flag by default Allows reusing data within frames Add new checkbox "Export As Single File" to revert to the old behavior --- .../python/generateRenderSettingFiles.py | 4 ++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 9 ++- .../plugin/rprHoudini/LOP_RPRExportHelper.cpp | 58 +++++++++++++----- .../plugin/rprHoudini/LOP_RPRExportHelper.h | 5 ++ .../plugin/rprHoudini/hda/rpr_exportRpr1.hda | Bin 8702 -> 10187 bytes 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 2d496ddfa..e85ccfad3 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -556,6 +556,10 @@ def hidewhen_not_tahoe(render_setting_categories): 'name': 'rprExportPath', 'defaultValue': '', 'c_type': 'std::string' + }, + { + 'name': 'rprExportAsSingleFile', + 'defaultValue': False } ] } diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 1f59df4d1..4c7a9b750 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1411,6 +1411,7 @@ class HdRprApiImpl { if (config->IsDirty(HdRprConfig::DirtyRprExport)) { m_rprSceneExportPath = config->GetRprExportPath(); + m_rprExportAsSingleFile = config->GetRprExportAsSingleFile(); } if (config->IsDirty(HdRprConfig::DirtyRenderQuality)) { @@ -2469,9 +2470,14 @@ Don't show this message again? RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_Y_FLIP, currentYFlip), "Failed to set context Y FLIP parameter"); } + unsigned int rprsFlags = 0; + if (!m_rprExportAsSingleFile) { + rprsFlags |= RPRLOADSTORE_EXPORTFLAG_EXTERNALFILES; + } + auto rprContextHandle = rpr::GetRprObject(m_rprContext.get()); auto rprSceneHandle = rpr::GetRprObject(m_scene.get()); - if (RPR_ERROR_CHECK(rprsExport(m_rprSceneExportPath.c_str(), rprContextHandle, rprSceneHandle, 0, nullptr, nullptr, 0, nullptr, nullptr, 0), "Failed to export .rpr file")) { + if (RPR_ERROR_CHECK(rprsExport(m_rprSceneExportPath.c_str(), rprContextHandle, rprSceneHandle, 0, nullptr, nullptr, 0, nullptr, nullptr, rprsFlags), "Failed to export .rpr file")) { return; } @@ -3659,6 +3665,7 @@ Don't show this message again? std::atomic m_abortRender; std::string m_rprSceneExportPath; + bool m_rprExportAsSingleFile; std::condition_variable* m_presentedConditionVariable = nullptr; bool* m_presentedCondition = nullptr; diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp index aa85a11e7..9bc37a6b9 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp @@ -20,9 +20,11 @@ limitations under the License. #include #include +#include #include #include +#include #include #include #include @@ -30,11 +32,18 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE +TF_DEFINE_PRIVATE_TOKENS(_tokens, + (rprExportPath) + (rprExportAsSingleFile) +); + static PRM_Name g_exportPathName("exportPath", "Export Path"); +static PRM_Name g_exportPathAsSingleFileName("exportAsSingleFile", "Export As Single File"); static PRM_Name g_renderSettingsName("renderSettings", "Render Settings"); static PRM_Template g_templateList[] = { PRM_Template(PRM_FILE, 1, &g_exportPathName), + PRM_Template(PRM_TOGGLE_E, 1, &g_exportPathAsSingleFileName), PRM_Template(PRM_STRING_E, 1, &g_renderSettingsName), PRM_Template(), }; @@ -59,13 +68,40 @@ LOP_RPRExportHelper::LOP_RPRExportHelper(OP_Network *net, const char *name, OP_O } +template +bool LOP_RPRExportHelper::SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, double time, bool timeDependent) { + if (auto exportPathAttr = prim->CreateAttribute(name, sdfType, true)) { + auto timeCode = timeDependent ? HUSDgetCurrentUsdTimeCode() : UsdTimeCode::Default(); + if (exportPathAttr.Set(value, timeCode)) { + return true; + } + + addError(LOP_MESSAGE, TfStringPrintf("Failed to set %s:%s", prim->GetPath().GetText(), name.GetText()).c_str()); + } else { + addError(LOP_MESSAGE, TfStringPrintf("Failed to create %s attribute", name.GetText()).c_str()); + } + + return false; +} + OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { if (cookModifyInput(context) >= UT_ERROR_FATAL) { return error(); } + auto getParm = [&](const UT_StringHolder &parmname) -> PRM_Parm* { + int index = getParmList()->getParmIndex(parmname); + if (index == -1) { + return nullptr; + } + return getParmList()->getParmPtr(index); + }; + + auto exportPathParm = getParm(g_exportPathName.getToken()); + auto exportAsSingleFileParm = getParm(g_exportPathAsSingleFileName.getToken()); + UT_String exportPath; - evalString(exportPath, g_exportPathName.getToken(), 0, context.getTime()); + exportPathParm->getValue(context.getTime(), exportPath, 0, true, context.getThread()); if (!exportPath.isstring()) { return error(); @@ -76,6 +112,10 @@ OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { exportPath += ".rpr"; } + int exportAsSingleFileInt; + exportAsSingleFileParm->getValue(context.getTime(), exportAsSingleFileInt, 0, context.getThread()); + bool exportAsSingleFile = bool(exportAsSingleFileInt); + UT_String renderSettingsPath; evalString(renderSettingsPath, g_renderSettingsName.getToken(), 0, context.getTime()); @@ -86,21 +126,11 @@ OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { // Insert export file into each UsdRenderSetting primitive, // or if no UsdRenderSetting primitives exist create new one - auto modifyRenderSettings = [this, &exportPath](UsdRenderSettings& renderSettings) { + auto modifyRenderSettings = [&](UsdRenderSettings& renderSettings) { auto prim = renderSettings.GetPrim(); - static TfToken rprExportPath("rprExportPath", TfToken::Immortal); - if (auto exportPathAttr = prim.CreateAttribute(rprExportPath, SdfValueTypeNames->String, true)) { - if (!exportPathAttr.Set(exportPath.toStdString())) { - addError(LOP_MESSAGE, TfStringPrintf("Failed to set %s:%s", prim.GetPath().GetText(), rprExportPath.GetText()).c_str()); - return false; - } - } else { - addError(LOP_MESSAGE, TfStringPrintf("Failed to create %s attribute", rprExportPath.GetText()).c_str()); - return false; - } - - return true; + return SetRenderSetting(&prim, _tokens->rprExportPath, SdfValueTypeNames->String, exportPath.toStdString(), context.getTime(), exportPathParm->isTimeDependent()) && + SetRenderSetting(&prim, _tokens->rprExportAsSingleFile, SdfValueTypeNames->Bool, exportAsSingleFile, context.getTime(), exportAsSingleFileParm->isTimeDependent()); }; // Use explicitly specified render settings primitive if any diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h index 1cf47155a..784a4f368 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h @@ -15,6 +15,7 @@ limitations under the License. #define RPR_LOP_RPREXPORTHELPER_H #include "pxr/pxr.h" +#include "pxr/usd/usd/prim.h" #include @@ -31,6 +32,10 @@ class LOP_RPRExportHelper : public LOP_Node { protected: OP_ERROR cookMyLop(OP_Context &context) override; + +private: + template + bool SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, double time, bool timeDependent); }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda index 7fbba16794963078d01a951e2d89140392459991..b132bcb2b24e2e66301acc91abf49cd557378f18 100644 GIT binary patch delta 3404 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 LRA{X*9pL`}sNMp_ delta 2064 zcmXw)cU0478-{$>lAp8wu{`+f6NjU%b$OH3`L|6le{ zKIOOGhk#Ok2-0C7q>4z(AprnD*qlnl(}+$!R6jBe07O~<0Hky1()~aRhN2%1o~R#D zuqDx-3;^QLgBtLI2|1HU{z0f9U!woDf7Ou#Rg{$83W8jeI!vPfOPZ4cX~aNU5bAn3 z07%&Y0N>mX#qUC-2KkW!0YF~spuzhew(=nbI=NUJV4ZY0kGux7>0p~1{|+F2A(TeN zWBmMy_GH>YIS2q?ss}Fku+1j&yys<~69fygF_L63WA;!9D=`AEbW^w(l0;k`cy#1r?l3|s*K*8X4~tNN z)Ph^d?yaKTs5mg-nmvf2g)1L{b@+hBOe#o60F&*RK>L7rXVs!OUV2@k*F z1*lk96tGF_LOxiZWmTjkobBE67Cfij1L)E{`&&My@#J*gZ0UOUWCgkW!{G87FL9OHpO1$NCV? zpL5jAc;c%pp*~mP$+@{O{iI*FK7z3D1h83bq+KR~+(U(~Zk*s>Fr~a8vxXVLQ2%yl zPG2hJC{M*FT?8Z2*f{Ldl%bJP_-57jg+a{=b34oLTpFf%LEqN@+8x+&663R|Zl|@r zp9V$+3N6a?PWs06s6uSH@zDZjXMsV|GJ($Fwg<`P{nVG)dSiXN>}$nh7{d|O#=Qb| zG9kfg0y$h%r^au1bn+deUPjz(K?rsE*IUL*VlCEdJuXH%bsOvbi0CUV)Dff`t^Het;=((u-&y4{e7H#NydC;cu}-(e^{rM@XVU) z*87vkC7X$p{0`_RxHiV`cQ2>K?=jRQ)p(JJemKE*Ao95UJreU|51~DVq`NI-~el1o-Z6Jh{A2~%- zazrT2mnmr}7!sfUA=90msO%KoFY5k`{NnjE zk^76d-gSlff=y&^ttQqX0*5Rejq@&V_BX+bYIqE`d!|=xP^+j z!Q>g)_iaIs+4WM^KfF=K!X7kp#v&X7#AOwVbi!{v+kbK*&qoLERe4Vjvv1XrM+Ya# z4kj(cI0uwZX}mCpggvs3n;ZpsnYur332QiAz3P!{%cySbd+)B+o!R%T|BU_XIf(S8 zZidcli9Pqp)kTG>coP^!&osIK-)I`Oc zipy*LqgM3s_mf`XC)bFt!^{GadQ zIz;G1##5CEI&qfWP_lTpN3CbZ?R%%i$Mw*f@BSkuhO1)t#JUW4GWO`#(?@g98Ts4(!%#fYeOyh}5<3GbB&?%9rL#{gqTH+`3G#ykHaS^s@`5 zSUlf4F-xk>`IJ$G_0&zUjjF0NyaFgVJ(CYK$@jr`s>RLD3SYf|Do0=7&{LOiHK}3d z-DU7bp~(=t2d4Ah;IxmwG+Zj27g0#pNjHmWGtvKAvC=wrh)J}tZs zKmC5 Date: Wed, 2 Dec 2020 18:17:26 +0200 Subject: [PATCH 20/32] Install version file for autotests (#415) --- CMakeLists.txt | 7 +++++++ cmake/defaults/ProjectDefaults.cmake | 2 ++ cmake/macros/parseVersion.cmake | 21 +++++++++++++++++++++ cmake/modules/FindRif.cmake | 23 ++--------------------- cmake/modules/FindRpr.cmake | 3 +++ 5 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 cmake/macros/parseVersion.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fd610a8c6..a24caf4d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,3 +36,10 @@ add_subdirectory(pxr/imaging) install(FILES README.md DESTINATION .) install(FILES INSTALL.md DESTINATION .) install(FILES LICENSE.md DESTINATION .) + +install( + CODE + "FILE(WRITE \"${CMAKE_INSTALL_PREFIX}/version\" +\"core:${RPR_VERSION_STRING} +plugin:${HD_RPR_MAJOR_VERSION}.${HD_RPR_MINOR_VERSION}.${HD_RPR_PATCH_VERSION} +\")") diff --git a/cmake/defaults/ProjectDefaults.cmake b/cmake/defaults/ProjectDefaults.cmake index 6205a72ce..530bda4f8 100644 --- a/cmake/defaults/ProjectDefaults.cmake +++ b/cmake/defaults/ProjectDefaults.cmake @@ -50,6 +50,8 @@ if (PXR_BUILD_TESTS) enable_testing() endif() +include(parseVersion) + if(NOT DEFINED RPR_SDK_PLATFORM) include(PlatformIntrospection) DETERMINE_PLATFORM(RPR_SDK_PLATFORM) diff --git a/cmake/macros/parseVersion.cmake b/cmake/macros/parseVersion.cmake new file mode 100644 index 000000000..edeb95f8a --- /dev/null +++ b/cmake/macros/parseVersion.cmake @@ -0,0 +1,21 @@ +macro(parseVersion version_file prefix) + if(NOT EXISTS ${version_file}) + message(FATAL_ERROR "Invalid ${prefix} SDK: missing ${version_file} file") + endif() + + file(STRINGS "${version_file}" _major_version_str + REGEX "^#define[\t ]+${prefix}_VERSION_MAJOR[\t ]+.*") + file(STRINGS "${version_file}" _minor_version_str + REGEX "^#define[\t ]+${prefix}_VERSION_MINOR[\t ]+.*") + file(STRINGS "${version_file}" _revision_version_str + REGEX "^#define[\t ]+${prefix}_VERSION_REVISION[\t ]+.*") + + string(REGEX REPLACE "^.*MAJOR[\t ]+([0-9]*).*$" "\\1" + ${prefix}_MAJOR_VERSION "${_major_version_str}") + string(REGEX REPLACE "^.*MINOR[\t ]+([0-9]*).*$" "\\1" + ${prefix}_MINOR_VERSION "${_minor_version_str}") + string(REGEX REPLACE "^.*REVISION[\t ]+([0-9]*).*$" "\\1" + ${prefix}_REVISION_VERSION "${_revision_version_str}") + + set(${prefix}_VERSION_STRING "${${prefix}_MAJOR_VERSION}.${${prefix}_MINOR_VERSION}.${${prefix}_REVISION_VERSION}") +endmacro() \ No newline at end of file diff --git a/cmake/modules/FindRif.cmake b/cmake/modules/FindRif.cmake index 27972b7c1..4c5befe4e 100644 --- a/cmake/modules/FindRif.cmake +++ b/cmake/modules/FindRif.cmake @@ -53,32 +53,13 @@ if(NOT DEFINED RIF_MODELS_DIR) set(RIF_MODELS_DIR "${RIF_LOCATION}/models") endif() -set(RIF_VERSION_FILE "${RIF_LOCATION_INCLUDE}/RadeonImageFilters_version.h") -if(NOT EXISTS ${RIF_VERSION_FILE}) - message(FATAL_ERROR "Invalid RIF SDK: missing ${RIF_VERSION_FILE} file") -endif() - -file(STRINGS "${RIF_VERSION_FILE}" _rif_major_version_str - REGEX "^#define[\t ]+RIF_VERSION_MAJOR[\t ]+.*") -file(STRINGS "${RIF_VERSION_FILE}" _rif_minor_version_str - REGEX "^#define[\t ]+RIF_VERSION_MINOR[\t ]+.*") -file(STRINGS "${RIF_VERSION_FILE}" _rif_revision_version_str - REGEX "^#define[\t ]+RIF_VERSION_REVISION[\t ]+.*") - -string(REGEX REPLACE "^.*MAJOR[\t ]+([0-9]*).*$" "\\1" - RIF_MAJOR_VERSION "${_rif_major_version_str}") -string(REGEX REPLACE "^.*MINOR[\t ]+([0-9]*).*$" "\\1" - RIF_MINOR_VERSION "${_rif_minor_version_str}") -string(REGEX REPLACE "^.*REVISION[\t ]+([0-9]*).*$" "\\1" - RIF_REVISION_VERSION "${_rif_revision_version_str}") - -set(RIF_VERSION_STRING "${RIF_MAJOR_VERSION}.${RIF_MINOR_VERSION}.${RIF_REVISION_VERSION}") +parseVersion("${RIF_LOCATION_INCLUDE}/RadeonImageFilters_version.h" RIF) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Rif REQUIRED_VARS - RIF_VERSION_STRING RIF_LOCATION_INCLUDE + RIF_VERSION_STRING RIF_LIBRARY ) diff --git a/cmake/modules/FindRpr.cmake b/cmake/modules/FindRpr.cmake index 3f9a14791..7b593564c 100644 --- a/cmake/modules/FindRpr.cmake +++ b/cmake/modules/FindRpr.cmake @@ -81,11 +81,14 @@ if(NOT RPR_PLUGINS) message(FATAL_ERROR "At least one RPR plugin required") endif() +parseVersion("${RPR_LOCATION_INCLUDE}/RadeonProRender.h" RPR) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Rpr REQUIRED_VARS RPR_LOCATION_INCLUDE + RPR_VERSION_STRING RPR_LOADSTORE_LIBRARY RPR_LIBRARY ) From 536f154aee07cef27dd43680ed384ff732f62b18 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Wed, 2 Dec 2020 17:28:55 +0100 Subject: [PATCH 21/32] buildmaster: version update to 2.0.9 --- 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 e737d0a15..38150345b 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 "8") +set(HD_RPR_PATCH_VERSION "9") From 14ec83e16dd3fba2a74a7957fbef57260e6eeb20 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Wed, 2 Dec 2020 19:09:55 +0200 Subject: [PATCH 22/32] Fix crash on resizing viewport when denoising enabled (#416) PURPOSE Fix crash on resizing viewport when denoising enabled EFFECT OF CHANGE None - changes that lead to this crash were not released yet. --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 4c7a9b750..9d0de71b0 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1874,6 +1874,15 @@ class HdRprApiImpl { } void UpdateAovs(HdRprRenderParam* rprRenderParam, RenderSetting enableDenoise, RenderSetting tonemap, bool clearAovs) { + auto colorAov = GetColorAov(); + if (colorAov) { + UpdateDenoising(enableDenoise, colorAov); + + if (tonemap.isDirty) { + colorAov->SetTonemap(tonemap.value); + } + } + if (m_dirtyFlags & (ChangeTracker::DirtyAOVBindings | ChangeTracker::DirtyAOVRegistry)) { m_resolveData.rawAovs.clear(); m_resolveData.computedAovs.clear(); @@ -1913,15 +1922,6 @@ class HdRprApiImpl { } } - auto colorAov = GetColorAov(); - if (colorAov) { - UpdateDenoising(enableDenoise, colorAov); - - if (tonemap.isDirty) { - colorAov->SetTonemap(tonemap.value); - } - } - if (m_dirtyFlags & ChangeTracker::DirtyScene || m_dirtyFlags & ChangeTracker::DirtyAOVRegistry || m_dirtyFlags & ChangeTracker::DirtyAOVBindings || From cde0920cf156756700e31623b84e918c4fc8529e Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Wed, 2 Dec 2020 18:13:54 +0100 Subject: [PATCH 23/32] buildmaster: version update to 2.0.10 --- 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 38150345b..79275709c 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 "9") +set(HD_RPR_PATCH_VERSION "10") From 1c3f9592c6055bea62c8f216055177502f1daf7d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Thu, 3 Dec 2020 18:35:36 +0200 Subject: [PATCH 24/32] Fix AOV management in contour rendering mode (#418) --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 9d0de71b0..3eef95615 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1502,40 +1502,28 @@ class HdRprApiImpl { if (renderMode == HdRprRenderModeTokens->Contour) { if (!m_contourAovs) { m_contourAovs = std::make_unique(); + m_contourAovs->normal = CreateAov(HdAovTokens->normal); + m_contourAovs->primId = CreateAov(HdAovTokens->primId); + m_contourAovs->materialId = CreateAov(HdRprAovTokens->materialId); } RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_DEBUG_ENABLED, preferences.GetContourDebug()), "Failed to set contour debug"); RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_ANTIALIASING, preferences.GetContourAntialiasing()), "Failed to set contour antialiasing"); + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_USE_NORMAL, int(preferences.GetContourUseNormal())), "Failed to set contour use normal"); if (preferences.GetContourUseNormal()) { - if (!m_contourAovs->normal) { - m_contourAovs->normal = CreateAov(HdAovTokens->normal); - } - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_NORMAL, preferences.GetContourLinewidthNormal()), "Failed to set contour normal linewidth"); RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_NORMAL_THRESHOLD, preferences.GetContourNormalThreshold()), "Failed to set contour normal threshold"); - } else { - m_contourAovs->normal = nullptr; } + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_USE_OBJECTID, int(preferences.GetContourUsePrimId())), "Failed to set contour use primId"); if (preferences.GetContourUsePrimId()) { - if (!m_contourAovs->primId) { - m_contourAovs->primId = CreateAov(HdAovTokens->primId); - } - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_OBJECTID, preferences.GetContourLinewidthPrimId()), "Failed to set contour primId linewidth"); - } else { - m_contourAovs->primId = nullptr; } + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_USE_MATERIALID, int(preferences.GetContourUseMaterialId())), "Failed to set contour use materialId"); if (preferences.GetContourUseMaterialId()) { - if (!m_contourAovs->materialId) { - m_contourAovs->materialId = CreateAov(HdRprAovTokens->materialId); - } - - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_OBJECTID, preferences.GetContourLinewidthPrimId()), "Failed to set contour primId linewidth"); - } else { - m_contourAovs->materialId = nullptr; + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_CONTOUR_LINEWIDTH_MATERIALID, preferences.GetContourLinewidthMaterialId()), "Failed to set contour materialId linewidth"); } RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_GPUINTEGRATOR, "gpucontour"), "Failed to set gpuintegrator"); From 32b3ea37348cfd835795c00efd379b33d7a7f5e8 Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 3 Dec 2020 17:43:57 +0100 Subject: [PATCH 25/32] buildmaster: version update to 2.0.11 --- 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 79275709c..65666444c 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 "10") +set(HD_RPR_PATCH_VERSION "11") From cfbb3e4d086eef262f921012c4f67329e7d01948 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 4 Dec 2020 00:41:58 +0200 Subject: [PATCH 26/32] Update RPR to 2.1.8 (#417) * Update RPR to 2.1.8 * Expose new AOVs * Camera space shading normal * Cryptomatte AOVs (TODO integration) * Add .rpr export image cache control * Allow disabling resolution downscale in interactive mode for Tahoe * Do not use image cache by default when export .rpr --- deps/RPR | 2 +- pxr/imaging/plugin/hdRpr/aovDescriptor.cpp | 18 ++++++++++++++-- pxr/imaging/plugin/hdRpr/aovDescriptor.h | 7 ++++++ .../python/generateRenderSettingFiles.py | 13 ++++++++++++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 8 ++++++- .../plugin/rprHoudini/LOP_RPRExportHelper.cpp | 20 ++++++++++-------- .../plugin/rprHoudini/LOP_RPRExportHelper.h | 2 +- .../plugin/rprHoudini/hda/rpr_exportRpr1.hda | Bin 10187 -> 10022 bytes .../hda/rpr_standard_rendervars.hda | Bin 26064 -> 27727 bytes 9 files changed, 56 insertions(+), 14 deletions(-) diff --git a/deps/RPR b/deps/RPR index 3bc01d29f..015becd5b 160000 --- a/deps/RPR +++ b/deps/RPR @@ -1 +1 @@ -Subproject commit 3bc01d29f8dee0068023a897e63699c82e5ce43d +Subproject commit 015becd5b81c772c5edfa07b5469e32ecef5e6be diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp index 97e58c478..ec4295253 100644 --- a/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp @@ -25,7 +25,7 @@ TF_INSTANTIATE_SINGLETON(HdRprAovRegistry); TF_DEFINE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS); HdRprAovRegistry::HdRprAovRegistry() { - const auto rprAovMax = RPR_AOV_LPE_8 + 1; + const auto rprAovMax = RPR_AOV_CRYPTOMATTE_OBJ2 + 1; const GfVec4f idClearValue(255.0f, 255.0f, 255.0f, 0.0f); m_aovDescriptors.resize(rprAovMax); @@ -61,7 +61,13 @@ HdRprAovRegistry::HdRprAovRegistry() { RPR_AOV_LPE_5, RPR_AOV_LPE_6, RPR_AOV_LPE_7, - RPR_AOV_LPE_8 + RPR_AOV_LPE_8, + RPR_AOV_CRYPTOMATTE_MAT0, + RPR_AOV_CRYPTOMATTE_MAT1, + RPR_AOV_CRYPTOMATTE_MAT2, + RPR_AOV_CRYPTOMATTE_OBJ0, + RPR_AOV_CRYPTOMATTE_OBJ1, + RPR_AOV_CRYPTOMATTE_OBJ2, }) { m_aovDescriptors[rprAovId] = HdRprAovDescriptor(rprAovId); } @@ -78,6 +84,7 @@ HdRprAovRegistry::HdRprAovRegistry() { m_aovDescriptors[RPR_AOV_BACKGROUND] = HdRprAovDescriptor(RPR_AOV_BACKGROUND, false); m_aovDescriptors[RPR_AOV_VELOCITY] = HdRprAovDescriptor(RPR_AOV_VELOCITY, false); m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL] = HdRprAovDescriptor(RPR_AOV_VIEW_SHADING_NORMAL, false); + m_aovDescriptors[RPR_AOV_CAMERA_NORMAL] = HdRprAovDescriptor(RPR_AOV_CAMERA_NORMAL, false); m_computedAovDescriptors.resize(kComputedAovsCount); m_computedAovDescriptors[kNdcDepth] = HdRprAovDescriptor(kNdcDepth, false, HdFormatFloat32, GfVec4f(std::numeric_limits::infinity()), true); @@ -135,6 +142,13 @@ HdRprAovRegistry::HdRprAovRegistry() { addAovNameLookup(HdRprAovTokens->lpe6, m_aovDescriptors[RPR_AOV_LPE_6]); addAovNameLookup(HdRprAovTokens->lpe7, m_aovDescriptors[RPR_AOV_LPE_7]); addAovNameLookup(HdRprAovTokens->lpe8, m_aovDescriptors[RPR_AOV_LPE_8]); + addAovNameLookup(HdRprAovTokens->cameraNormal, m_aovDescriptors[RPR_AOV_CAMERA_NORMAL]); + addAovNameLookup(HdRprAovTokens->cryptomatteMat0, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_MAT0]); + addAovNameLookup(HdRprAovTokens->cryptomatteMat1, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_MAT1]); + addAovNameLookup(HdRprAovTokens->cryptomatteMat2, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_MAT2]); + addAovNameLookup(HdRprAovTokens->cryptomatteObj0, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_OBJ0]); + addAovNameLookup(HdRprAovTokens->cryptomatteObj1, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_OBJ1]); + addAovNameLookup(HdRprAovTokens->cryptomatteObj2, m_aovDescriptors[RPR_AOV_CRYPTOMATTE_OBJ2]); } HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(TfToken const& name) { diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.h b/pxr/imaging/plugin/hdRpr/aovDescriptor.h index 20e9695dc..21068bda0 100644 --- a/pxr/imaging/plugin/hdRpr/aovDescriptor.h +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.h @@ -65,6 +65,13 @@ PXR_NAMESPACE_OPEN_SCOPE (lpe6) \ (lpe7) \ (lpe8) \ + (cameraNormal) \ + (cryptomatteMat0) \ + (cryptomatteMat1) \ + (cryptomatteMat2) \ + (cryptomatteObj0) \ + (cryptomatteObj1) \ + (cryptomatteObj2) \ TF_DECLARE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS); diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index e85ccfad3..c930c8952 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -416,6 +416,15 @@ def hidewhen_not_tahoe(render_setting_categories): 'houdini': { 'hidewhen': hidewhen_not_northstar } + }, + { + 'name': 'interactiveEnableDownscale', + 'ui_name': 'Downscale Resolution When Interactive', + 'help': 'Controls whether in interactive mode resolution should be downscaled or no.', + 'defaultValue': True, + 'houdini': { + 'hidewhen': hidewhen_not_tahoe + } } ] }, @@ -560,6 +569,10 @@ def hidewhen_not_tahoe(render_setting_categories): { 'name': 'rprExportAsSingleFile', 'defaultValue': False + }, + { + 'name': 'rprExportUseImageCache', + 'defaultValue': False } ] } diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 3eef95615..1baa648db 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1412,6 +1412,7 @@ class HdRprApiImpl { if (config->IsDirty(HdRprConfig::DirtyRprExport)) { m_rprSceneExportPath = config->GetRprExportPath(); m_rprExportAsSingleFile = config->GetRprExportAsSingleFile(); + m_rprExportUseImageCache = config->GetRprExportUseImageCache(); } if (config->IsDirty(HdRprConfig::DirtyRenderQuality)) { @@ -1590,7 +1591,8 @@ class HdRprApiImpl { } RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_PREVIEW, uint32_t(downscale)), "Failed to set preview mode"); } else { - RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_PREVIEW, uint32_t(m_isInteractive)), "Failed to set preview mode"); + bool enableDownscale = m_isInteractive && preferences.GetInteractiveEnableDownscale(); + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_PREVIEW, uint32_t(enableDownscale)), "Failed to set preview mode"); } if (preferences.IsDirty(HdRprConfig::DirtyInteractiveMode) || m_isInteractive) { @@ -2462,6 +2464,9 @@ Don't show this message again? if (!m_rprExportAsSingleFile) { rprsFlags |= RPRLOADSTORE_EXPORTFLAG_EXTERNALFILES; } + if (m_rprExportUseImageCache) { + rprsFlags |= RPRLOADSTORE_EXPORTFLAG_USE_IMAGE_CACHE; + } auto rprContextHandle = rpr::GetRprObject(m_rprContext.get()); auto rprSceneHandle = rpr::GetRprObject(m_scene.get()); @@ -3654,6 +3659,7 @@ Don't show this message again? std::string m_rprSceneExportPath; bool m_rprExportAsSingleFile; + bool m_rprExportUseImageCache; std::condition_variable* m_presentedConditionVariable = nullptr; bool* m_presentedCondition = nullptr; diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp index 9bc37a6b9..078c97a6c 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.cpp @@ -35,15 +35,18 @@ PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PRIVATE_TOKENS(_tokens, (rprExportPath) (rprExportAsSingleFile) + (rprExportUseImageCache) ); static PRM_Name g_exportPathName("exportPath", "Export Path"); -static PRM_Name g_exportPathAsSingleFileName("exportAsSingleFile", "Export As Single File"); +static PRM_Name g_exportAsSingleFileName("exportAsSingleFile", "Export As Single File"); +static PRM_Name g_exportUseImageCacheName("exportUseImageCache", "Use Image Cache"); static PRM_Name g_renderSettingsName("renderSettings", "Render Settings"); static PRM_Template g_templateList[] = { PRM_Template(PRM_FILE, 1, &g_exportPathName), - PRM_Template(PRM_TOGGLE_E, 1, &g_exportPathAsSingleFileName), + PRM_Template(PRM_TOGGLE_E, 1, &g_exportAsSingleFileName), + PRM_Template(PRM_TOGGLE_E, 1, &g_exportUseImageCacheName), PRM_Template(PRM_STRING_E, 1, &g_renderSettingsName), PRM_Template(), }; @@ -69,7 +72,7 @@ LOP_RPRExportHelper::LOP_RPRExportHelper(OP_Network *net, const char *name, OP_O } template -bool LOP_RPRExportHelper::SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, double time, bool timeDependent) { +bool LOP_RPRExportHelper::SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, bool timeDependent) { if (auto exportPathAttr = prim->CreateAttribute(name, sdfType, true)) { auto timeCode = timeDependent ? HUSDgetCurrentUsdTimeCode() : UsdTimeCode::Default(); if (exportPathAttr.Set(value, timeCode)) { @@ -98,7 +101,6 @@ OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { }; auto exportPathParm = getParm(g_exportPathName.getToken()); - auto exportAsSingleFileParm = getParm(g_exportPathAsSingleFileName.getToken()); UT_String exportPath; exportPathParm->getValue(context.getTime(), exportPath, 0, true, context.getThread()); @@ -112,9 +114,8 @@ OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { exportPath += ".rpr"; } - int exportAsSingleFileInt; - exportAsSingleFileParm->getValue(context.getTime(), exportAsSingleFileInt, 0, context.getThread()); - bool exportAsSingleFile = bool(exportAsSingleFileInt); + bool exportAsSingleFile = bool(evalInt(g_exportAsSingleFileName.getToken(), 0, context.getTime())); + bool exportUseImageCache = bool(evalInt(g_exportUseImageCacheName.getToken(), 0, context.getTime())); UT_String renderSettingsPath; evalString(renderSettingsPath, g_renderSettingsName.getToken(), 0, context.getTime()); @@ -129,8 +130,9 @@ OP_ERROR LOP_RPRExportHelper::cookMyLop(OP_Context &context) { auto modifyRenderSettings = [&](UsdRenderSettings& renderSettings) { auto prim = renderSettings.GetPrim(); - return SetRenderSetting(&prim, _tokens->rprExportPath, SdfValueTypeNames->String, exportPath.toStdString(), context.getTime(), exportPathParm->isTimeDependent()) && - SetRenderSetting(&prim, _tokens->rprExportAsSingleFile, SdfValueTypeNames->Bool, exportAsSingleFile, context.getTime(), exportAsSingleFileParm->isTimeDependent()); + return SetRenderSetting(&prim, _tokens->rprExportPath, SdfValueTypeNames->String, exportPath.toStdString(), exportPathParm->isTimeDependent()) && + SetRenderSetting(&prim, _tokens->rprExportAsSingleFile, SdfValueTypeNames->Bool, exportAsSingleFile, false) && + SetRenderSetting(&prim, _tokens->rprExportUseImageCache, SdfValueTypeNames->Bool, exportUseImageCache, false); }; // Use explicitly specified render settings primitive if any diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h index 784a4f368..50122d9d6 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRExportHelper.h @@ -35,7 +35,7 @@ class LOP_RPRExportHelper : public LOP_Node { private: template - bool SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, double time, bool timeDependent); + bool SetRenderSetting(UsdPrim* prim, TfToken const& name, SdfValueTypeName const& sdfType, T const& value, bool timeDependent); }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda index b132bcb2b24e2e66301acc91abf49cd557378f18..2bacd0f33a83e2b40f73f26013e5aa319da5b23c 100644 GIT binary patch delta 2694 zcmaKuc|6p67sqEXkA2^+wV!=WLe{G+*~%6}mQrK>C$3 z80;L&$JMfYsytLfQP`9ffj}U9)_4#>1l^H%R2UHg5jKTDp!%#F6$O-b^jr)u^1wVArf?gq9G88 z0SJVX^ee^b3E~MTECvFRw_sN6i)C6)2P78b?rFyi+fWtQq}hNWsyW*MZbzo3{nBQT zZ4TB<;XeUww&b?pXdV!7W)lOLCkT%vg(0zMG$M?E@<)SI3cHwIAQl|};&l~ySOn{! z5&j^WX%#I4!VwrG7y!6~L?Q|kL{Q|}ho}lLQK~7I2K5}5wj`^97!?NYTWnAe8vMzu z3yD(exCE&r0YT~zr#jObQ}1$$P&Ht@2o{S$gzncUk_ezfC?W{7Mj(U1|Egdy|54&W z0D*l7_#f2&`};b(C>cPp+5<>de;@)y3!GdaOMR8B8n*r z58_BDJoDN_EP%v@hA}yS2u2b~cqR}3`SB}(ATrkjpa=j02nX>|`}GHz+aZub_uC-| zAv*qmI~E8)5fIFQ11KU85e#C0C@cv;_!F>b5)nj40fhbDPKXeYDFwtZZ;Qn+!+}^l zU`s-y0d+T5H$YEESA!`I!`v2tBO%ZzVwBF$c~Nl!qW=t;k2Sd1{T;;eH2)?{gOSIi z_gtop?~d%@Gl)Ovd$S&9{FQZ&9kwaX)GPe0<)ONyFf&wfyu%Aa#SEosunhHM$9x)P zRaB`vh4Xbyo8Nl3v_+fI-~Db^f!O+-8Qo|e)A6#t>uZ4P`!5|=<`M6sx5qSe?r1HYPCKH8}k&i6=yfo!gfvBAS+$%vzx8LTmAHY z`?x^$K)Q*4k3wNwi@*6*;?>^cZhLwh4jP#jiP4>J-kcC*)VnDr$|q+-i1}n^p&AGK zcIk|YVdLaXg(B6%O6BrAcuQ-=l#9?+cW3cZj^4xbjmml%Rnezg#SGv*Su`iR)QA4= z1*w{R* zfPWO!zTBrQ<iE{<<%ri$ZRU_`Dvr)=R$lHS=S|_yC>!y0d4#Vyn-t zE|=dmvD%Dx=-|A@mot|O+mBqTc2BIH@Xhg)x!#t6YiM>Vor-5|rY2tx zISQX#q1t__Kwta^vdcqDKOuX|d#BjAvZ^h3mBr^KuJsrD1~i>7HW<`PI7|r;uV~68 zm^~({H{a&_<_JqFSkin6hXzhE7_VS*?~1>{yi}A-JOP!g9^kiI)P^pPYvjMC2E%P) z8!%E}UQ!X{nW3 zv=;kw`^X9DQHq(yFh!u(ZMLa+AjELQ^oe+(5H?blEjL@^t*@&j|igKT9r&~hX4Vm=%D28N73Sm;Bo}Q;i7CdzUKE%9XIC8vifUzLsV;O@kG zw$MuHx;-x-yY+r-{!f>-HDJKgx32FTY)SCexiho6fPM#He=gN&&wn3a3oo5TU<$ z!jq(DQT@D;4SBi9%M$U%V5~f#x4r--J^$V#$J+|U2ySxqi+pa9Z7h#hAL7W?=3ed; za$pQt93$uBbrU{Ap%hS38|M33YY} zT?sF{=-)9C`WE#(aPB8^6Dk|IrJ3DHXS?$rHg&^_%L8J^{`lJy{h001wRR(Kt}V1^ z6K~KM@2d{((3*bx6$LLo93(a&F|462)AO^{r?{tN{%gz2`Rn{W2GjcI?|tL=L?36< z50<%6tWYe`bz>Q6Zv#)SnL87j+F^LgZI>^*s&-661~tM{U~jM4d)sP#a6ORg&k0w7 zZx0f=#1EG(Oy2O<;`zJv&b{-$h8ZX7dKKLSb`sJ zeK>a9;AWBwLrXur^{9xTJHxhi;T+zmYCPNZTfsVc!$*7mld1CB)%-GUlQfi+(nue0 zvvZm!hs`qgD9BNMizdtMN787|8PN?qK3+Dt(&nR8-&lXP?jYQBE4)0J_wgKAU{pmA z+cpUWeMxHVM;bP_zpL~yPChh@^hS~xACBZy&>7#SyXZZa1Z93e540Rz15}t#HRg-# S@bAs83Z^h9v^h=H0{UfD^01mbQ00A>!#!-KhX#pEK59t5^0WM$0QGWmc00c;7Y;XVo z5f=ae003XcQGWmc01H%aZ)|feb7*C3W&i*Y7XSbQ0AI#YVw1fA8A}uw0000mU&c{? z0000BLvL<$Wo~qHE@yfG02D_601BR8#!-I&000M8WpZXRV?8Ui75lRW|-5%B;30d-%-QGX*KL}_7cZ)cO<6C1OL0>1^5 znGhV4yAKJI!Vn*mYm|iV`Dp-^GlGhY5)C0|#XAr*8qi7lnVDdmo3PDB4a4kVq=EI0}Q|q2=B>*vP%OP6<)ZEKXY}4#O6ht+$^S?p-mUe zU$F2D&xx(KzqcRSj+d!W(3V6I62=^F8mfr@bOf2&Nf^pW70}H?J7kzaJ3>}KxFXcP z(jRL2{y=|+I#84|xtDdiX7mlH!wWW}0h)y~e7kV*-#?$8?H=my-@iZj{rKeMfKyl& zA0|xT00fAkqN_{uohXdoA0nkYOn%!i6`>V4zL;6iL*Qa>y1-KcB1C-~a5uFoEoIWR z*s2yG3Ha=^;PXrCFQ#dJ0{wtpK?$n<)cQr;m@$7VeJyn*zoo*2D5#G#_-mSHBXjim z?09UR9bbMPjej=}NB=NQ)HxZCK8~&~&#x{!jTMkOwH`b5o-{Beq_gr}g5* zh}D0dmNz3G2lLkV_MLQLjw;fzV}INF11VeFK*F~Q`sdd6ma?_e7HV;b4Ms5!3lyC% zF7<`7Mf>)3r+eM`6)8JkI>7tTbSQetWT^R}JQ^#{N$mQBnibY8aR`^IBXbpp+Q~8*-6MgAc+BNU2uEM>7%{9xXiFuS0rj&nKGU?}$gb;Ya}}1S;yKR= zRjv2aFZt>%^eW8f(G_16&*LFp*YbZ$KS;NFn+oy$9{e%jxA$BzJ~Df?XQ)brsf7@^ z2#;Re=6LYrNq>!5l^Jr+~^~;xkp9&x)@jh)?CX}K4BN))=9uQ$62NoWlrjdyI?qAd&i!= zcj{T|i-HITZ_YXb&jSL=b@$F`$V8!uTRGF};(_Z*C5Py<0|^yIGIc=b z0p)RPZAc8?u7cw$7k-)HSy6u=M0Fpsr8+V{jLy+{hIU0+^6dlxvyQZpAVyagM=7=A z-8rFir|I@rHg0X4nVLzPFTGMb*pl$k6kEKJtPJ%n^u7U!c7MNC) z4irs)MC7YEEcC>ZewRV!3nWF~>!z{rN6oWc^8Bwj$w9Yg%AAZv_}W zW*?RhE=(Se&}G1~U7CM_Me7tn#8F@r%T7qp&{Cp<3bDk)FdZdwD+gNu zb}YIm@1bB0%b$k^xcOrv)N*zaUy_%1QwVO)GA_PVvx#wCLO*}cJSDIcfN;Fn2>egH zqi4oHaVcgmYy=OfZ%4)G-_y}uZn&%%)(cFlE}VQwiN%|$<}z|OPHKhV&7~GE1&7-V z2>K9hplxmw0|1HTc3nJj7vl%a&kI1|Hi7XY=7xr>J{}bQOQDztcrR3;V>*Zd0Y(xV(_o ziz8b2aKrVcNp-xk{LXKAq^Thn$?%j{%Z$ymup+CKXEW->e9f;o#Yeol zI;cA0E#9b@sO#ULh)4exsZmX>I~5{_=S=XEyI(O;v-c^MaB7>tsTs;TNP$iK=Fw_Z zXrq(5=e~cOB7|09lE-7u3rWhXoKyWp*`8jBQ=Ysv@RW6Q7fXEtRRh0hfU45+qxP3I zvk|5$%-N%!#>g+kI|3T7JJ+4HR9$sjsuX>)PyTX%Cy+LLJ1)6VW$2Z!xY9duA~2R- zX_GCPdu-8FkJ3xbg)11PRLi#^N(p3KECCcXs1kqAq=aIk%2p_8TdEQj^@K&*dKqIB zPqt#7$dhx=Nl&?R|Kg2p$X)nQ@NKcpv=#v5 z(dpT#d3pTt+&nrR@4X%$pB){KPmdyx0rtux>{Yr;W)ixrzDyaDM7J5UPFpe$If6a8 z)XIN3do%}2N5REgl`?Ww=%Nc{?Ag+dw|NCbz&A^I?wg&R1ZC!!x6pYEzs|@(}U3x ztDH=@$o$!5fe^A~AWI@u$wZ}X`*JpNM}&V>9#M4)S2B>YGquuyv2-$4Xjd~bqb=eR zVd>^?74k<2c(YsG9^D^|q=>ljh>(i*SVnpCvWR%wsZvHYffQ2No|E!~zN#s>_wh@P z9^2mO!mH{dwHGddvgH!&E&S~_Q3P3XaqgRMc4B-L9ZRq0Q=Z#HsdR;CgQK!t?m>T4 zjd5vzpt6U|GQN^(=^#~o#K`55XOSYplb$b@kfa1W%_$Pd<$FRDABjEMQ+n=Hj=J<* zygYeGBXP<1p8yQ#(Zv?wVK%^DOYZ9PaC?3I`h1OdC?w?4C@AVLKJHnZj>Kmi7mm4N^N diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_standard_rendervars.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_standard_rendervars.hda index f95e261fc7a7f35eb219d3d4e1a4cc8b20e48f25..665cc51ee10a434f51d17b41e1b828c7eebd255c 100644 GIT binary patch delta 13951 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�~U*;fWrRMMw;I>8`D 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 delta 12628 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 S4KP29d*vuyeQ0Bd{eJ*K431F% From 274aed918d7fd8792b8235d57910522eaeb9d19d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 4 Dec 2020 00:42:19 +0200 Subject: [PATCH 27/32] Configure Houdini plugin for automatic renderer restart (#419) PURPOSE To improve UX. When the user changes such render qualities as renderQuality and renderDevice, we need to resync the scene because changing these settings requires RPR context recreation. Previously, the user had to do it manually through Houdini UI. EFFECT OF CHANGE No more need to restart render manually when changing render quality. --- pxr/imaging/plugin/rprHoudini/CMakeLists.txt | 1 + pxr/imaging/plugin/rprHoudini/UsdRenderers.json | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 pxr/imaging/plugin/rprHoudini/UsdRenderers.json diff --git a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt index 6d185deff..b3b94121f 100644 --- a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt +++ b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt @@ -52,5 +52,6 @@ install( install( FILES ui/MainMenuCommon.xml + UsdRenderers.json DESTINATION houdini) diff --git a/pxr/imaging/plugin/rprHoudini/UsdRenderers.json b/pxr/imaging/plugin/rprHoudini/UsdRenderers.json new file mode 100644 index 000000000..77e42526a --- /dev/null +++ b/pxr/imaging/plugin/rprHoudini/UsdRenderers.json @@ -0,0 +1,8 @@ +{ + "HdRprPlugin" : { + "valid" : true, + "menulabel" : "RPR", + "menupriority" : 0, + "restartrendersettings" : ["renderQuality", "renderDevice"] + } +} From 89c9f4f390ec1f0861a55bf406ceabc0d00c07de Mon Sep 17 00:00:00 2001 From: radeonprorender Date: Thu, 3 Dec 2020 23:44:24 +0100 Subject: [PATCH 28/32] buildmaster: version update to 2.0.12 --- 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 65666444c..9bd00218e 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 "11") +set(HD_RPR_PATCH_VERSION "12") From b307bd44bc6764b5db241bceb013de582ecd0fd1 Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 4 Dec 2020 21:11:15 +0200 Subject: [PATCH 29/32] Fix compilation for USD 19.11 (#421) --- pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp index b1ed1a037..06e3c5f02 100644 --- a/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp +++ b/pxr/imaging/plugin/rprHoudini/LOP_RPRMaterialProperties.cpp @@ -90,7 +90,7 @@ OP_ERROR LOP_RPRMaterialProperties::cookMyLop(OP_Context &context) { UsdShadeMaterial material(materialPrim); if (!material) { - addError(LOP_MESSAGE, TfStringPrintf("Specified path does not point to a material: %s", materialPrim.GetPrimTypeInfo().GetTypeName().GetText()).c_str()); + addError(LOP_MESSAGE, TfStringPrintf("Specified path does not point to a material: %s", materialPath.c_str()).c_str()); return error(); } From ffabb097ff178793f2ab2b104ab232c2e785418d Mon Sep 17 00:00:00 2001 From: George Shakula Date: Fri, 4 Dec 2020 21:11:37 +0200 Subject: [PATCH 30/32] Fix .json config exported with .rpr (#420) * Fix AOV names * Fix contour debug type - from bool to int --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 17 ++++++++++++----- .../plugin/rprHoudini/hda/rpr_exportRpr1.hda | Bin 10022 -> 10570 bytes 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 1baa648db..51e7fdea9 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2537,11 +2537,11 @@ Don't show this message again? /* RPR_AOV_WORLD_COORDINATE = */ "world.coordinate", /* RPR_AOV_UV = */ "uv", /* RPR_AOV_MATERIAL_ID = */ "material.id", - /* RPR_AOV_GEOMETRIC_NORMAL = */ "geometric.normal", - /* RPR_AOV_SHADING_NORMAL = */ "shading.normal", + /* RPR_AOV_GEOMETRIC_NORMAL = */ "normal.geom", + /* RPR_AOV_SHADING_NORMAL = */ "normal", /* RPR_AOV_DEPTH = */ "depth", /* RPR_AOV_OBJECT_ID = */ "object.id", - /* RPR_AOV_OBJECT_GROUP_ID = */ "object.group.id", + /* RPR_AOV_OBJECT_GROUP_ID = */ "group.id", /* RPR_AOV_SHADOW_CATCHER = */ "shadow.catcher", /* RPR_AOV_BACKGROUND = */ "background", /* RPR_AOV_EMISSION = */ "emission", @@ -2559,7 +2559,7 @@ Don't show this message again? /* RPR_AOV_LIGHT_GROUP1 = */ "light.group1", /* RPR_AOV_LIGHT_GROUP2 = */ "light.group2", /* RPR_AOV_LIGHT_GROUP3 = */ "light.group3", - /* RPR_AOV_DIFFUSE_ALBEDO = */ "diffuse.albedo", + /* RPR_AOV_DIFFUSE_ALBEDO = */ "albedo.diffuse", /* RPR_AOV_VARIANCE = */ "variance", /* RPR_AOV_VIEW_SHADING_NORMAL = */ "view.shading.normal", /* RPR_AOV_REFLECTION_CATCHER = */ "reflection.catcher", @@ -2573,6 +2573,13 @@ Don't show this message again? /* RPR_AOV_LPE_6 = */ "lpe6", /* RPR_AOV_LPE_7 = */ "lpe7", /* RPR_AOV_LPE_8 = */ "lpe8", + /* RPR_AOV_CAMERA_NORMAL = */ "camera.normal", + /* RPR_AOV_CRYPTOMATTE_MAT0 = */ "CryptoMaterial00", + /* RPR_AOV_CRYPTOMATTE_MAT1 = */ "CryptoMaterial01", + /* RPR_AOV_CRYPTOMATTE_MAT2 = */ "CryptoMaterial02", + /* RPR_AOV_CRYPTOMATTE_OBJ0 = */ "CryptoObject00", + /* RPR_AOV_CRYPTOMATTE_OBJ1 = */ "CryptoObject01", + /* RPR_AOV_CRYPTOMATTE_OBJ2 = */ "CryptoObject02", }; static const size_t kNumRprsAovNames = sizeof(kRprsAovNames) / sizeof(kRprsAovNames[0]); @@ -2628,7 +2635,7 @@ Don't show this message again? contour["linewidth.matid"] = rprConfig->GetContourLinewidthMaterialId(); contour["linewidth.normal"] = rprConfig->GetContourLinewidthNormal(); contour["antialiasing"] = rprConfig->GetContourAntialiasing(); - contour["debug"] = rprConfig->GetContourDebug(); + contour["debug"] = int(rprConfig->GetContourDebug()); config["contour"] = contour; } diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_exportRpr1.hda index 2bacd0f33a83e2b40f73f26013e5aa319da5b23c..9b011440092556b0709bc7244c8faca1d2b5721b 100644 GIT binary patch delta 3003 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 Date: Fri, 4 Dec 2020 20:14:02 +0100 Subject: [PATCH 31/32] buildmaster: version update to 2.0.13 --- 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 9bd00218e..cc30f1035 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 "12") +set(HD_RPR_PATCH_VERSION "13") From f9d62dd652c9f538042a954655eea816e5948a0e Mon Sep 17 00:00:00 2001 From: bsavery Date: Mon, 7 Dec 2020 10:26:15 -0800 Subject: [PATCH 32/32] Update CHANGELOG.MD --- CHANGELOG.MD | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index eb5682c02..cd877d48c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,21 @@ # Change Log +## Version 2.0.13 +- Improved interactivity with Interactive Renders. +- Some issues with texture compression present in version 3.0.1 are fixed. +- Issues with normal maps (related to texture compression) are also fixed. +- Fixed issues with .rpr file export: + - Fixed the AOV names in config.json file. + - Fixed the contour rendering option in config.json file + - Export of .rpr file is made faster and textures are reused between animation frames. +- Users no longer need to manually restart the render when switching render mode in Houdini. +- Time-to-first-pixel is made faster when not using denoisers. +- Added an ID parameter to Render Geometry Settings Node in Houdini for setting an explicit Object ID. +- Add a Houdini Node RPR Material Properties for explicitly setting the Material ID to be used in the corresponding AOV. +- Single and two-channel textures are handled correctly now. +- Fixed USDPreviewSurface Normal Maps. + + ## Version 2.0 ### New Features: - The new plug-in version incorporates version 2.0 of our Radeon™ ProRender system and brings about the significant changes and enhancements: