Skip to content

Commit

Permalink
Fixing bugs and adding missing features for motion blurred instancers. (
Browse files Browse the repository at this point in the history
#666)

Fixes #653
  • Loading branch information
sirpalee authored Feb 18, 2021
1 parent 1ad3542 commit e2465ba
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 10 deletions.
2 changes: 2 additions & 0 deletions render_delegate/constant_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ ASTR(indirect_sample_clamp);
ASTR(input);
ASTR(instance_inherit_xform);
ASTR(instance_matrix);
ASTR(instance_motion_end);
ASTR(instance_motion_start);
ASTR(instance_shader);
ASTR(instance_visibility);
ASTR(instancer);
Expand Down
18 changes: 16 additions & 2 deletions render_delegate/render_delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens,
(openvdbAsset)
((arnoldGlobal, "arnold:global:"))
(percentDone)
(instantaneousShutter)
);
// clang-format on

Expand Down Expand Up @@ -446,6 +447,8 @@ void HdArnoldRenderDelegate::_SetRenderSetting(const TfToken& _key, const VtValu
if (value.IsHolding<std::string>()) {
AiProfileSetFileName(value.UncheckedGet<std::string>().c_str());
}
} else if (key == _tokens->instantaneousShutter) {
_CheckForBoolValue(value, [&](const bool b) { AiNodeSetBool(_options, str::ignore_motion_blur, b); });
} else {
auto* optionsEntry = AiNodeGetNodeEntry(_options);
// Sometimes the Render Delegate receives parameters that don't exist
Expand Down Expand Up @@ -864,12 +867,23 @@ void HdArnoldRenderDelegate::ApplyLightLinking(AtNode* shape, const VtArray<TfTo
}
}

bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex)
bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex, float shutterOpen, float shutterClose)
{
HdDirtyBits bits = HdChangeTracker::Clean;
// If Light Linking have changed, we have to dirty the categories on all rprims to force updating the
// the light linking information.
if (_lightLinkingChanged.exchange(false, std::memory_order_acq_rel)) {
renderIndex->GetChangeTracker().MarkAllRprimsDirty(HdChangeTracker::DirtyCategories);
bits |= HdChangeTracker::DirtyCategories;
}
// When shutter open and shutter close significantly changes, we might not have enough samples for transformation
// and deformation, so we need to force re-syncing all the prims.
if (_shutterOpen != shutterOpen || _shutterClose != shutterClose) {
_shutterOpen = shutterOpen;
_shutterClose = shutterClose;
bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyTransform | HdChangeTracker::DirtyInstancer;
}
if (bits != HdChangeTracker::Clean) {
renderIndex->GetChangeTracker().MarkAllRprimsDirty(bits);
return true;
}
return false;
Expand Down
6 changes: 5 additions & 1 deletion render_delegate/render_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,10 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
/// before the next iteration.
///
/// @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 should be skipped.
bool ShouldSkipIteration(HdRenderIndex* renderIndex);
bool ShouldSkipIteration(HdRenderIndex* renderIndex, float shutterOpen, float shutterClose);

private:
HdArnoldRenderDelegate(const HdArnoldRenderDelegate&) = delete;
Expand Down Expand Up @@ -322,6 +324,8 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
AtNode* _fallbackVolumeShader; ///< Pointer to the fallback Arnold Volume Shader.
std::string _logFile;
int _verbosityLogFlags = AI_LOG_WARNINGS | AI_LOG_ERRORS;
float _shutterOpen = 0.0f; ///< Saved Shutter Open value of the active camera.
float _shutterClose = 0.0f; ///< Saved Shutter Close value of the active camera.
bool _ignoreVerbosityLogFlags = false;
};

