Skip to content

Fix instancing/draw-commands mismatch skipping indirect draws - #9159

Merged
mvaligursky merged 1 commit into
mainfrom
mv-instancing-draw-commands
Aug 12, 2026
Merged

Fix instancing/draw-commands mismatch skipping indirect draws#9159
mvaligursky merged 1 commit into
mainfrom
mv-instancing-draw-commands

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Fixes #9153.

After draw commands (indirect / multi-draw) were added, there were two independent "instance count" mechanisms that were only partially reconciled: hardware instancing (MeshInstance.instancingCount) and draw commands (setIndirect / setMultiDraw). The zero-instance skip guard in the forward and shadow renderers gated the entire draw on instancingData.count, so a mesh instance that had instancing set up with count 0 (or unset) but a valid draw command was dropped before it ever reached device.draw — the model would not render at all.

Changes:

  • Forward renderer: only skip the zero-instance draw when no draw commands are bound for the camera (!drawCall.getDrawCommands(camera)).
  • Shadow renderer: same guard for shadow casters.
  • MeshInstance: added a Precedence section to the class docs making the expected behavior explicit — when draw commands are bound they are the source of truth for the draw count and per-draw instance counts, instancingCount is ignored, and instancingCount = 0 does not skip rendering. instancingCount only applies to plain hardware instancing when no draw commands are bound.

This matches the behavior already implemented in the graphics backends, where the indirect draw path derives instance counts entirely from the draw commands and ignores the numInstances argument.

When draw commands (indirect / multi-draw) are bound, they are the
source of truth for the number of draws and per-draw instance counts.
The zero-instance skip guard in the forward and shadow renderers gated
the whole draw on instancingData.count, so a mesh instance with
instancing set up but count 0 was dropped even when a valid draw
command existed. Only skip when no draw commands are bound, and
document the precedence on MeshInstance.
@github-actions

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2358.0 KB (+0.0 KB, +0.00%) 605.3 KB (+0.0 KB, +0.00%) 470.3 KB (+0.5 KB, +0.10%)
playcanvas.min.mjs 2355.4 KB (+0.0 KB, +0.00%) 604.4 KB (+0.0 KB, +0.00%) 469.7 KB (+0.3 KB, +0.06%)

@mvaligursky
mvaligursky merged commit 9012828 into main Aug 12, 2026
10 checks passed
@mvaligursky
mvaligursky deleted the mv-instancing-draw-commands branch August 12, 2026 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instancing mismatch between MeshInstance and DrawCommands

1 participant