Skip to content

bugfix: Render ground-aligned particles without sorting#2838

Open
stephanmeesters wants to merge 2 commits into
TheSuperHackers:mainfrom
stephanmeesters:perf/ground-aligned-particles-nosort
Open

bugfix: Render ground-aligned particles without sorting#2838
stephanmeesters wants to merge 2 commits into
TheSuperHackers:mainfrom
stephanmeesters:perf/ground-aligned-particles-nosort

Conversation

@stephanmeesters

@stephanmeesters stephanmeesters commented Jun 28, 2026

Copy link
Copy Markdown

A performance gain (about 8%) could be achieved in a busy scene, see animated gif below, by not sorting particles that are "ground-aligned". (tested in release mode, windowed, stats averaged in 60 secs window)

The reasoning is that ground-aligned particles generally do not have much benefit from back to front sorting, as they are effectively on the ground with nothing behind them, and other nearby ground-aligned particles are at about the same height.

In testing this actually appeared to resolve some rendering issues as ground particles would sometimes cut into nearby particles leaving hard edges (see the before image).

sorting-renderer.webm

Todo

  • Do some more testing, in campaign etc

@greptile-apps

greptile-apps Bot commented Jun 28, 2026

Copy link
Copy Markdown

Greptile Summary

This PR optimizes ground-aligned particle rendering by skipping back-to-front sorting in PointGroupClass::Render, yielding ~8% performance improvement in busy scenes and also fixing visual artifacts where ground particles clipped into billboard particles. The RenderVolumeParticle path is explicitly left unchanged (with a new explanatory @info comment), as volumetric particles have layered depth slices that do benefit from sorting even when ground-aligned.

  • Render change: Billboard && is prepended to the sort condition, so non-billboard (ground-aligned) particles always use the non-sorting vertex buffer path, reducing CPU work.
  • RenderVolumeParticle unchanged: A new @info annotation explains that volumetric ground-aligned particles retain sorting — this is an explicit design decision, not an oversight.

Confidence Score: 5/5

Safe to merge — the change is well-scoped, the Billboard guard is correctly placed, and the deliberate retention of sorting in the volumetric path is clearly documented.

Both changed code paths are consistent with the stated intent: regular ground-aligned particles skip sorting for the performance and visual-artifact wins described in the PR, while volumetric particles keep sorting because their layered depth slices require depth ordering for correct blending. The previous review concern about RenderVolumeParticle is explicitly addressed with the new @info annotation.

No files require special attention.

Important Files Changed

Filename Overview
Core/Libraries/Source/WWVegas/WW3D2/pointgr.cpp Added Billboard && guard to skip sorting for ground-aligned particles in Render; RenderVolumeParticle explicitly retains sorting for all volumetric particles with a new explanatory comment.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[PointGroupClass::Render] --> B{Billboard?}
    B -- No\nground-aligned --> C[sort = false\nUse BUFFER_TYPE_DYNAMIC_DX8\nNo back-to-front ordering]
    B -- Yes\nbillboard --> D{Translucent?\nAlpha test off?\nSorting enabled?}
    D -- No --> C
    D -- Yes --> E[sort = true\nUse BUFFER_TYPE_DYNAMIC_SORTING\nBack-to-front ordering]

    F[PointGroupClass::RenderVolumeParticle\ndepth > 1] --> G{Translucent?\nAlpha test off?\nSorting enabled?}
    G -- No --> H[sort = false]
    G -- Yes --> I[sort = true\nAlways sorted regardless\nof Billboard flag\nnote: layered slices need depth order]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[PointGroupClass::Render] --> B{Billboard?}
    B -- No\nground-aligned --> C[sort = false\nUse BUFFER_TYPE_DYNAMIC_DX8\nNo back-to-front ordering]
    B -- Yes\nbillboard --> D{Translucent?\nAlpha test off?\nSorting enabled?}
    D -- No --> C
    D -- Yes --> E[sort = true\nUse BUFFER_TYPE_DYNAMIC_SORTING\nBack-to-front ordering]

    F[PointGroupClass::RenderVolumeParticle\ndepth > 1] --> G{Translucent?\nAlpha test off?\nSorting enabled?}
    G -- No --> H[sort = false]
    G -- Yes --> I[sort = true\nAlways sorted regardless\nof Billboard flag\nnote: layered slices need depth order]