Expand Down
11 changes: 8 additions & 3 deletions render_delegate/render_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,19 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
static_cast<const AtNode*>(AiNodeGetPtr(AiUniverseGetOptions(_renderDelegate->GetUniverse()), str::camera));
const auto* camera = reinterpret_cast<const HdArnoldCamera*>(renderPassState->GetCamera());
const auto useOwnedCamera = camera == nullptr;
AtNode* currentCamera = nullptr;
// If camera is nullptr from the render pass state, we are using a camera created by the renderpass.
if (useOwnedCamera) {
currentCamera = _camera;
if (currentUniverseCamera != _camera) {
renderParam->Interrupt();
AiNodeSetPtr(AiUniverseGetOptions(_renderDelegate->GetUniverse()), str::camera, _camera);
}
} else {
if (currentUniverseCamera != camera->GetCamera()) {
currentCamera = camera->GetCamera();
if (currentUniverseCamera != currentCamera) {
renderParam->Interrupt();
AiNodeSetPtr(AiUniverseGetOptions(_renderDelegate->GetUniverse()), str::camera, camera->GetCamera());
AiNodeSetPtr(AiUniverseGetOptions(_renderDelegate->GetUniverse()), str::camera, currentCamera);
}
}

Expand Down Expand Up @@ -627,7 +630,9 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt

// We skip an iteration step if the render delegate tells us to do so, this is the easiest way to force
// a sync step before calling the render function. Currently, this is used to trigger light linking updates.
const auto renderStatus = _renderDelegate->ShouldSkipIteration(GetRenderIndex())
const auto renderStatus = _renderDelegate->ShouldSkipIteration(
GetRenderIndex(), AiNodeGetFlt(currentCamera, str::shutter_start),
AiNodeGetFlt(currentCamera, str::shutter_end))
? HdArnoldRenderParam::Status::Converging
: renderParam->Render();
_isConverged = renderStatus != HdArnoldRenderParam::Status::Converging;
Expand Down
2 changes: 2 additions & 0 deletions render_delegate/rprim.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ class HdArnoldRprim : public HydraType {
HdDirtyBits dirtyBits, HdSceneDelegate* sceneDelegate, HdArnoldRenderParam* param, bool force = false)
{
#if PXR_VERSION >= 2102
// Newer USD versions need to update the instancer before accessing the instancer id.
HydraType::_UpdateInstancer(sceneDelegate, &dirtyBits);
// We also force syncing of the parent instancers.
HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), HydraType::GetInstancerId());
#endif
_shape.Sync(this, dirtyBits, _renderDelegate, sceneDelegate, param, force);
Expand Down
14 changes: 10 additions & 4 deletions render_delegate/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,18 @@ void HdArnoldShape::_SyncInstances(
convertMatrices(sample);
}
}
auto setMotionParam = [&](const char* name, float value) {
if (AiNodeLookUpUserParameter(_instancer, name) == nullptr) {
AiNodeDeclare(_instancer, name, "CONSTANT ARRAY FLOAT");
}
AiNodeSetArray(_instancer, name, AiArray(1, 1, AI_TYPE_FLOAT, value));
};
if (sampleCount > 1) {
AiNodeSetFlt(_instancer, str::motion_start, instanceMatrices.times.front());
AiNodeSetFlt(_instancer, str::motion_end, instanceMatrices.times.back());
setMotionParam(str::instance_motion_start, instanceMatrices.times.front());
setMotionParam(str::instance_motion_end, instanceMatrices.times[sampleCount - 1]);
} else {
AiNodeResetParameter(_instancer, str::motion_start);
AiNodeResetParameter(_instancer, str::motion_end);
setMotionParam(str::instance_motion_start, 0.0f);
setMotionParam(str::instance_motion_end, 1.0f);
}
AiArrayUnmap(matrixArray);
AiNodeSetArray(_instancer, str::instance_matrix, matrixArray);
Expand Down
8 changes: 8 additions & 0 deletions render_delegate/volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <pxr/base/tf/dl.h>

#include <pxr/imaging/hd/changeTracker.h>
#include <pxr/imaging/hd/instancer.h>

#include <pxr/usd/sdf/assetPath.h>

Expand Down Expand Up @@ -240,6 +241,13 @@ void HdArnoldVolume::Sync(
_ForEachVolume([&](HdArnoldShape* s) { s->SetVisibility(visibility); });
}

#if PXR_VERSION >= 2102
// Newer USD versions need to update the instancer before accessing the instancer id.
_UpdateInstancer(sceneDelegate, dirtyBits);
// We also force syncing of the parent instancers.
HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), GetInstancerId());
#endif

_ForEachVolume([&](HdArnoldShape* shape) {
shape->Sync(this, *dirtyBits, _renderDelegate, sceneDelegate, param, transformDirtied);
});
Expand Down

0 comments on commit e2465ba

Please sign in to comment.