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

Issues and possible improvements to transparency rendering #5943

Open
mvaligursky opened this issue Jan 15, 2024 · 7 comments
Open

Issues and possible improvements to transparency rendering #5943

mvaligursky opened this issue Jan 15, 2024 · 7 comments
Assignees
Labels
area: graphics Graphics related issue enhancement

Comments

@mvaligursky
Copy link
Contributor

The default framebuffer WebGL uses for rendering is RGB(A)8 buffer. The values written to it are expected to be in the display color space, which typically means sRGB. As this framebuffer is created by the canvas, we have no control over it, and it is not created with sRGB (EXT_sRGB) flag. Meaning the shader writing to it needs to manually encode values from linear to sRGB space.

LDR rendering

  • when rendering directly to the default framebuffer, the engine correctly encodes values to sRGB space at the end of shaders. This causes alpha blending to not be correct, as the blending takes place in sRGB space, instead of correctly in linear space, with the result getting encoded to sRGB. This is how PlayCanvas currently operates if rendering directly to the default framebuffer.
  • proposal to support linear workflow: https://www.w3.org/Graphics/Color/Workshop/slides/Russell.pdf (it does not seem to be progressing, see https://groups.google.com/a/chromium.org/g/blink-dev/c/tA7Av4fLQFY/m/oUw_k949AAAJ).
  • a workaround is rendering to a created framebuffer using sRGB, which would alpha blend correctly, and blit the framebuffer to the default framebuffer at the end of the frame. This is expensive, and so not typically used.
  • we also implement dithered transparency. As this does not depend on alpha blending, it's not affected by blending in gamma space and works correctly. The only problem is that when enabled, this looks visually different to alpha blending, as that is incorrect.

HDR rendering

  • When we render in HDR mode, we use float format of the internal render target in linear space. This makes alpha blending to work in linear space, which is correct.
  • We have problem with transparency dithering here if tone mapping is used - it does not match the correct alpha blending. The problem is that with dithering, the discarded and visible pixels are tone mapped, but as tone-mapping is not linear, it does not match the alpha blending, as non-blended values are tonemapped.
  • Transparency dithering works correctly if tone mapping is used, as long as TAA is used as well - as TAA resolves transparency by blending with history buffer, and this blending takes place before the tone mapping.

References:
KhronosGroup/WebGL#2474
mrdoob/three.js#23019
https://stackoverflow.com/questions/51032480/how-do-you-implement-a-gamma-correct-workflow-in-webgl2
https://groups.google.com/g/angleproject/c/5ITMg4_m8Ug
#5287

@MAG-AdrianMeredith
Copy link
Contributor

its not necessarily srgb though right? https://ccameron-chromium.github.io/webgl-examples/p3.html. but I guess this would actually help here as we're letting the hardware do it

@mvaligursky
Copy link
Contributor Author

True, but until we implement #5287, it's sRGB. Handling P3 is part of that issue.

@mvaligursky
Copy link
Contributor Author

Related Chromium issue I created exploring the sRGB in WebXR: https://partnerissuetracker.corp.google.com/issues/352345526?pli=1

@mvaligursky
Copy link
Contributor Author

conclusion regarding WebXR, from the issue above:

The mechanism for specifying a texture format for WebXR is the Layers API, which is not yet supported by Chrome but does have support in the Meta Quest browser. WebXR is not compatible with buffers allocated by drawingBufferStorage.

@mvaligursky
Copy link
Contributor Author

#6838 implements support for sRGB framebuffer on WebGPU, but also support for sRGB render target on all platforms (just not the default framebuffer on WebGL), allowing linear rendering.

@mvaligursky
Copy link
Contributor Author

mvaligursky commented Jul 22, 2024

Update on this.

  • the linear blending can be used on both WebGL and WebGPU if the color buffer of a render target uses some of the sRGB formats, for example SRGBA8
  • sRGBA8 format can be used as a canvas framebuffer format on WebGPU as well, using displayFormat member of createGraphicsDevice options
  • on WebGL the support is not implemented currently and the options are more limited:

@mvaligursky
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue enhancement
Projects
None yet
Development

No branches or pull requests

2 participants