pex-context icon indicating copy to clipboard operation
pex-context copied to clipboard

Multisampled framebuffer support

Open vorg opened this issue 3 years ago • 7 comments

Is available in WebGL 2

Example usage renderbufferStorageMultisample + blitframebuffer: https://stackoverflow.com/a/55976760/1527470

vorg avatar May 19 '22 10:05 vorg

Question about pex-context syntax though : is it fbo.blit(anotherFbo) or ctx.blit(fbo1, fbo2) We don’t really have resource class methods, there some but hidden like _dispose and you still do ctx.dispose(texture)

e.g. webgpu

const encoder = device.createCommandEncoder();
encoder.copyBufferToBuffer(srcBuffer, 0, dstBuffer, 0, 4);

Which would suggest ctx.blit(fbo1, fbo2) syntax.

But the thing is we don’t expose fbos…we just have passes...so maybe it’s actually

ctx.pass({
   color: [ colorTexture ],
   numSamples: 16 //auto allocate render buffer matching texture size, blit and resolve on pass end
}}

A bit automagic but it’s not like we blit fbos left and right outside of this single usecase ever.

Or even better:

ctx.pass({
   //auto allocate render buffer matching texture size, blit and resolve on pass end
   color: [ { texture: colorTexture, numSamples: 16 } ]
}}

vorg avatar May 19 '22 10:05 vorg

Live example here https://codesandbox.io/s/webgl-multi-sampled-mrt-fbos-1vhkif

vorg avatar May 19 '22 10:05 vorg

https://github.com/mrdoob/three.js/issues/23300#issuecomment-1100666026

Some notes (I'll repeat the obvious for the sake of being on the same page): • as mentioned above, multi-sampling for data textures is prone to error although invaluable for anything used to render to screen (i.e. your usual PBR result in slot 0, vertex colors or ids in slot 1 for selective post-processing) • all attachments (color or depth, etc.) of a multi-sampled FBO must be multi-sampled with the same number of samples • attachments of a multi-sampled FBO like renderBuffers or textures cannot be read from directly, they must be downsampled via blitFramebuffer before use. This includes methods like readPixels • blitFramebuffer can only copy one color attachment between FBOs at a time (one to all of another -- see issue 12 https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_blit.txt). This is an implementation detail, but worth noting as I did in my demo

vorg avatar May 19 '22 10:05 vorg

Spotted this from the three issue tracker.

If you need a more complete example as far as reviews made in three, see this gist which forgoes temporary FBO attachments when blitting and instead disassembles/reconstructs attachments https://gist.github.com/CodyJasonBennett/edbc4372d3c9a921ebc3e46cb5899ba8. This is less clean, but much more memory efficient.

Regarding the API, blit can copy any frame buffer -- whether that be user-created or native to the underlying canvas implementation. There might be a consideration for how one would copy to/from the canvas with this API. This is useful for where you might want to sample depth from a forward pass, often done in hybrid/forward+ rendering setups.

A constraint in WebGPU is that the mesh pipeline would also be multi-sampled, so this would not be isolated to the render passes. I'm not very familiar with Pex's internals, but this can be tricky to deal with from a design perspective.

CodyJasonBennett avatar May 25 '22 12:05 CodyJasonBennett

There is also in issue the blitFramebuffer can copy only one renderbuffer at the time although (manually) fixable. That's another vote for hiding complexity inside pex-context pass()

To do multiple ones, you need to do a Blit for each buffer, changing your READ_BUFFER for each buffer you want to blit, and select the corresponding draw buffer of the draw framebuffer. (source)

vorg avatar Nov 07 '22 23:11 vorg