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

Examples: Postprocessing fullscreen triangle optimization #21358

Merged
merged 2 commits into from
Mar 30, 2021

Conversation

trinketmage
Copy link
Contributor

Description

The postprocessing is using a fullscreen PlaneGeometry for fullscreen fragmentShader, it can lead to quad overshading. Here a fullscreen Triangle instead.

alt text

@mrdoob
Copy link
Owner

mrdoob commented Feb 25, 2021

I remember we used this technique for rendering particles in my demoscene days back in 2002 🤓

The rationale is indeed interesting.

We can probably implement this in THREE.Sprite too.

@mrdoob mrdoob added this to the r127 milestone Feb 25, 2021
@mrEuler
Copy link
Contributor

mrEuler commented Feb 25, 2021

Just week ago had conversation with coworkers about this. 👍

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 25, 2021

I think the source code should only be modified in that way when to a comment is added that links to a respective explanation. Without knowing this approach, new devs are going to wonder about this setup.

@WestLangley
Copy link
Collaborator

Also see this article by @luruke for additional suggestions. background_vert.glsl.js uses a similar trick.

@mrdoob mrdoob modified the milestones: r127, r128 Mar 30, 2021
@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

@zeux Do you know if this is a good thing to do with current/future GPUs?

@takahirox
Copy link
Collaborator

Coincidentally I have been thinking of this technique, too, to improve our post-processing performance lately. Real-Time Rendering mentions in Chapter 12 that image processing with this technique is 10% faster than the one with quadrilateral on AMD GCN architecture, because of better cache coherency. And similar to @mrdoob I was thinking whether this technique is still good on other architectures/GPUs.

@zeux
Copy link
Contributor

zeux commented Mar 30, 2021

Yeah full-screen triangle is never worse than a full-screen quad for post-processing. It can be better depending on the GPU; I'd generally expect gains in the 0-5% range depending on the effect and GPU in question, I've seen 8% quoted in some presentations but it's usually more of an outlier.

The issues this addresses are, in order of increasing severity:

  • Quad overshading mentioned in the original commit; GPUs need to process pixels in groups of 2x2, and they typically don't merge quads from different triangles. On a 1000x1000 RT this results in the diagonal being shaded redundantly twice, so an extra ~2000 pixels = 0.2% waste
  • Wave packing efficiency. GPUs process pixels (and vertices) in large groups, depending on the architecture the group size varies but can be up to 64. Often rasterizers generate workload for large triangles in tiles and different tiles can't be merged across two large triangles because there is too much extra work generated between these tiles; given a hypothetical 8x8 raster tile and 64-pixel wave, you end up shading each diagonal tile twice which is a waste of 64 pixels per 8x8 diagonal tile = 8000 pixels in 1000x1000 RT = 0.8% waste
  • Cache efficiency. The details are very dependent on the architecture, texture tiling modes, rasterization order and shader in question, but given that GPUs often fetch and cache small tiles of textures instead of a single pixel, the problem with wave efficiency can also affect cache efficiency and result in pixels around the diagonal filling the texture cache and not using some of the results, only to refill it again when the waves from the other triangle start processing

A full-screen triangle typically solves all of these issues as GPUs generate full waves/quads of pixels in correct order and process all of them without waste. The only downside is that it's harder to use this if you only want to run postfx on part of your screen, although you can use scissor rectangles for that.

@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

@zeux Many thanks for the explanation! 🙏

Okay, I'll just merge it and clean it up then.

@mrdoob mrdoob modified the milestones: r128, r127 Mar 30, 2021
@mrdoob mrdoob merged commit f3fc055 into mrdoob:dev Mar 30, 2021
@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

Thanks!

@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

Clean up: 0e8e043

@yszhao91

This comment has been minimized.

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.

8 participants