Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAYA-108563 - Support default material shading using new SDK APIs #1339

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/mayaUsd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ if(DEFINED UFE_PREVIEW_VERSION_NUM)
)
endif()

if (MAYA_API_VERSION VERSION_GREATER_EQUAL 20220100 AND MAYA_API_VERSION VERSION_LESS 20230000)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
HAS_DEFAULT_MATERIAL_SUPPORT_API=1
)
endif()

if (MAYA_API_VERSION VERSION_GREATER_EQUAL 20230000 AND UFE_VERSION VERSION_GREATER_EQUAL 2.0.3)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
HAS_DEFAULT_MATERIAL_SUPPORT_API=1
)
endif()

# Some of the UFE classes are exporting STL classes which causes this warning.
if(UFE_FOUND AND MSVC)
target_compile_options(${PROJECT_NAME}
Expand Down
61 changes: 56 additions & 5 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,15 +1280,61 @@ void HdVP2Mesh::_InitRepr(const TfToken& reprToken, HdDirtyBits* dirtyBits)

switch (desc.geomStyle) {
case HdMeshGeomStyleHull:
break; // Creating the hull render items requires geom subsets from the topology, and we
// can't access that here.
// Creating the smoothHull hull render items requires geom subsets from the topology,
// and we can't access that here.
#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
if (reprToken == HdVP2ReprTokens->defaultMaterial) {
// But default material mode does not use geom subsets, so we create the render item
renderItem = _CreateSmoothHullRenderItem(renderItemName);
renderItem->setDefaultMaterialHandling(
MRenderItem::DrawOnlyWhenDefaultMaterialActive);
renderItem->setShader(_delegate->Get3dDefaultMaterialShader());
}
#endif
break;
case HdMeshGeomStyleHullEdgeOnly:
// The smoothHull repr uses the wireframe item for selection
// highlight only.
// The smoothHull repr uses the wireframe item for selection highlight only.
#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
if (reprToken == HdReprTokens->smoothHull
|| reprToken == HdVP2ReprTokens->defaultMaterial) {
// Share selection highlight render item between smoothHull and defaultMaterial:
bool foundShared = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we end up using this pattern to share more render items then this seems like a good candidate to be refactored into a method.

_ReprVector::const_iterator it = std::find_if(
_reprs.begin(),
_reprs.end(),
_ReprComparator(
reprToken == HdReprTokens->smoothHull ? HdVP2ReprTokens->defaultMaterial
: HdReprTokens->smoothHull));
if (it != _reprs.end()) {
const HdReprSharedPtr& repr = it->second;
const auto& items = repr->GetDrawItems();
#if HD_API_VERSION < 35
for (HdDrawItem* item : items) {
HdVP2DrawItem* shDrawItem = static_cast<HdVP2DrawItem*>(item);
#else
for (const HdRepr::DrawItemUniquePtr& item : items) {
HdVP2DrawItem* const shDrawItem = static_cast<HdVP2DrawItem*>(item.get());
#endif
if (shDrawItem
&& shDrawItem->MatchesUsage(HdVP2DrawItem::kSelectionHighlight)) {
drawItem->SetRenderItem(shDrawItem->GetRenderItem());
foundShared = true;
break;
}
}
}
if (!foundShared) {
renderItem = _CreateSelectionHighlightRenderItem(renderItemName);
}
drawItem->SetUsage(HdVP2DrawItem::kSelectionHighlight);
}
#else
// The smoothHull repr uses the wireframe item for selection highlight only.
if (reprToken == HdReprTokens->smoothHull) {
renderItem = _CreateSelectionHighlightRenderItem(renderItemName);
drawItem->SetUsage(HdVP2DrawItem::kSelectionHighlight);
}
#endif
// The item is used for wireframe display and selection highlight.
else if (reprToken == HdReprTokens->wire) {
renderItem = _CreateWireframeRenderItem(renderItemName);
Expand Down Expand Up @@ -1605,7 +1651,8 @@ void HdVP2Mesh::_UpdateDrawItem(
}
#endif

if (desc.geomStyle == HdMeshGeomStyleHull) {
if (desc.geomStyle == HdMeshGeomStyleHull
&& desc.shadingTerminal == HdMeshReprDescTokens->surfaceShader) {
Copy link
Collaborator Author

@JGamache-autodesk JGamache-autodesk Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultMaterial repr has a different shading terminal and will skip the shading update.
Regular smoothMesh has "surfaceShader" as terminal, so this addition does not require version check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we modify the real material while in default material mode does it update correctly when we turn off "use default material"? IIRC somewhere we clear all the dirty flags, so we'd forget about the dirty material id and then not update.

bool dirtyMaterialId = (itemDirtyBits & HdChangeTracker::DirtyMaterialId) != 0;
if (dirtyMaterialId) {
SdfPath materialId = GetMaterialId(); // This is an index path
Expand Down Expand Up @@ -2388,6 +2435,10 @@ MHWRender::MRenderItem* HdVP2Mesh::_CreateSmoothHullRenderItem(const MString& na
renderItem->setObjectTypeExclusionFlag(MHWRender::MFrameContext::kExcludeMeshes);
#endif

#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
renderItem->setDefaultMaterialHandling(MRenderItem::SkipWhenDefaultMaterialActive);
#endif

setWantConsolidation(*renderItem, true);

return renderItem;
Expand Down
29 changes: 28 additions & 1 deletion lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ namespace {
//! Representation selector for shaded and textured viewport mode
const HdReprSelector kSmoothHullReprSelector(HdReprTokens->smoothHull);

#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
//! Representation selector for default material viewport mode
const HdReprSelector kDefaultMaterialReprSelector(HdVP2ReprTokens->defaultMaterial);
#endif

//! Representation selector for wireframe viewport mode
const HdReprSelector kWireReprSelector(TfToken(), HdReprTokens->wire);

Expand Down Expand Up @@ -252,6 +257,15 @@ void _ConfigureReprs()
/*flatShadingEnabled=*/false,
/*blendWireframeColor=*/false);

#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
const HdMeshReprDesc reprDescHullDefaultMaterial(
HdMeshGeomStyleHull,
HdCullStyleDontCare,
HdMeshReprDescTokens->constantColor,
/*flatShadingEnabled=*/false,
/*blendWireframeColor=*/false);
#endif

const HdMeshReprDesc reprDescEdge(
HdMeshGeomStyleHullEdgeOnly,
HdCullStyleDontCare,
Expand All @@ -262,6 +276,12 @@ void _ConfigureReprs()
// Hull desc for shaded display, edge desc for selection highlight.
HdMesh::ConfigureRepr(HdReprTokens->smoothHull, reprDescHull, reprDescEdge);

#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
// Hull desc for default material display, edge desc for selection highlight.
HdMesh::ConfigureRepr(
HdVP2ReprTokens->defaultMaterial, reprDescHullDefaultMaterial, reprDescEdge);
#endif

// Edge desc for bbox display.
HdMesh::ConfigureRepr(HdVP2ReprTokens->bbox, reprDescEdge);

Expand Down Expand Up @@ -731,7 +751,14 @@ void ProxyRenderDelegate::_Execute(const MHWRender::MFrameContext& frameContext)
// To support Wireframe on Shaded mode, the two displayStyle checks
// should not be mutually excluded.
if (displayStyle & MHWRender::MFrameContext::kGouraudShaded) {
if (!reprSelector.Contains(HdReprTokens->smoothHull)) {
#ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API
if (displayStyle & MHWRender::MFrameContext::kDefaultMaterial) {
if (!reprSelector.Contains(HdVP2ReprTokens->defaultMaterial)) {
reprSelector = reprSelector.CompositeOver(kDefaultMaterialReprSelector);
}
} else
#endif
if (!reprSelector.Contains(HdReprTokens->smoothHull)) {
reprSelector = reprSelector.CompositeOver(kSmoothHullReprSelector);
}
}
Expand Down
21 changes: 21 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/render_delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ class MShaderCache final
if (!TF_VERIFY(shaderMgr))
return;

_3dDefaultMaterialShader
= shaderMgr->getStockShader(MHWRender::MShaderManager::k3dDefaultMaterialShader);

TF_VERIFY(_3dDefaultMaterialShader);

_3dCPVSolidShader = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dCPVSolidShader);

TF_VERIFY(_3dCPVSolidShader);
Expand Down Expand Up @@ -215,6 +220,13 @@ class MShaderCache final
return _fallbackCPVShaders[index];
}

/*! \brief Returns the default material shader.
*/
MHWRender::MShaderInstance* Get3dDefaultMaterialShader() const
{
return _3dDefaultMaterialShader;
}

/*! \brief Returns a white 3d fat point shader.
*/
MHWRender::MShaderInstance* Get3dFatPointShader() const { return _3dFatPointShader; }
Expand Down Expand Up @@ -344,6 +356,8 @@ class MShaderCache final

//!< Fallback shaders with CPV support
MHWRender::MShaderInstance* _fallbackCPVShaders[FallbackShaderTypeCount] { nullptr };
//!< 3d default material shader
MHWRender::MShaderInstance* _3dDefaultMaterialShader { nullptr };

MHWRender::MShaderInstance* _3dFatPointShader { nullptr }; //!< 3d shader for points
MHWRender::MShaderInstance* _3dCPVSolidShader { nullptr }; //!< 3d CPV solid-color shader
Expand Down Expand Up @@ -862,6 +876,13 @@ MHWRender::MShaderInstance* HdVP2RenderDelegate::Get3dSolidShader(const MColor&
return sShaderCache.Get3dSolidShader(color);
}

/*! \brief Returns the default material shader.
*/
MHWRender::MShaderInstance* HdVP2RenderDelegate::Get3dDefaultMaterialShader() const
{
return sShaderCache.Get3dDefaultMaterialShader();
}

/*! \brief Returns a 3d CPV solid-color shader.
*/
MHWRender::MShaderInstance* HdVP2RenderDelegate::Get3dCPVSolidShader() const
Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/render_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class HdVP2RenderDelegate final : public HdRenderDelegate
MHWRender::MShaderInstance* GetFallbackShader(const MColor& color) const;
MHWRender::MShaderInstance* GetFallbackCPVShader() const;
MHWRender::MShaderInstance* Get3dSolidShader(const MColor& color) const;
MHWRender::MShaderInstance* Get3dDefaultMaterialShader() const;
MHWRender::MShaderInstance* Get3dCPVSolidShader() const;
MHWRender::MShaderInstance* Get3dFatPointShader() const;

Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ PXR_NAMESPACE_OPEN_SCOPE
// clang-format off
#define HDVP2_REPR_TOKENS \
(bbox) \
(defaultMaterial) \
(selection)

#define HDVP2_TOKENS \
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
import fixturesUtils
import imageUtils
import mayaUtils
import unittest
import usdUtils
import testUtils

from mayaUsd import lib as mayaUsdLib
from mayaUsd import ufe as mayaUsdUfe

from maya import cmds
import maya.api.OpenMayaRender as omr

import ufe

Expand Down Expand Up @@ -81,7 +83,20 @@ def testPerInstanceInheriedDataBasisCurves(self):
cmds.select("|stage|stageShape,/instanced_2")
self.assertSnapshotClose('%s_selected.png' % self._testName)


@unittest.skipUnless("SkipWhenDefaultMaterialActive" in dir(omr.MRenderItem), "Requires new SDK API")
def testInstanceDefaultMaterial(self):
self._StartTest('defaultMaterialBillboards')
cmds.select("|stage|stageShape,/root/group/billboard_03",
"|stage|stageShape,/root/group/flatquad_03")
self.assertSnapshotClose('%s_selected.png' % self._testName)
panel = mayaUtils.activeModelPanel()
cmds.modelEditor(panel, edit=True, useDefaultMaterial=True)
self.assertSnapshotClose('%s_default.png' % self._testName)
cmds.select("|stage|stageShape,/root/group/billboard_04",
"|stage|stageShape,/root/group/flatquad_04")
self.assertSnapshotClose('%s_defaultSelected.png' % self._testName)
cmds.modelEditor(panel, edit=True, useDefaultMaterial=False)
self.assertSnapshotClose('%s_notDefault.png' % self._testName)

if __name__ == '__main__':
fixturesUtils.runTests(globals())
61 changes: 61 additions & 0 deletions test/testSamples/instances/billboard.usda
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#usda 1.0
(
defaultPrim = "GEO"
metersPerUnit = 0.01
upAxis = "Y"
)

def Xform "GEO"
{
def Mesh "BILLBOARD" (
prepend apiSchemas = ["MaterialBindingAPI"]
kind = "component"
)
{
uniform bool doubleSided = 1
float3[] extent = [(-1.5, 0, -1.5), (1.5, 0, 1.5)]
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
rel material:binding = </GEO/BILLBOARD/Looks/TEXTUREDA>
point3f[] points = [(-1.5, 0, 1.5), (1.5, 0, 1.5), (-1.5, 0, -1.5), (1.5, 0, -1.5)]
texCoord2f[] primvars:map1 = [(0, 0), (1, 0), (0, 1), (1, 1)] (
interpolation = "faceVarying"
)
int[] primvars:map1:indices = [0, 1, 3, 2]

def Scope "Looks"
{
def Material "TEXTUREDA"
{
token inputs:file1:varname = "map1"
token outputs:surface.connect = </GEO/BILLBOARD/Looks/TEXTUREDA/TEXTUREDA.outputs:surface>

def Shader "TEXTUREDA"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor.connect = </GEO/BILLBOARD/Looks/TEXTUREDA/file1.outputs:rgb>
token outputs:displacement
token outputs:surface
}

def Shader "file1"
{
uniform token info:id = "UsdUVTexture"
float4 inputs:fallback = (0.5, 0.5, 0.5, 1)
asset inputs:file = @green_A.png@
float2 inputs:st.connect = </GEO/BILLBOARD/Looks/TEXTUREDA/file1/TexCoordReader.outputs:result>
token inputs:wrapS = "repeat"
token inputs:wrapT = "repeat"
float3 outputs:rgb

def Shader "TexCoordReader"
{
uniform token info:id = "UsdPrimvarReader_float2"
token inputs:varname.connect = </GEO/BILLBOARD/Looks/TEXTUREDA.inputs:file1:varname>
float2 outputs:result
}
}
}
}
}
}
Loading