Skip to content

Commit

Permalink
Merge pull request #1220 from Autodesk/krickw/MAYA-109887/per_instanc…
Browse files Browse the repository at this point in the history
…e_data_support

Add per instance inherited data support to Vp2RenderDelegate.
  • Loading branch information
Krystian Ligenza authored Mar 15, 2021
2 parents 6cd417f + c8b190f commit 48b49ec
Show file tree
Hide file tree
Showing 16 changed files with 1,406 additions and 108 deletions.
105 changes: 91 additions & 14 deletions lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,11 @@ void HdVP2BasisCurves::Sync(
#endif
}

#if defined(HD_API_VERSION) && HD_API_VERSION >= 36
// Sync instance topology if necessary.
_UpdateInstancer(delegate, dirtyBits);
#endif

if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->normals)
|| HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->primvar)) {
const HdVP2Material* material = static_cast<const HdVP2Material*>(
Expand Down Expand Up @@ -891,14 +896,17 @@ void HdVP2BasisCurves::_UpdateDrawItem(
if (itemDirtyBits
& (HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyDisplayStyle
| DirtySelectionHighlight)) {
VtVec3fArray colorArray;
VtFloatArray alphaArray;
VtVec3fArray colorArray;
HdInterpolation colorInterpolation = HdInterpolationConstant;
VtFloatArray alphaArray;
HdInterpolation alphaInterpolation = HdInterpolationConstant;

auto itColor = primvarSourceMap.find(HdTokens->displayColor);
if (itColor != primvarSourceMap.end()) {
const VtValue& value = itColor->second.data;
if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() > 0) {
colorArray = value.UncheckedGet<VtVec3fArray>();
colorInterpolation = itColor->second.interpolation;
}
}

Expand All @@ -907,6 +915,7 @@ void HdVP2BasisCurves::_UpdateDrawItem(
const VtValue& value = itOpacity->second.data;
if (value.IsHolding<VtFloatArray>() && value.GetArraySize() > 0) {
alphaArray = value.UncheckedGet<VtFloatArray>();
alphaInterpolation = itOpacity->second.interpolation;

// It is possible that all elements in the opacity array are 1.
// Due to the performance indication about transparency, we have to
Expand All @@ -927,13 +936,16 @@ void HdVP2BasisCurves::_UpdateDrawItem(
// to match the default color of Hydra Storm.
if (colorArray.empty()) {
colorArray.push_back(GfVec3f(0.18f, 0.18f, 0.18f));
colorInterpolation = HdInterpolationConstant;
}

if (alphaArray.empty()) {
alphaArray.push_back(1.0f);
alphaInterpolation = HdInterpolationConstant;
}

bool prepareCPVBuffer = true;
bool prepareInstanceColorBuffer = false;

// Use fallback shader if there is no material binding or we failed to create a shader
// instance from the material.
Expand All @@ -942,11 +954,18 @@ void HdVP2BasisCurves::_UpdateDrawItem(
MHWRender::MGeometry::Primitive primitiveType = MHWRender::MGeometry::kLines;
int primitiveStride = 0;

if (colorArray.size() == 1 && alphaArray.size() == 1) {
bool usingCPV
= (colorArray.size() > 1 && colorInterpolation != HdInterpolationInstance)
|| (alphaArray.size() > 1 && alphaInterpolation != HdInterpolationInstance);

if (!usingCPV) {
prepareCPVBuffer = false;
prepareInstanceColorBuffer = colorInterpolation == HdInterpolationInstance
|| alphaInterpolation == HdInterpolationInstance;

const GfVec3f& clr3f = colorArray[0];
const MColor color(clr3f[0], clr3f[1], clr3f[2], alphaArray[0]);
// When the interpolation is instance the color of the material is ignored
const MColor color(clr3f[0], clr3f[1], clr3f[2], alphaArray[0]);

if (refineLevel > 0) {
shader = _delegate->GetBasisCurvesFallbackShader(type, basis, color);
Expand Down Expand Up @@ -1015,6 +1034,37 @@ void HdVP2BasisCurves::_UpdateDrawItem(

_CommitMVertexBuffer(_curvesSharedData._colorBuffer.get(), bufferData);
}
} else if (prepareInstanceColorBuffer) {
TF_VERIFY(
colorInterpolation == HdInterpolationInstance
|| alphaInterpolation == HdInterpolationInstance);

if (alphaInterpolation == HdInterpolationConstant) {
float alpha = alphaArray[0];
for (unsigned int i = 1; i < colorArray.size(); i++)
alphaArray.push_back(alpha);
}
if (colorInterpolation == HdInterpolationConstant) {
GfVec3f color = colorArray[0];
for (unsigned int i = 1; i < alphaArray.size(); i++)
colorArray.push_back(color);
}

unsigned int numInstances = colorArray.size();
stateToCommit._instanceColors.setLength(numInstances * kNumColorChannels);
float* bufferData = &stateToCommit._instanceColors[0];

if (bufferData) {
unsigned int offset = 0;
for (size_t i = 0; i < numInstances; i++) {
const GfVec3f& color = colorArray[i];
bufferData[offset++] = color[0];
bufferData[offset++] = color[1];
bufferData[offset++] = color[2];

bufferData[offset++] = alphaArray[i];
}
}
}
}
}
Expand Down Expand Up @@ -1101,11 +1151,6 @@ void HdVP2BasisCurves::_UpdateDrawItem(
// If the mesh is instanced but has 0 instance transforms remember that
// so the render item can be hidden.

#if defined(HD_API_VERSION) && HD_API_VERSION >= 36
// Sync instance topology if necessary.
_UpdateInstancer(sceneDelegate, &itemDirtyBits);
#endif

bool instancerWithNoInstances = false;
if (!GetInstancerId().IsEmpty()) {

Expand Down Expand Up @@ -1138,7 +1183,9 @@ void HdVP2BasisCurves::_UpdateDrawItem(
std::vector<unsigned char> colorIndices;

// Assign with the index to the dormant wireframe color by default.
colorIndices.resize(instanceCount, 0);
bool hasAuthoredColor = stateToCommit._instanceColors.length() > 0;
const size_t authoredColorIndex = sizeof(colors) / sizeof(MColor);
colorIndices.resize(instanceCount, hasAuthoredColor ? authoredColorIndex : 0);

// Assign with the index to the active selection highlight color.
if (auto state = drawScene.GetActiveSelectionState(id)) {
Expand All @@ -1164,6 +1211,10 @@ void HdVP2BasisCurves::_UpdateDrawItem(

for (unsigned int i = 0; i < instanceCount; ++i) {
unsigned char colorIndex = colorIndices[i];
if (colorIndex == authoredColorIndex) {
offset += kNumColorChannels;
continue;
}
const MColor& color = colors[colorIndex];
for (unsigned int j = 0; j < kNumColorChannels; j++) {
stateToCommit._instanceColors[offset++] = color[j];
Expand Down Expand Up @@ -1353,8 +1404,12 @@ void HdVP2BasisCurves::_UpdateDrawItem(
}

// Important, update instance transforms after setting geometry on render items!
auto& oldInstanceCount = stateToCommit._drawItemData._instanceCount;
auto newInstanceCount = stateToCommit._instanceTransforms.length();
auto& oldInstanceCount = stateToCommit._drawItemData._instanceCount;
auto newInstanceCount = stateToCommit._instanceTransforms.length();
MString extraColorChannelName = kDiffuseColorStr;
if (drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight)) {
extraColorChannelName = kSolidColorStr;
}

// GPU instancing has been enabled. We cannot switch to consolidation
// without recreating render item, so we keep using GPU instancing.
Expand All @@ -1371,7 +1426,7 @@ void HdVP2BasisCurves::_UpdateDrawItem(

if (stateToCommit._instanceColors.length() == newInstanceCount * kNumColorChannels) {
drawScene.setExtraInstanceData(
*renderItem, kSolidColorStr, stateToCommit._instanceColors);
*renderItem, extraColorChannelName, stateToCommit._instanceColors);
}
}
#if MAYA_API_VERSION >= 20210000
Expand All @@ -1390,7 +1445,7 @@ void HdVP2BasisCurves::_UpdateDrawItem(

if (stateToCommit._instanceColors.length() == newInstanceCount * kNumColorChannels) {
drawScene.setExtraInstanceData(
*renderItem, kSolidColorStr, stateToCommit._instanceColors);
*renderItem, extraColorChannelName, stateToCommit._instanceColors);
}

stateToCommit._drawItemData._usingInstancedDraw = true;
Expand Down Expand Up @@ -1697,6 +1752,28 @@ void HdVP2BasisCurves::_UpdatePrimvarSources(
TfTokenVector::const_iterator begin = requiredPrimvars.cbegin();
TfTokenVector::const_iterator end = requiredPrimvars.cend();

// inspired by HdStInstancer::_SyncPrimvars
// Get any required instanced primvars from the instancer. Get these before we get
// any rprims from the rprim itself. If both are present, the rprim's values override
// the instancer's value.
const SdfPath& instancerId = GetInstancerId();
if (!instancerId.IsEmpty()) {
HdPrimvarDescriptorVector instancerPrimvars
= sceneDelegate->GetPrimvarDescriptors(instancerId, HdInterpolationInstance);
for (const HdPrimvarDescriptor& pv : instancerPrimvars) {
if (std::find(begin, end, pv.name) == end) {
// erase the unused primvar so we don't hold onto stale data
_curvesSharedData._primvarSourceMap.erase(pv.name);
} else {
if (HdChangeTracker::IsPrimvarDirty(dirtyBits, instancerId, pv.name)) {
const VtValue value = sceneDelegate->Get(instancerId, pv.name);
_curvesSharedData._primvarSourceMap[pv.name]
= { value, HdInterpolationInstance };
}
}
}
}

for (size_t i = 0; i < HdInterpolationCount; i++) {
const HdInterpolation interp = static_cast<HdInterpolation>(i);

Expand Down
Loading

0 comments on commit 48b49ec

Please sign in to comment.