Search Unity

Is it possible to use a 2D texture array to update the mesh's texture by only one element?

Discussion in 'Shaders' started by Mr_Admirals, Dec 30, 2018.

  1. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Work on my snow deformation shader continues, and I'm beginning to near completion of the project. My main final hurdle that I'm dealing with is with how to extend the snow deformation area to work on as large of a mesh as possible.

    My current solution I'm working on is to programmatically divide the starting mesh into submeshes that will then use a trigger collider to detect whether the localized snow deformation pipeline should be turned on or off. This is being done via a C# script. However, I recently learned about 2D texture arrays. My knowledge on them is limited, so I'm wondering if a texture array assigned to a large mesh can be updated only by textures in the element that are currently being written to. As in only a small section of the mesh's texture is actually updated per frame. Or do all the array elements need to be fed through the pipeline regardless?

    I'm working with what I feel is a rather complicated problem, so I'm definitely open to suggestions or even ideas of their own on how to tackle the problem. Let me know your thoughts and opinions, or if I need to elaborate.
     
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    I suppose you use high resolution render textures to store deformation data "directly". Imagine, for example, ground tile with size 64m x 64m and texture 2048x2048 = accuracy ~ 0.03 meters per pixel. Now, for filling area 1km x 1km we need 256 tiles and 256 textures. For the best quality, we can choose uncompressed floating point render textures. And multiply memory usage from single texture by 256. Finally, VRAM requirements for game increase drastically :)

    So, first problem is efficient memory management. We can "pack" deformation data so we can use much less textures.
    Also we can "stream" textures (convert render texture from previous terrain tile to normal texture, dump to HDD, load data from disk for current tile etc.).
    Maybe use Sparse Textures ?
    https://docs.unity3d.com/Manual/SparseTextures.html

    Texture 2D array uses custom asset:
    https://gist.github.com/Spaxe/57de76c993a4dc8bb37275acbe597ef2
    https://forum.unity.com/threads/how-to-use-texture-array-in-shader.356536/

    I think it will be better to use 3D render texture
     
  3. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Thank you for the reply Przemyslaw!

    Hmm... In all of this troubleshooting, I did never take into account how much stress I'd be putting on the VRAM.

    A few questions:

    1. When you say terrain tile, do you mean to actually cut up the terrain mesh into physically separate meshes?
    2. How would one go about packing the deformation data?

    Sparse textures actually look very promising. Is that what you're using for Tank Engineer?

    What makes a 3D render texture better than a 2D one in this instance?
     
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
  5. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    So I was reading up about Unity's Custom Render Textures. They might be just what I need though I'm not too sure as the Unity Manual says when writing shaders for them you can't update vertex positions. I suppose I could just Blit() the final output to a non-custom render texture to get around that, but that defeats the purpose of only updating the texture by sections.

    Hmm... This problem is just so tricky, but I know there's a solution because Red Dead Redemption 2 managed to do it.