-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Multisampling in FrameBufferSystem #6296
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this gets it wrong - you shouldn't have to do a manual blit
if you are rendering into a render-texture. In addition, you could add a multisample
property on RenderTexture
that defers to this.framebuffer.multisample
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The semantics are inconsistent - a render texture won't 'blend' if clear=false
in Renderer.render
& multisampling is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, "4. Strange conflation with MSAA" - I think that is because you are not clearing the frame buffer with the background before rendering to it. |
Oh, no, macs, my bane! I hate them really, I dont have one. I'll ask for a testing device on work tomorrow. There shoulnd't be a problem with clearMode, because its an input texture that should be cleared anyway. Maybe I'll add Exactly, case 4 is done when something is already drawn, and the problem is that users will do it anyway. We need a way to mitigate the damage, my solution is to apply AA to all shapes befure they start combining them. I've modified demo a bit to compare samples=4 and samples=8. |
@ivanpopelyshev Why are using resolution=.125 in your demo? |
MacOS/ iOS WebGL2 support is worst. |
@eXponenta The other PR works on my machine (the one with Renderbuffer classes). It is actually a problem with this PR. @ivanpopelyshev What machine are you testing on, does it have WebGL 2? |
His machine has fully WebGL2 support. |
@eXponenta WebGL 2 support depends on the browser I guess, not on the machine. |
It isn't fully true. |
@eXponenta Well, MacBooks of course have the graphics ability to support WebGL 2. The browsers are supposed to bind the WebGL API to a OpenGL backend. |
The heck is going on on apple devices? We'll know tomorrow when I get said devices from test team! Stay tuned! |
Codecov Report
@@ Coverage Diff @@
## dev #6296 +/- ##
==========================================
- Coverage 77.79% 77.16% -0.63%
==========================================
Files 186 183 -3
Lines 10219 9670 -549
==========================================
- Hits 7950 7462 -488
+ Misses 2269 2208 -61
Continue to review full report at Codecov.
|
Shame on me, I had a mistake in |
Need to test this thing on iOS 13.2 Safari . @SukantPal whats your device? |
@ivanpopelyshev It works now! (macOS Catalina, 2018 i7 MacBook Pro). And MacBooks don't "somehow" support WebGL 2 - Firefox & Chrome do on all of 'em. It is just that Safari developers aren't implementing that API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice man! WIll need to discuss with @SukantPal which of the two PRs should be merged in.
Currently i'm leaning towards this PR as there is less Code to get us MSAA.
But @SukantPal's PR seems more flexible.. my question would be is there anything other than MSAA we can achieve with blitting and renderBuffers?
* @param {number} samples number of samples | ||
* @returns {number} recommended number of samples | ||
*/ | ||
detectSamples(samples) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this? Can we rather, just check values are PO2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know what to put there. This thing works and is covered by a test. I don't know which values are available on different systems, I didn't research it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just enforce the use of the consts?
export enum MSAA_QUALITY {
NONE = 0,
LOW = 0,
MEDIUM = 4,
HIGH = 8
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing about pow2. I do not understand what do you want to put there. I made basic algorithm, it should work according to the test and specification. If user wants to specify 16 and some videocard actually allows it - fine. Btw, there's no guarantee about order and i use it. Maybe I should actually add sort()
somewhere just to be sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like there's no 16: https://webglstats.com/webgl2/parameter/SAMPLES
Maybe its my stupid time - I don't know what to write with those IF's. There will be more code in that case.
@bigtimebuddy @GoodBoyDigital I don't think we should really delay this any longer. If you want, we could finalize this pull request. I just want you to consider whether we should require users to do a We might also need to consider blend modes for multisample render-textures. Renderbuffer blits don't support "blending", and this will break some expected behaviors. Instead of blitting directly onto the "texture", we might need to blit into a secondary texture and then render that onto the actual render-texture (via a shader that will blend). |
This PR doesn't actually forbid a blitting with shader, it doesnt include it on low-level. I use extra filter for blitting in my fork, and I think it has to be part of high-level object, alongside with WebGL1 fallback and some other things. |
@ivanpopelyshev I don't understand what you said. "This PR doesn't forbid blitting with a shader". How? First of all, blitting can't be done by a shader (by definition). It just copying the pixels from a render buffer onto a texture (no blending, direct copy). "I use extra filter for blitting in my fork, and I think it has to be part of high-level object" - that doesn't make sense. All my complaint is that we're going to have to add a line after rendering to use multisample in PixiJS - app.renderer.render(circle, buf);
app.renderer.framebuffer.blit(); What is the problem if the blitting is handled as a part of the rendering pipeline. I don't think any user would expect to a blit after calling |
@ivanpopelyshev I still don't understand why your example uses 1/8th resolution on the textures. That just nullifies the effect of multisampling. |
To actually see that it works on a 4k screen. |
What do you see on a 4K screen? If you’re on a 4K screen, it will still just render as normal. On my screen, it has jagged edges and doesn’t look like a circle. You’re supposed to use 1x resolution so the multisample makes the effective resolution 8. The whole point is to multisample each pixel 8 times, not multisample 8 pixels 8 times. |
Pixels are half-red, that means AA is working :) |
28f4c7f
to
dadab0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of small documentation things. Otherwise looks good. Thanks for the demo in the description @ivanpopelyshev.
packages/constants/src/index.ts
Outdated
@@ -409,3 +409,22 @@ export enum MASK_TYPES { | |||
STENCIL = 2, | |||
SPRITE = 3, | |||
} | |||
|
|||
/** | |||
* Constants for multi-sampling antialiasing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like really more documentation about this feature being experimental and that there's a significant performance cost paid for using it. Also, it's not super obvious, but a code example usage setting renderer.framebuffer.multisample
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
linked it to Framebuffer#multisample. Don't want to ctrl+C everything.
Codecov Report
@@ Coverage Diff @@
## dev #6296 +/- ##
=========================================
+ Coverage 74.27% 76.7% +2.42%
=========================================
Files 85 76 -9
Lines 4615 4142 -473
=========================================
- Hits 3428 3177 -251
+ Misses 1187 965 -222 Continue to review full report at Codecov.
|
@ivanpopelyshev Should we have a fallback to higher resolution if multisampling is not supported on the device? When forcing WebGL 1, the half-red pixels do not show up. |
@bigtimebuddy @GoodBoyDigital I approved this - but I did have concerns about requiring a |
@SukantPal good catch! I put it in |
Thanks everyone for getting this feature through! |
My minimal implementation for #6288
Demo: https://www.pixiplayground.com/#/edit/ZbmXFH7nt11L70Ux2jUy8
🎁 Added
Framebuffer.#multisample
- number of samples that user wants. By default its 0 so shortcutif (multisample)
can be used.Extra operation
blit
that has to be called afterrenderer.render
if you think that msaa is enabled on renderTexture. Operation corresponds to low-levelgl.blitFramebuffer
and requires extra internal framebuffer object to bind the texture.How it works
API is secure - It won't fail in case of WegGL1 or if there's not enough samples.
Internally,
colorTextures[0]
for MSAA renderbuffer, so, theoretically, MRT still should work. I didn't test it though. However,colorTextures[0]
still exists - that's where we blit the data for later usage.Why not RenderBuffer object
I do not want to add new objects and abstractions in vanilla PixiJS for a case that cant be used in production.
However, it is good as a temporary solution for demos and prototyping games. Basically, its a Toy.
Two-three hundred lines of code are not much, we just mirror WebGL2 API a bit so people can experiment how it looks.
Future:
Both PR's should be small.
RenderTextureSystem
Add high-level
blit
operation, that can will either use framebuffer blit, either texture copy either scaling filter, that will enable trivial WebGL1 fallback.FilterSystem
We can enable usage of custom texture pools per object, specify that we need particular renderTexture for dealing with a container, and that texture can have multisampling.
What cant be in vanilla:
MSAA is slow. I don't believe anyone will use it in production even after those PR's.
I'm working on a real solution that can be used in production by heavy projects:
If this PR will be merged, I won't need to add framebuffer hacks in the plugin.
Another plugin
I hope that this thing covers @SukantPal case for filters, maybe not right now but after next FilterSystem PR.