diff --git a/CHANGELOG.md b/CHANGELOG.md index a8153d3f2..0252e417e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ <!-- SPDX-License-Identifier: Apache-2.0 --> # Changelog -## Pending feature release +## Pending Feature release ### Feature - [usd#2119](https://github.com/Autodesk/arnold-usd/issues/2119) - Support options shader_override attribute @@ -15,7 +15,7 @@ - [usd#2133](https://github.com/Autodesk/arnold-usd/issues/2133) - Fixed crash when the root primitive is invalid - [usd#2122](https://github.com/Autodesk/arnold-usd/issues/2122) - RectLight doesn't take width / height into account with scenes exported from Arnold - [usd#1764](https://github.com/Autodesk/arnold-usd/issues/1764) - ArnoldUsd schema was missing from Arnold SDK - +- [usd#2154](https://github.com/Autodesk/arnold-usd/issues/2154) - Husk renders can miss scene updates ## [7.3.5.0] - 2024-11-08 diff --git a/libs/render_delegate/reader.cpp b/libs/render_delegate/reader.cpp index 8a61b18f8..73f932cce 100644 --- a/libs/render_delegate/reader.cpp +++ b/libs/render_delegate/reader.cpp @@ -223,8 +223,8 @@ void HydraArnoldReader::ReadStage(UsdStageRefPtr stage, arnoldRenderDelegate->SetRenderTags(purpose); // The scene might not be up to date, because of light links, etc, that were generated during the first sync. - // UpdateSceneChanges updates the dirtybits for a resync, this is how it works in our hydra render pass. - while (arnoldRenderDelegate->UpdateSceneChanges(_renderIndex, _shutter)) { + // HasPendingChanges updates the dirtybits for a resync, this is how it works in our hydra render pass. + while (arnoldRenderDelegate->HasPendingChanges(_renderIndex, _shutter)) { _renderIndex->SyncAll(&_tasks, &_taskContext); } } @@ -251,7 +251,7 @@ void HydraArnoldReader::Update() { HdArnoldRenderDelegate *arnoldRenderDelegate = static_cast<HdArnoldRenderDelegate*>(_renderDelegate); _imagingDelegate->ApplyPendingUpdates(); - arnoldRenderDelegate->UpdateSceneChanges(_renderIndex, _shutter); + arnoldRenderDelegate->HasPendingChanges(_renderIndex, _shutter); _renderIndex->SyncAll(&_tasks, &_taskContext); } diff --git a/libs/render_delegate/render_delegate.cpp b/libs/render_delegate/render_delegate.cpp index 843af043b..6deec42da 100644 --- a/libs/render_delegate/render_delegate.cpp +++ b/libs/render_delegate/render_delegate.cpp @@ -460,7 +460,8 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(bool isBatch, const TfToken &cont _context(context), _universe(universe), _procParent(nullptr), - _renderDelegateOwnsUniverse(universe==nullptr) + _renderDelegateOwnsUniverse(universe==nullptr), + _renderSessionType(renderSessionType) { _lightLinkingChanged.store(false, std::memory_order_release); @@ -485,7 +486,7 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(bool isBatch, const TfToken &cont AiADPAddProductMetadata(AI_ADP_PLUGINVERSION, AtString{AI_VERSION}); AiADPAddProductMetadata(AI_ADP_HOSTNAME, AtString{"Hydra"}); AiADPAddProductMetadata(AI_ADP_HOSTVERSION, AtString{PXR_VERSION_STR}); - AiBegin(renderSessionType); + AiBegin(_renderSessionType); } _supportedRprimTypes = {HdPrimTypeTokens->mesh, HdPrimTypeTokens->volume, HdPrimTypeTokens->points, HdPrimTypeTokens->basisCurves, str::t_procedural_custom}; @@ -563,7 +564,7 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(bool isBatch, const TfToken &cont if (_renderDelegateOwnsUniverse) { _universe = AiUniverse(); - _renderSession = AiRenderSession(_universe, renderSessionType); + _renderSession = AiRenderSession(_universe, _renderSessionType); } _renderParam.reset(new HdArnoldRenderParam(this)); @@ -1532,14 +1533,15 @@ void HdArnoldRenderDelegate::ProcessConnections() bool HdArnoldRenderDelegate::CanUpdateScene() { // For interactive renders, it is always possible to update the scene - if (!_isBatch) + if (_renderSessionType == AI_SESSION_INTERACTIVE) return true; // For batch renders, only update the scene if the render hasn't started yet, // or if it's finished const int status = AiRenderGetStatus(_renderSession); return status != AI_RENDER_STATUS_RESTARTING && status != AI_RENDER_STATUS_RENDERING; } -bool HdArnoldRenderDelegate::UpdateSceneChanges(HdRenderIndex* renderIndex, const GfVec2f& shutter) + +bool HdArnoldRenderDelegate::HasPendingChanges(HdRenderIndex* renderIndex, const GfVec2f& shutter) { HdDirtyBits bits = HdChangeTracker::Clean; // If Light Linking have changed, we have to dirty the categories on all rprims to force updating the diff --git a/libs/render_delegate/render_delegate.h b/libs/render_delegate/render_delegate.h index a4b5de7db..e3eedd9d0 100644 --- a/libs/render_delegate/render_delegate.h +++ b/libs/render_delegate/render_delegate.h @@ -327,15 +327,15 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate { HDARNOLD_API void ApplyLightLinking(HdSceneDelegate *delegate, AtNode* node, SdfPath const& id); - /// Updates the eventual changes that happened in the input scene - /// since the last iteration. + /// Eventually mark some hydra primitives as being dirty + /// in which case we'll have another sync iteration pending /// /// @param renderIndex Pointer to the Hydra Render Index. /// @param shutterOpen Shutter Open value of the active camera. /// @param shutterClose Shutter Close value of the active camera. - /// @return True if the iteration contains scene changes. + /// @return True if hydra has pending changes. HDARNOLD_API - bool UpdateSceneChanges(HdRenderIndex* renderIndex, const GfVec2f& shutter); + bool HasPendingChanges(HdRenderIndex* renderIndex, const GfVec2f& shutter); /// Returns whether the Arnold scene can be updated or /// if Hydra changes should be ignored. @@ -728,6 +728,7 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate { AtNode* _fallbackShader = nullptr; ///< Pointer to the fallback Arnold Shader. AtNode* _fallbackVolumeShader = nullptr; ///< Pointer to the fallback Arnold Volume Shader. AtNode* _procParent = nullptr; + AtSessionMode _renderSessionType = AI_SESSION_INTERACTIVE; std::string _logFile; std::string _statsFile; AtStatsMode _statsMode; diff --git a/libs/render_delegate/render_pass.cpp b/libs/render_delegate/render_pass.cpp index 6b1201f73..8b3eb653e 100644 --- a/libs/render_delegate/render_pass.cpp +++ b/libs/render_delegate/render_pass.cpp @@ -970,10 +970,16 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt clearBuffers(_renderBuffers); } - _renderDelegate->UpdateSceneChanges( + // Check if hydra still has pending changes that will be processed in the next iteration. + bool hasPendingChanges = _renderDelegate->HasPendingChanges( GetRenderIndex(), {AiNodeGetFlt(currentCamera, str::shutter_start), AiNodeGetFlt(currentCamera, str::shutter_end)}); - const auto renderStatus = renderParam->UpdateRender(); + + // If we still have pending Hydra changes, we don't want to start / update the render just yet, + // as we'll receive shortly another sync. In particular in the case of batch renders, this prevents + // from rendering the final scene #2154 + const auto renderStatus = hasPendingChanges ? + HdArnoldRenderParam::Status::Converging : renderParam->UpdateRender(); _isConverged = renderStatus != HdArnoldRenderParam::Status::Converging; // We need to set the converged status of the render buffers.