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

Optimize VP2 rendering of USD objects with geometric cut-outs #3952

Conversation

jufrantz
Copy link
Contributor

@jufrantz jufrantz commented Oct 8, 2024

Building upon #3947 , this PR leverages transparency cut-outs, achieved through UsdPreviewSurface.opacityThreshold>0 or glTF alpha_mode=MASK, to optimize instancing in vp2RenderDelegate.

In HdStorm, draw items using these materials are detected as "masked". They are rendered efficiently without depth sorting or OIT, and they still contribute to shadows, unlike translucent items.

VP2 sdk does not expose such feature. An MRenderItem can only be declared as "transparent" which implies alpha blending. These transparent items also receive special treatment in shadow and post-effects passes (e.g. SSAO). To achieve correct blended transparency, VP2 will automatically de-instantiate items with transparent shader. In cases of massive instancing, this severely impacts draw performance. For example, depth sorting thousands of individual objects is quite expensive, and consolidating all instanced geometries will produce very fat geometry data.

This PR specifically optimizes the case of instanced geometry with masked materials thanks to MPxSubsceneOverride::setAllowTransparentInstances. This flag allows us to preserve instancing even for transparent items. These items are consequently correctly treated in shadow and post-effects passes, beauty pass remains correct without sorting (without the huge cost of de-instantiation) since the material does not produce semi-transparent fragments.

These geometric cut-outs are typically used for vegetation foliage, which is important to instantiate massively in complex environments. Additionally, USD 23.02+ uses UsdPreviewSurface.opacityThreshold for cards drawMode , it is aimed at lightweight and fast rendering; instanced cards will also be optimized. These two cases are common in our productions, and we need them to be efficient within maya.

Changes

  • Added "masked" transparency feature detection, inspired by HdStorm ( materialNetwork.cpp, materialXFilter.cpp )

  • Added HdVP2Material._drawItemFlags: These flags indicate if the material is transparent and masked. They are computed during material sync, when parameters changed, and are retained for later access during rprim sync.

  • Ensured affected renderables are re-synced, and MRenderItems are updated, whenever a material changes its drawItemFlags.

  • Finally, set up MRenderItems during this rprim sync so GPU instancing is not broken, when possible, thanks to MPxSubsceneOverride::setAllowTransparentInstances.

Results

Tests were conducted in maya 2025.2 with this scene, featuring 100000 instances of a sphere that has textured opacity and a masked UsdPreviewSurface. The camera is framing the whole instancer. I profiled using this script:

# Avoid consolidating potentially un-instanced items
cmds.setAttr("hardwareRenderingGlobals.consolidateWorld", 0)
# Use Object Sorting transparency
cmds.setAttr("hardwareRenderingGlobals.transparencyAlgorithm", 1)

# Temporary turn on texturing and profile one VP2 refresh
cmds.modelEditor("modelPanel4", e=True, displayTextures=True)
cmds.refresh()
cmds.ogs(traceRenderPipeline=True)
cmds.profiler(reset=True)
cmds.profiler(sampling=True)
cmds.refresh()
cmds.profiler(sampling=False)
cmds.ogs(traceRenderPipeline=False)
cmds.modelEditor("modelPanel4", e=True, displayTextures=False)

Before optimization:

TraceRenderPipeline reports:

# Count for list: [View Cube] = 26
# Count for list: [HUD] = 2
# Count for list: [Pre-Opaque UI] = 2
# Count for list: [Transparent] = 100000

Profiler reports:

  • VP2UpdateScene: 114ms
  • VP2Draw3dBeautyPass: 1667ms

profiler_beforePR

After optimization:

TraceRenderPipeline reports a single render item, instanced:

# -- VP2 Trace[modelPanel4][3d Beauty Pass]
# Count for list: [View Cube] = 26
# Count for list: [HUD] = 2
# Count for list: [Pre-Opaque UI] = 2
# Count for list: [Transparent] = 1

Profiler reports:

  • VP2UpdateScene: 885us
  • VP2Draw3dBeautyPass: 952us

profiler_afterPR

@jufrantz jufrantz force-pushed the optimize_vp2_rendering_of_instances_with_masked_transparency branch from a29f6ab to 2729579 Compare October 9, 2024 10:07
@JGamache-autodesk
Copy link
Collaborator

Hi @jufrantz, looks very interesting, but I definitely need to ask... Have you tried making _isTransparent return false for the cut-out cases? That would remove any need for transparency mitigation at the render item level since these items would correctly declare their shading to be opaque.

@JGamache-autodesk
Copy link
Collaborator

Tried it locally. I only kept your new _IsMaskedTransparency function, and modified _isTransparent to do:

//! Return true if the surface shader needs to be rendered in a transparency pass.
 bool _IsTransparent(const HdMaterialNetwork& network)
 {
+    if (_IsMaskedTransparency(network)) {
+        return false;
+    }
+
     using OpaqueTestPair = std::pair<TfToken, float>;

And, for your scene, performance went from bad enough to cause a TDR to 30fps with correct visual results.

@jufrantz
Copy link
Contributor Author

jufrantz commented Oct 9, 2024

Hello @JGamache-autodesk,

That's definitely a good question especially since you are right, I just tested this and it works correctly on my scene, rendering is correct including shadows and SSAO (wow!).

To be myself transparent, this was my first intention and I tried it. I didnt test on this kind of scenes but on a simpler scene with just a non-instanced mesh and I detected issues with SSAO that was occluding the discarded surface. We are encountering these performance issues on scenes with instancing and I didn't want to introduce a regression with SSAO, I ended up with this solution and its complications.

I re-tested with this scene and still have the issue on non-instanced geometry, while it works on the same geometry and shader when point-instanced. Something is happening behind the scene but I have no clue.

image

@jufrantz
Copy link
Contributor Author

jufrantz commented Oct 10, 2024

Another test I did during #3947. It isn’t related to vp2RenderDelegate / MPxSubsceneOverride but might still be interesting, it led me to the idea that beauty fragment discards and marking the shader as opaque would not be enough for post effects.

On this scene with maya native meshs and shading, if usdPreviewSurface shading node sets transparencyOn output based on opacityThreshold input, like this:

@@ -479,6 +479,7 @@ MStatus PxrMayaUsdPreviewSurface::compute(const MPlug& plug, MDataBlock& dataBlo
         }
 
         float transparencyOn = false;
+        if (opacityThreshold <= 0.0) {
             if (opacityConnected) {
                 transparencyOn = true;
             } else {
@@ -489,6 +490,7 @@ MStatus PxrMayaUsdPreviewSurface::compute(const MPlug& plug, MDataBlock& dataBlo
                     transparencyOn = true;
                 }
             }
+        }

I traced that VP2 correctly classifies shaded items as opaque and I get this result with SAAO:
image

Versus the PR unchanged (all items marked transparent):
image

Hope it helps,
Julien

@JGamache-autodesk
Copy link
Collaborator

Thanks for all the tests, they helped me do a quick investigation in Maya rendering code.

Also interesting in your last scene is instancing the masked panels and seeing better SSAO results with GPU instancing enabled.

Can you update the PR with your latest code that properly declares masked as opaque in material.cpp and usdPreviewSurface.cpp? We will accept the SSAO issue this reveals and log a bug to eventually have this fixed in Maya.

jufrantz added a commit to jufrantz/maya-usd that referenced this pull request Oct 14, 2024
@jufrantz jufrantz changed the title Optimize VP2 rendering of USD instances with geometric cut-outs Optimize VP2 rendering of USD objects with geometric cut-outs Oct 16, 2024
@jufrantz
Copy link
Contributor Author

Hi @JGamache-autodesk,

I have pushed the requested changes. All materials with masked transparency are now simply marked as opaque in this PR, and I’ve also updated usdPreviewSurface shading node in #3947.

Could you please provide us with the Maya issue ID once it’s logged so that we can follow up with the support team?

Thank you for your feedback.
Julien

@JGamache-autodesk
Copy link
Collaborator

The SSAO issue with cut-out shaders is logged as MAYA-135575.

… transparency.

HdVP2Material now detects when its shader's transparency is used for a
geometric cut-out, such as a UsdPreviewSurface with opacityThreshold
(e.g., for `cards` drawMode).

In this case, transparency does not require alpha blending or depth
sorting. We can setup the transparent MRenderItem to still leverage
GPU instanced draw thanks to `MPxSubSceneOverride::setAllowTransparentInstances`.

cf Maya API Reference: https://help.autodesk.com/cloudhelp/2025/ENU/MAYA-API-REF/cpp_ref/class_m_h_w_render_1_1_m_px_sub_scene_override.html#ab5f84f5ba90bb3caabbb69ab3d52cb37
…eview.

Removes the special case for instanced render items, all objects with materials
that have masked transparency are now consistently marked as opaque.
@jufrantz jufrantz force-pushed the optimize_vp2_rendering_of_instances_with_masked_transparency branch from e68f973 to d0d2e9c Compare October 18, 2024 14:28
@jufrantz
Copy link
Contributor Author

Hello,
I fixed the formatting (by dropping an incorrect formatting commit). Sorry for this error; it appears something is wrong with my clang-formats.

@seando-adsk
Copy link
Collaborator

There was a single test failure on Windows 2022 with testUsdExportPackage - I've seen this test randomly fail. I'll just re-run the preflight to be sure.

@seando-adsk seando-adsk assigned jufrantz and unassigned jufrantz Oct 22, 2024
@seando-adsk
Copy link
Collaborator

@jufrantz Just as an FYI, we are using clang format version 10 (which is quite old). It formats differently than newer versions which is why we haven't updated yet.

@seando-adsk seando-adsk added the vp2renderdelegate Related to VP2RenderDelegate label Oct 22, 2024
@seando-adsk seando-adsk added the ready-for-merge Development process is finished, PR is ready for merge label Oct 22, 2024
@seando-adsk seando-adsk merged commit 6d8f838 into Autodesk:dev Oct 22, 2024
12 of 13 checks passed
@jufrantz
Copy link
Contributor Author

Hello @seando-adsk,
I finally found it in the workflow scripts and now have a container ready for my upcoming formats. Everything will be set for the next PR. Thanks for the info and for wrapping up the two PRs.

@jufrantz jufrantz deleted the optimize_vp2_rendering_of_instances_with_masked_transparency branch October 22, 2024 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-merge Development process is finished, PR is ready for merge vp2renderdelegate Related to VP2RenderDelegate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants