diff --git a/third_party/renderman-25/plugin/hdPrman/CMakeLists.txt b/third_party/renderman-25/plugin/hdPrman/CMakeLists.txt index d89be46b48..7ecd3ae3ab 100644 --- a/third_party/renderman-25/plugin/hdPrman/CMakeLists.txt +++ b/third_party/renderman-25/plugin/hdPrman/CMakeLists.txt @@ -125,7 +125,7 @@ pxr_plugin(${PXR_PACKAGE} rileyRenderTargetPrim terminalSceneIndexObserver utils - velocityMotionBlurSceneIndexPlugin + motionBlurSceneIndexPlugin virtualStructResolvingSceneIndex PUBLIC_HEADERS diff --git a/third_party/renderman-25/plugin/hdPrman/basisCurves.cpp b/third_party/renderman-25/plugin/hdPrman/basisCurves.cpp index 0ffdab033f..15f4ee6edf 100644 --- a/third_party/renderman-25/plugin/hdPrman/basisCurves.cpp +++ b/third_party/renderman-25/plugin/hdPrman/basisCurves.cpp @@ -28,13 +28,8 @@ #include "hdPrman/material.h" #include "hdPrman/rixStrings.h" #include "pxr/imaging/hd/basisCurvesTopology.h" -#include "pxr/base/gf/matrix4f.h" -#include "pxr/base/gf/matrix4d.h" -#include "Riley.h" #include "RiTypesHelper.h" -#include "RixShadingUtils.h" -#include "RixPredefinedStrings.hpp" PXR_NAMESPACE_OPEN_SCOPE @@ -150,18 +145,12 @@ HdPrman_BasisCurves::_ConvertGeometry(HdPrman_RenderParam *renderParam, // Points float primvarTime = 0.0f; - if( HdPrman_RenderParam::HasSceneIndexPlugin( - HdPrmanPluginTokens->velocityBlur) ) { - HdPrman_ConvertPointsPrimvar( - sceneDelegate, - id, - renderParam->GetShutterInterval(), - primvars, - vertexPrimvarCount); - } else { - primvarTime = renderParam->ConvertPositions( - sceneDelegate, id, vertexPrimvarCount, primvars); - } + HdPrman_ConvertPointsPrimvar( + sceneDelegate, + id, + renderParam->GetShutterInterval(), + primvars, + vertexPrimvarCount); // Set element ID. Overloaded use of "__faceIndex" to support picking... std::vector elementId(numCurves); diff --git a/third_party/renderman-25/plugin/hdPrman/debugCodes.cpp b/third_party/renderman-25/plugin/hdPrman/debugCodes.cpp index 567ae3f676..013966389a 100644 --- a/third_party/renderman-25/plugin/hdPrman/debugCodes.cpp +++ b/third_party/renderman-25/plugin/hdPrman/debugCodes.cpp @@ -49,6 +49,7 @@ TF_REGISTRY_FUNCTION(TfDebug) "computations."); TF_DEBUG_ENVIRONMENT_SYMBOL(HDPRMAN_TERMINAL_SCENE_INDEX_OBSERVER, "Debug logging for HdPrman terminal scene index observer."); + TF_DEBUG_ENVIRONMENT_SYMBOL(HDPRMAN_MOTION_BLUR, "Motion blur"); } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/third_party/renderman-25/plugin/hdPrman/debugCodes.h b/third_party/renderman-25/plugin/hdPrman/debugCodes.h index 951418d2a6..efdafcc7d8 100644 --- a/third_party/renderman-25/plugin/hdPrman/debugCodes.h +++ b/third_party/renderman-25/plugin/hdPrman/debugCodes.h @@ -42,7 +42,8 @@ TF_DEBUG_CODES( HDPRMAN_MESHLIGHT, HDPRMAN_RENDER_SETTINGS, HDPRMAN_RENDER_PASS, - HDPRMAN_TERMINAL_SCENE_INDEX_OBSERVER + HDPRMAN_TERMINAL_SCENE_INDEX_OBSERVER, + HDPRMAN_MOTION_BLUR ); PXR_NAMESPACE_CLOSE_SCOPE diff --git a/third_party/renderman-25/plugin/hdPrman/gprim.h b/third_party/renderman-25/plugin/hdPrman/gprim.h index 026b7795f1..42f3cc0b48 100644 --- a/third_party/renderman-25/plugin/hdPrman/gprim.h +++ b/third_party/renderman-25/plugin/hdPrman/gprim.h @@ -25,7 +25,6 @@ #define EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H #include "pxr/pxr.h" -#include "pxr/imaging/hd/enums.h" #include "pxr/usd/sdf/types.h" #include "pxr/base/gf/matrix4d.h" @@ -37,8 +36,6 @@ #include "hdPrman/utils.h" #include "Riley.h" -#include "RixShadingUtils.h" -#include "RixPredefinedStrings.hpp" PXR_NAMESPACE_OPEN_SCOPE @@ -181,18 +178,6 @@ HdPrman_Gprim::Sync(HdSceneDelegate* sceneDelegate, HdTimeSampleArray xf; sceneDelegate->SampleTransform(id, &xf); - // If blur is explicitly disabled, use single time 0 sample - const bool enableMotionBlur = - param->IsMotionBlurEnabled() && - HdPrman_IsMotionBlurPrimvarEnabled(sceneDelegate, id) && - HdPrman_GetNumXformSamples(sceneDelegate, id) >= 2; - - if (!enableMotionBlur) { - xf.values[0] = xf.Resample(0.f); - xf.times[0] = 0.f; - xf.Resize(1); - } - // Update visibility so thet rprim->IsVisible() will work in render pass if (HdChangeTracker::IsVisibilityDirty(*dirtyBits, id)) { BASE::_UpdateVisibility(sceneDelegate, dirtyBits); diff --git a/third_party/renderman-25/plugin/hdPrman/mesh.cpp b/third_party/renderman-25/plugin/hdPrman/mesh.cpp index c94eba4660..e7dcc50e9b 100644 --- a/third_party/renderman-25/plugin/hdPrman/mesh.cpp +++ b/third_party/renderman-25/plugin/hdPrman/mesh.cpp @@ -25,25 +25,14 @@ #include "hdPrman/mesh.h" #include "hdPrman/renderParam.h" #include "hdPrman/coordSys.h" -#include "hdPrman/instancer.h" #include "hdPrman/material.h" #include "hdPrman/rixStrings.h" -#include "pxr/base/gf/matrix4d.h" -#include "pxr/base/gf/matrix4f.h" -#include "pxr/base/gf/vec2f.h" -#include "pxr/base/gf/vec3f.h" -#include "pxr/base/gf/vec4f.h" -#include "pxr/imaging/hd/coordSys.h" #include "pxr/imaging/hd/meshTopology.h" -#include "pxr/imaging/hd/meshUtil.h" #include "pxr/imaging/pxOsd/subdivTags.h" #include "pxr/imaging/pxOsd/tokens.h" #include "pxr/usd/usdRi/rmanUtilities.h" -#include "Riley.h" #include "RiTypesHelper.h" -#include "RixShadingUtils.h" -#include "RixPredefinedStrings.hpp" #include @@ -169,18 +158,12 @@ HdPrman_Mesh::_ConvertGeometry(HdPrman_RenderParam *renderParam, // Point positions (P) // float primvarTime = 0.0f; - if( HdPrman_RenderParam::HasSceneIndexPlugin( - HdPrmanPluginTokens->velocityBlur) ) { - HdPrman_ConvertPointsPrimvar( - sceneDelegate, - id, - renderParam->GetShutterInterval(), - primvars, - npoints); - } else { - primvarTime = renderParam->ConvertPositions( - sceneDelegate, id, npoints, primvars); - } + HdPrman_ConvertPointsPrimvar( + sceneDelegate, + id, + renderParam->GetShutterInterval(), + primvars, + npoints); // Topology. primvars.SetIntegerDetail(RixStr.k_Ri_nvertices, nverts.cdata(), RtDetailType::k_uniform); diff --git a/third_party/renderman-25/plugin/hdPrman/motionBlurSceneIndexPlugin.cpp b/third_party/renderman-25/plugin/hdPrman/motionBlurSceneIndexPlugin.cpp new file mode 100644 index 0000000000..09f824c655 --- /dev/null +++ b/third_party/renderman-25/plugin/hdPrman/motionBlurSceneIndexPlugin.cpp @@ -0,0 +1,1460 @@ +// +// Copyright 2022 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "hdPrman/motionBlurSceneIndexPlugin.h" + +#include "hdPrman/debugCodes.h" +#include "hdPrman/tokens.h" + +#include "pxr/imaging/hd/filteringSceneIndex.h" +#include "pxr/imaging/hd/primvarsSchema.h" +#include "pxr/imaging/hd/retainedDataSource.h" +#include "pxr/imaging/hd/sceneIndexPluginRegistry.h" +#include "pxr/imaging/hd/tokens.h" +#include "pxr/imaging/hd/xformSchema.h" + +#include "pxr/base/vt/array.h" +#include "pxr/base/vt/typeHeaders.h" +#include "pxr/base/vt/visitValue.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + (fps) + ((mblur, "ri:object:mblur")) + ((vblur, "ri:object:vblur")) + ((vblur_on, "Velocity Blur")) + ((ablur_on, "Acceleration Blur")) + ((vblur_off, "No Velocity Blur")) + ((geosamples, "ri:object:geosamples")) + ((xformsamples, "ri:object:xformsamples")) + (angularVelocities) // XXX: Why is this not in HdTokens? +); + +// XXX: These defaults are pulled from UsdMotionAPI, for which there is not yet +// a corresponding Hydra schema. +static const int _defaultNonlinearSampleCount = 3; +static const float _defaultBlurScale = 1.0f; +// There is no canonical source for these defaults. They were previously hard- +// coded in renderParam.cpp. +static const int _defaultXformSamples = 2; +static const int _defaultGeoSamples = 2; +static const bool _defaultMblur = true; +static const TfToken _defaultVblur = _tokens->ablur_on; + +// XXX: We need to encode the fps in the scene index (in a standard +// place). Note that fps is called timeCodesPerSecond in USD. +static const float _fps = 24.0f; + +static const float _minimumShutterInterval = 1.0e-10; + +// XXX: Set by HdPrman_MotionBlurSceneIndexPlugin::SetShutterInterval() +// and needed by _MotionBlurHelper. These are part of our shutter +// interval workaround. See comments on SetShutterInterval() at bottom of file. +static float _shutterOpen = 0.0f; +static float _shutterClose = 0.0f; + +using TfTokenSet = std::unordered_set; + +TF_REGISTRY_FUNCTION(TfType) +{ + HdSceneIndexPluginRegistry::Define(); +} + +TF_REGISTRY_FUNCTION(HdSceneIndexPlugin) +{ + // This plug-in should be inserted *after* the extComp plug-in, + // so that disabling of blur, etc. will also affect points from extComp + const HdSceneIndexPluginRegistry::InsertionPhase insertionPhase = 3; + + const HdContainerDataSourceHandle inputArgs = + HdRetainedContainerDataSource::New( + _tokens->fps, + HdRetainedSampledDataSource::New(VtValue(_fps))); + + for( auto const& pluginDisplayName : HdPrman_GetPluginDisplayNames() ) { + HdSceneIndexPluginRegistry::GetInstance().RegisterSceneIndexForRenderer( + pluginDisplayName, + HdPrmanPluginTokens->motionBlur, + inputArgs, + insertionPhase, + HdSceneIndexPluginRegistry::InsertionOrderAtStart); + } +} + +namespace +{ + +// Get fps from input arguments data source +float _GetFps(const HdContainerDataSourceHandle& inputArgs) +{ + if (!inputArgs) { + return _fps; + } + + const auto source = HdSampledDataSource::Cast(inputArgs->Get(_tokens->fps)); + if (!source) { + return _fps; + } + + const VtValue &value = source->GetValue(0.0f); + if (!value.IsHolding()) { + return _fps; + } + + return value.UncheckedGet(); +} + +// Unfortunately, when encountering a legacy prim, the scene index emulation +// calls GetContributingSampleTimesForInterval with startTime and endTime +// being the smallest and largest finite floating point number. It does this +// because it cannot query the scene delegate itself. +// +// We rely on the UsdImaging knowing the relevant camera and its +// shutter interval and returning a sample time for the beginning and +// end of the shutter interval. +std::pair +_GetSamplingInterval( + const HdSampledDataSourceHandle& samplesSource, + const float shutterOpen, const float shutterClose, + const HdSampledDataSource::Time startTime, + const HdSampledDataSource::Time endTime) +{ + if (std::numeric_limits::lowest() < startTime && + endTime < std::numeric_limits::max()) { + // Client gives us a valid shutter interval. Use it. + return { startTime, endTime }; + } + + // Do the shutter interval reconstruction described above. + + std::vector sampleTimes; + // Ignore return value - just examine sampleTimes instead + samplesSource->GetContributingSampleTimesForInterval( + startTime, endTime, &sampleTimes); + + // Not enough samples to reconstruct the shutter interval. + if (sampleTimes.size() < 2) { + // These fallback values are from the camera + return { shutterOpen, shutterClose }; + } + + const auto iteratorPair = + std::minmax_element(sampleTimes.begin(), + sampleTimes.end()); + return { *iteratorPair.first, *iteratorPair.second }; +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/// \class _MotionBlurHelper +/// +/// Helper base class for motion blur. This class carries the implementations +/// for methods to retrieve motion blur parameters from the prim, to compute +/// contributing time samples, and to sample the given sampled data source. +/// This class encapsulates all the logic for transform, velocity, and +/// deformation motion blur. +/// +class _MotionBlurHelper +{ +public: + using Time = HdSampledDataSource::Time; + + /// samplesSource: the original data source + /// key: identifying name for samplesSource + /// primPath: path of sampleSource's parent prim (for diagnostics) + /// primType: type of sampleSource's parent prim + /// primvarsSource: data source for sampleSource's parent prim's primvars + /// inputArgs: data source from scene index plugin + _MotionBlurHelper( + const HdSampledDataSourceHandle& samplesSource, + const TfToken& key, + const SdfPath& primPath, + const TfToken& primType, + const HdContainerDataSourceHandle& primvarsSource, + const HdContainerDataSourceHandle& inputArgs) + : _samplesSource(samplesSource) + , _key(key) + , _primPath(primPath) + , _primType(primType) + , _primvarsSource(primvarsSource) + , _inputArgs(inputArgs) + { } + +protected: + bool + _GetContributingSampleTimesForInterval( + Time startTime, + Time endTime, + std::vector