Search Unity

Camera Clear Flags "Don't Clear" and "Depth Only" don't work as expected on WebGL

Discussion in 'Web' started by momo_the_monster, Jan 25, 2017.

  1. momo_the_monster

    momo_the_monster

    Joined:
    Sep 3, 2014
    Posts:
    16
    I have a project with a Camera's Clear Flags set to "Depth Only".
    In the editor, this works as expected, with each frame drawing upon the last.
    When I export for WebGL, it clears to black each frame.

    Is it possible to keep WebGL from clearing each frame? I've tried several shader approaches as well, writing the frame to a RenderTexture and accessing that on the next frame. That also works in the editor but gives a blank (black) output in a WebGL build.
     

    Attached Files:

  2. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    It's a bug and here is the public tracker for it:
    https://issuetracker.unity3d.com/issues/clear-flags-doesnt-work-properly-on-webgl

    I expect the fix to be in 5.6 and in a 5.5 patch in the coming weeks.

    Thanks for reporting the issue.
     
  3. Pham-Thanh-Binh

    Pham-Thanh-Binh

    Joined:
    Nov 9, 2016
    Posts:
    3
    oh It didn't fix in 5.6. I got it in 5.6
     
  4. Pham-Thanh-Binh

    Pham-Thanh-Binh

    Joined:
    Nov 9, 2016
    Posts:
    3
    upload_2017-6-12_19-54-12.png

    This is result when i try to set depth only for cube camera.
     
  5. roka

    roka

    Joined:
    Sep 12, 2010
    Posts:
    598
    Disable the AA on your depth camera to solve the problem until we got a patch.
     
  6. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    I should have provided an update on this issue. TLTR: We had to revert the fix before 5.6 release because of performance concerns, in fact if you look at the bug tracker, it will say that the bug will not be fixed. However, it's possible to workaround it.

    By default, the browser always clears the main render buffer. This is because it is more efficient to do so, than to preserve the image from the current frame to the next. This default behavior can be modified on webgl context creation via preserveDrawingBuffer attribute.

    At the moment, there is no way to change this attribute via scripting/ui, however, you can workaround it:
    - open PlaybackEngines/WebGLSupport/BuildTools/Emscripten/src/library_html5.js from Unity installation folder
    - search for preserveDrawingBuffer assignment in emscripten_webgl_init_context_attributes
    - change it's value from 0 to 1
    as follows:
    Code (csharp):
    1.  
    2. {{{ makeSetValue('attributes', C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer, 1, 'i32') }}};
    3.  
    A cleaner solution is to use an additional camera (which will not clear) to render your scene to a render texture, then blit the image to the main camera.
     
  7. Pham-Thanh-Binh

    Pham-Thanh-Binh

    Joined:
    Nov 9, 2016
    Posts:
    3
    Thanks you roka. Your suggest work fine.

    Thanks Marco-Trivellator : I not yet tried your suggest. Anyway, thanks you for your help.
     
  8. roka

    roka

    Joined:
    Sep 12, 2010
    Posts:
    598
    On the version 5.6.1P4, my solution "Disable the AA on your depth camera to solve the problem until we got a patch." do not work anymore, if we enable the AA on the quality setting and if we have 2 camera , the Orthographic camera do not render in all clear flag.
     
    Last edited: Jun 19, 2017
  9. Chris_Entropy

    Chris_Entropy

    Joined:
    Apr 11, 2011
    Posts:
    202
    Are there any news on this problem? Will this be fixed in one of the 2017 Versions?
     
  10. kevin-masson

    kevin-masson

    Joined:
    Sep 24, 2018
    Posts:
    73
    Will this be fixed in one of the 2019 versions?
     
  11. Voronoi

    Voronoi

    Joined:
    Jul 2, 2012
    Posts:
    589
    @Marco-Trivellato I don't know if I'm doing this correctly, but the only way I can get a Mac OSX build to render as in the Editor is to create 2 cameras and a render texture. This seems like a complicated way to do what should be easier and fast. The Render texture is slow when I increase the resolution.

    Am I missing something? Is there a way to just have one camera in the scene and not have to use a rendertexture when the desired look is to have the camera clear flags set to depth only?
     
  12. Emrys95

    Emrys95

    Joined:
    Sep 7, 2018
    Posts:
    4
    bump, this isn't working in 2019.4 also as far as I can tell, tried both editting index.html and .js in webgl to preserve buffers, requiring the usage of rendertextures and more memory. Is there still no fix to this for WebGL?
     
  13. Visama

    Visama

    Joined:
    Jun 27, 2019
    Posts:
    4
    It isn't working in 2020 version. I've tried disabling AA but it doesn't fix it. I tried a RenderTexture too, but now the problem appears even in PC version, not only WebGL.
     
  14. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    We are not currently tracking an active WebGL specific bug regarding camera color clearing. Does the workaround mentioned in the bug link above not work? If it does not, please raise a bug report with a test case.
     
  15. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    547
    It's this bug apparently.
     
  16. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    In that bug it was suggested that the preserveDrawingBuffer parameter should be used to keep color from clearing. That should still be the case. That is why I am asking whether the workaround posted in the bug link works or not?
     
  17. saermuk

    saermuk

    Joined:
    Aug 10, 2020
    Posts:
    13
    2020 1.2f.1 Still now...... Camera Depth Error.png
     
  18. saermuk

    saermuk

    Joined:
    Aug 10, 2020
    Posts:
    13
    I have finished solved this error.

    Use "Raw Image" and "Render Texture"

    version : 2020.2.1f1
     
  19. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    Routing via a render texture is certainly one option.

    I am surprised about there being a relatively large number of people reporting this issue. To understand the problem better, can someone illustrate what kind of rendering feature/use case you are doing that requires not clearing the color buffer across frames?

    There are three major difficulties with implementing support for this to WebGL: tile-based renderer performance, browser compositing performance, and web capabilities.

    First, on the web, WebGL API has a built-in behavior that the canvas color target is cleared to black between rendered frames. This is a built-in feature that can be worked around/disabled via that `preserveDrawingBuffer: true` flag. However that flag is applied at game/page startup time, and not something that can be toggled at runtime. So if that flag is enabled, then all cameras in the application will never clear the color, independent to what the Unity Camera setting is set to. This means that we are unable to map the Camera Clear option to `preserveDrawingBuffer: false/true` at runtime.

    Then, there is the issue with browser compositing performance. Browser compositors have been designed with the `preserveDrawingBuffer: false` option in mind. There is a browser rendering performance loss (apparently small, but still there) with enabling `preserveDrawingBuffer: true` in a browser. According to Google, the option should be used primarily for debugging, and main reason that `preserveDrawingBuffer: true` exists in the first place is to let ease the development of WebGL unit test suites.

    Then, there is another issue with tile based GPUs (primarily mobile devices). Tile-based GPUs have very fast dedicated but small "tile memory" on the GPU die, and then larger and slower DRAM memory that is generally shared with the main CPU. The way that these GPUs work is that they hold framebuffers on the fast tile memory on the GPU. When a frame starts, if it can be started with a clear/black framebuffer state, the GPU can issue a very fast "load this render target with clear color=(0,0,0,0)" to start rendering. If the previous frame should be preserved, then it GPU should issue a "load this image from the slow DRAM" operation instead. This loses performance (not much, but still a loss)

    To implement support for disabling Camera Clear Color on web builds, we could always build with `preserveDrawingBuffer: true` and take a performance impact, or we could implement a manual indirection via a render to texture based option, which would be even slower. That brings me back to the original question: how many users need this, and for what purpose?

    To my understanding the most general use case for omitting camera color clear at frame start would be to optimize GPU memory copies on non-tile-based GPUs. I.e. to optimize performance. If that is the desired use case, then the existing behavior in Unity is already optimal, hence the reason that the issue was WontFixed. Are there some other use cases that I am missing?

    Note that all of the above explanation specifically only applies to the back buffer of the web Canvas element. If we are dealing with offscreen render targets, those should allow color clearing options as usual, because they are not tied to the browser's canvas element compositor in any way.
     
    Last edited: May 20, 2021
    kevin-masson likes this.
  20. kevin-masson

    kevin-masson

    Joined:
    Sep 24, 2018
    Posts:
    73
    Thanks a lot for all those details ! It makes the problem much easier to understand.

    We use that feature to render one frame and display it continuously to the user. Pretty much like a camera snapshot. To implement that, we simply redirect using a render texture and it works great for us.
     
    jukka_j likes this.
  21. nixcry

    nixcry

    Joined:
    Mar 13, 2017
    Posts:
    5
    I managed to make this right in Unity 2019.4.11.
    Key points:
    1. Use "Raw Image" instead of "Image" to represent the targeted render texture.
    2. To properly cut out the secondary camera's background, set the Background Type of the secondary camera to "Solid Color" with an alpha of "0".
    upload_2021-5-10_17-46-13.png
    upload_2021-5-10_17-41-11.png
    upload_2021-5-10_17-43-42.png

    To make things clear, all the scene screenshots are from Firefox Browser, not Unity Editor
     

    Attached Files:

    jukka_j likes this.