Loading

Reviews (4): Last reviewed commit: "Clarify bugfix comment, add info comment..." | Re-trigger Greptile

@stephanmeesters stephanmeesters force-pushed the perf/ground-aligned-particles-nosort branch from fdcebaf to 45a97a7 Compare June 28, 2026 11:41
@stephanmeesters

Copy link
Copy Markdown
Author

@greptileai It should not apply to RenderVolumeParticle as these are layered particles that require sorting

@greptile-apps

greptile-apps Bot commented Jun 28, 2026

Copy link
Copy Markdown

The current PR diff only modifies Render(), so RenderVolumeParticle is unaffected — its sorting logic remains unchanged. However, your note raises an important concern for future maintainability: someone could mistakenly apply the same Billboard skip to RenderVolumeParticle to "keep parity," breaking layered particle rendering.

To guard against that, it would be worth adding a short comment in RenderVolumeParticle's sorting block explicitly documenting why the ground-aligned skip does NOT apply there. Can you point me to where RenderVolumeParticle computes its sort variable so I can suggest the right comment in context?

@xezon

xezon commented Jun 28, 2026

Copy link
Copy Markdown

In testing this actually appeared to resolve some rendering issues as ground particles would sometimes cut into nearby particles leaving hard edges

This is very nice. An annoying visual issue.

Does it now always fix this issue or does it depend on "random" sorting order?

@xezon xezon added Bug Something is not working right, typically is user facing Major Severity: Minor < Major < Critical < Blocker Performance Is a performance concern Gen Relates to Generals ZH Relates to Zero Hour Rendering Is Rendering related labels Jun 28, 2026
// Enable sorting if the primitives are translucent and alpha testing is not enabled.
const bool sort = (Shader.Get_Dst_Blend_Func() != ShaderClass::DSTBLEND_ZERO) && (Shader.Get_Alpha_Test() == ShaderClass::ALPHATEST_DISABLE) && (WW3D::Is_Sorting_Enabled());
// However, do not apply sorting for ground-aligned (i.e. non-billboard) particles.
// This is for performance reasons and because ground-aligned particles do not generally benefit from back-to-front sorting.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you also mention the visual improvement?

@stephanmeesters

Copy link
Copy Markdown
Author

Does it now always fix this issue or does it depend on "random" sorting order?

In theory, yes:

Particles do not write to the depth buffer (except for ALPHA_TEST particles), which means they do not clip through each other, unless you use a sorting renderer that sorts each triangle by Z and then draws them in order.

The sorted particles are drawn last in a frame so all of the ground-aligned particles should now appear behind the sorted particles.

The ground-aligned particles are now drawn in the order of how they are in the particle manager list so that should be consistent as well (no flickering etc).

(also, ALPHA_TEST particles are never sorted and are always billboarded.)

@xezon

xezon commented Jun 30, 2026

Copy link
Copy Markdown

Ok cool

@xezon xezon left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Tested. Looking good.

@xezon

xezon commented Jun 30, 2026

Copy link
Copy Markdown

The bot is complaining about RenderVolumeParticle

@stephanmeesters

Copy link
Copy Markdown
Author

Clarified the comment and changed from perf to bugfix as primary contribution, added an info comment to RenderVolumeParticle according to Greptile's suggestion

@stephanmeesters stephanmeesters changed the title perf: Render ground-aligned particles without sorting bugfix: Render ground-aligned particles without sorting Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Major Severity: Minor < Major < Critical < Blocker Performance Is a performance concern Rendering Is Rendering related ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants