Search Unity

Bug Blit to/from RenderTexture Texture2DArray slice not working in WebGL (Built-in and URP)

Discussion in 'General Graphics' started by XANTOMEN, Jul 19, 2022.

  1. XANTOMEN

    XANTOMEN

    Joined:
    Dec 18, 2012
    Posts:
    41
    Hi, I made a Bug Report to Unity but wanted to also make sure that I'm not just being dumb about it and there's some documentation I have not read on why this wouldn't work or something (and ask if someone knows a workaround).

    The following will work in the Unity Editor and in Windows builds (both with Direct3D and with OpenGL) but won't work in WebGL builds:

    Doing a Graphics.Blit or CommandBuffer.Blit into a slice of a RenderTexture that is not the first one.

    So for example:

    sourceTexture -> Any texture type
    destinationTexture -> A RenderTexture of dimension "Texture2DArray".

    The following line will copy sourceTexture to depth 0 of destinationTexture:

    Graphics.Blit(sourceTexture, destinationTextire, 0, 0);

    The following line will NOT copy sourceTexture to depth 1 of destinationTexture (in WebGL):

    Graphics.Blit(sourceTexture, destinationTexture, 0, 1);

    It's also possible that the error is instead on the retrieval (from slice to a third texture) instead, but previous tests make me think the Blit to slice is erroneous.

    Currently trying it in Unity 2021.3.6f1 LTS but I've also tried on 2020.3.26f LTS.

    Also, I've seen someone else was having the same issue and never received a reply: https://answers.unity.com/questions/1893575/blit-into-texture2darray-slice-not-working-in-webg.html

    I'm attaching a full test project in the post, and these are the Editor and WebGL results:

    Editor_Results.png WebGL_Results.png

    Thank you for any guidance.
     

    Attached Files:

    nxtboyIII likes this.
  2. georgerh

    georgerh

    Joined:
    Feb 28, 2020
    Posts:
    72
    If source and destination are the same size and texture format, you could use CopyTexture instead.

    But be aware of the master texture limit pitfall.
     
    XANTOMEN likes this.
  3. XANTOMEN

    XANTOMEN

    Joined:
    Dec 18, 2012
    Posts:
    41
    I wish, but I can't because WebGL does not support CopyTexture :(
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    Doh...

    Maybe you could use the SetRenderTarget overload that takes a mip, face and slice and do it manually. Technically, that's exactly what Blit is doing (I think) but maybe it works if you do it manually.
     
  5. XANTOMEN

    XANTOMEN

    Joined:
    Dec 18, 2012
    Posts:
    41
    Interesting, thank you for pointing me towards that function, I didn't know it!

    So, I don't understand how you'd do SetRenderTarget to copy a texture into another and test the situation described in the post (and attached in a .zip file), would you mind dropping some lines of code so I understand better how it'd work? How would I set the source to copy from if not the camera?

    However, this idea brought me to testing an alternative in my original URP project (not this test project), where what I prefer is indeed to copy from Camera to texture2DArray directly (and not from texture to texture), and I've used CommandBuffer.SetRenderTarget for that in the Configure function of my ScriptableRenderPass, and my result is:

    It works on Editor (renders to all slices), it does not even copy to depthSlice 0 in WebGL :S (So, a worse result than before, where I could at least have my first slice show up)

    (Altho, this one last test does give a console Error, so I'll look into it ("Feedback loop formed between Framebuffer and active Texture."))
     
    Last edited: Jul 20, 2022
  6. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    See attached file. Haven't tested it with WebGL, though.
     

    Attached Files:

    • Copy.cs
      File size:
      2.8 KB
      Views:
      226
    XANTOMEN likes this.
  7. XANTOMEN

    XANTOMEN

    Joined:
    Dec 18, 2012
    Posts:
    41
    Thank you!! You rock!

    It seems like that workaround works, plus to be able to test I had to do a Blit from destination texture to the canvas textures I made, so I'm able to confirm then that Bliting normally FROM depthSlice is fine, but Bliting TO depthSlice is not... (in WebGL)

    Ay ay ay....

    Hope they fix the bug, but for now I'll attempt to do this in URP, hopefully I'm still lucky there
     
    c0d3_m0nk3y likes this.
  8. XANTOMEN

    XANTOMEN

    Joined:
    Dec 18, 2012
    Posts:
    41
    OMG you gotta be kidding me....

    I had a hunch and tried this, where mat is the copy of Hidden/BlitCopy you made:

    cb.Blit(testingRT_00, destinationTexture, mat, 0, 0);
    cb.Blit(testingRT_01, destinationTexture, mat, 0, 1);

    Instead of:

    cb.Blit(testingRT_00, destinationTexture, 0, 0);
    cb.Blit(testingRT_01, destinationTexture, 0, 1);

    And removed the rest of your code (the workaround), so I am again making the straight Blit from the first test project I reported about, just with the material as an argument.

    .... Turns out with material it works and without it it does not...

    Man, sometimes Unity pisses me off.... I've spent 5 days on this lol...

    Thank you for your help
     
    Last edited: Jul 20, 2022
    nxtboyIII and c0d3_m0nk3y like this.
  9. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    I feel you! (already spending 2 weeks to work around a performance issue with SpeedTree trees)

    Glad, we found a workaround at least.
     
    XANTOMEN likes this.
  10. nxtboyIII

    nxtboyIII

    Joined:
    Jun 4, 2015
    Posts:
    281
    Dude, thank you so much. I ran into this exact same issue and it fixed it to just add a material.
     
    XANTOMEN likes this.