Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

artifacts when RT-no-depth

Discussion in 'General Graphics' started by AlexHell, Jul 4, 2019.

  1. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167
    Hello! My another artifact is detected on android device. It doesn't reproduced at PC \ editor (include gles emulation).
    I'm localize artifact - it's due to disabled depth-buffer on RenderTexture, i.e. I create
    Code (CSharp):
    1. new RenderTexture(_resultTextureSize, _resultTextureSize, 0, RenderTextureFormat.ARGB32);
    then use it for blit (Graphics.Blit)
    1) with SMAA (subpixel morphological AA), which already have
    Code (CSharp):
    1. SubShader
    2.     {
    3.         ZTest Always Cull Off ZWrite Off
    and no-sampling-of-depth as I understand inside shader code
    result: when I render SMAA "Blend Weights Calculation" (pass 4) produces incorrect result texture

    .. it's strange also due to Graphic.Blit is only geometry-quad (not many-polygons), and wtf the result is incorrect and different when with\without~~depth-bits in RT.

    REMARK: SMAA use Color-edge-detection - 100% sure. Not use depth-edge-detection, more - the depth code is deleted from pixel-shader.

    2) related artifact with Camera.Render with render to RT-without-depth
    - when I render with Camera and Shader with ZTest Off + ZWrite Always - then it produces strange clipping of haotic-polygons, but my geometry is BackToFront-SORTED (100% sure, it's tested and also used for solid\transparent cases - the same code)
    - when I render with Camera to RT with-depth (24 bits in RT contsructor) when artifacts is gone

    - can disable ZTest\ZWrite or not disable - result is the same, i.e.
    \ when I Set {ZTest Off + ZWrite Always} and NOT-fix-by-enable-depth-bits - then artifact exist in android or editor-emulator, but artifact not exist on PC \ webgl (and editor without emulation)
    \ when NOT-set {ZTest Off + ZWrite Always} and NOT-fix-by-enable-depth-bits - then artifact exist
    \ when FIX-by-enable-depth-bits and Set {ZTest Off + ZWrite Always} - then artifact NOT-exist
    \ when FIX-by-enable-depth-bits and NOT-set {ZTest Off + ZWrite Always} - then artifact NOT-exist

    -----


    I'm use SMAA like this https://github.com/Chman/SMAA/blob/master/SMAA/Shaders/SMAA.shader but with fixes:
    Code (CSharp):
    1. // inside DEPTH - 3 pass
    2. float4 frag(fInput_edge i) : COLOR
    3.                 {
    4.                     return float4(0, 0, 0, 0); // NOTE: disabled, not needed for post-process AA
    5.                 }
    i.e. my version is NOT contains _CameraDepthTexture
    and also fix for webgl for loop-counter
    and e3-precision-for-android (tested - it works)

    Also original SMAA contains this comments
    Code (CSharp):
    1. // TODO: Stencil buffer not working for some reason
    2. // TODO: Stencil not working
    which say like autor can't understand Why stencil is not work, and depth buffer also can be a mess, which also can be the consequence of implicit-depth-using
    .. original (same as mine) have 0-depth-bits in RT.. but it's not work in my android with 0-bits, but work when 24-depth-bits

    -----


    The 1st artifact with SMAA incorrect result is not-reproduces in editor-emulator-gles-mode.
    It's also reproduced in part-of-webgl-users (but not in me) which use webgl-on-mobiles - but it's not as important as native-android-apk.
    This artifact also can be fixed by enable depth-bits on SMAA-intermediate-RT-s (2 count).
    I'm 100% sure of artifact case - it's depth-related when _reusableRt1 without-depth-bits in this code
    Code (CSharp):
    1. // create rt1, rt2
    2. _sMaa = new SubpixelMorphologicalAA.ImmediateSmaa(rt1, rt2);
    3.  
    4.  
    5. public RenderTexture Render(RenderTexture source)
    6.         {
    7.             GraphicsUtils.AssureRenderTextureIsCreatedNotLost(_reusableRt1);
    8.             GraphicsUtils.AssureRenderTextureIsCreatedNotLost(_reusableRt2);
    9.  
    10.             GraphicsUtils.ClearRenderTexture(_reusableRt1);
    11.             GraphicsUtils.ClearRenderTexture(_reusableRt2);
    12.  
    13.             // Edge Detection (source - gamma color space for color/luma edge detection)
    14.             Graphics.Blit(source, _reusableRt1, _smaaMaterial, PassEdgeDetection);
    15.  
    16.             // Blend Weights
    17.             Graphics.Blit(_reusableRt1, _reusableRt2, _smaaMaterial, PassBlendWeights);
    18.  
    19.             // todo debug
    20.             TextureSaveUtils.SaveRenderTextureToFile(_reusableRt1, "Q:\\SmaaStep1_Debug.png");
    21.             TextureSaveUtils.SaveRenderTextureToFile(_reusableRt2, "Q:\\SmaaStep2_Debug.png");
    22.  
    23.             // Neighborhood Blending
    24.             _smaaMaterial.SetTexture("_BlendTex", _reusableRt2);
    25.             Graphics.Blit(source, _reusableRt1, _smaaMaterial, PassNeighborhoodBlending);
    26.  
    27.             // todo debug
    28.             TextureSaveUtils.SaveRenderTextureToFile(source, "Q:\\PreSmaa_Debug.png");
    29.             TextureSaveUtils.SaveRenderTextureToFile(_reusableRt1, "Q:\\AfterSmaa_Debug.png");
    30.  
    31.             return _reusableRt1;
    32.         }
    tests:
    - when rt1=WITH-depth and rt2=WITH-depth = NO-artifacts
    - when rt1=WITH-depth and rt2=without-depth = NO-artifacts
    - when rt1=without-depth and rt2=WITH-depth = Artifacts
    - when rt1=without-depth and rt2=without-depth = Artifacts
    culprit is rt2=without-depth

    NOTE: no artifact when SMAA pass edge-detection (pass 2 for color), i.e. source RT without depth, _reusableRt1 without depth, when I dump PNG with _reusableRt1 (SmaaStep1_Debug.png) -- it's correct (equals in the case with-depth and without-depth of _reusableRt1 + _reusableRt2), i.e. artifact is not at the stage of edge-detection, but at blend-weight.

    ------

    The 2nd artifact is reproduced in editor-emulator-gles-mode and I see what Rt-result is broken when Camera renders to it. It can be fixed (and already is fixed) by enable depth-bits in RT when render from Camera to first-RT, then use many (my visual stack need of) intermediate RT-s without depth (for GPU-memory optimization which is needed too).
    I'm 100% sure of artifact case - it's depth-related when RT of camera.targetTexture == RT-without-depth-bits in this code
    Code (CSharp):
    1. _camera.targetTexture = rt;
    2. _camera.Render();
    3. _camera.targetTexture = null;
    ------------------------

    Those fixes of enabling-depth-bits is a mess and anti-optimization-of-gpu-memory, which already have optimized, but I must to return to this task and fix.

    ------------------------
    Also I have tested with and without checked "Disable Depth and Stencil" in android player settings - artifacts is not changes
    tests
    - inititially "Disable Depth and Stencil" it's not checked (enabled depth), RT with depth=0-bits -- artifacts exists
    - when I check it (disabled depth), RT with depth=0-bits -- artifacts exists
    - when checked (disabled depth), and RT with depth=24-bits -- NO artifacts
    .. very strange checkbox.. it's not work at all..

    -----
    My current code case-1 and case-2 is not related to each other. And it's not related to Camera-post-process - I do NOT have post-process on camera. Camera.Render() used multiple times manually, then use visualStack with my logic and many RT-s, then apply-AA (SMAA in this case) and then place result RT to screen RawImage.

    I clarify this to show what I don't use weird camera setup or postProcess.

    -----
    tested unity versions (build on):
    - Unity 5.6.5p4 (64-bit)
    - Unity 2017.4.29f1 (latest 2017, tested now)
    -----

    My current confusion and questions is

    1) Why ZTest Off + ZWrite Always is not give result as I expected when depth-bits is absent, i.e. no depth in RT.. but there are like sampling from Depth as I understand. Why it sample from depth \ or any other use of depth?

    2) From which RT \ texture it samples when I Camera.Render and RT is 0-bits ? My guess is 'gl_FragDepthEXT' (I'm take WARNING: 0:4: 'GL_EXT_frag_depth' : extension is not supported in WebGL on the part-of-users-of-web-version, but NOT in my android device). Or any other implicit Depth-texture exist?

    3) Is it probable what SMAA depth-edge-detection code not-fully-deleted and any-instruction-in-shader (which one?) can require-depth.. which lead to artifacts when depth-absent-on-RT. Also "stencil is not work" with no-reason-from-autor can be the culprit, or unity bug, for implicit-use-of-depth-from-rt-in-any-case.

    4) Is it probable of hardware bug?
     
    Last edited: Jul 4, 2019