Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

CustomRenderTexture shortcomings for making new texture

Discussion in 'General Graphics' started by andyz, Oct 13, 2020.

  1. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,285
    CustomRenderTexture is very useful - you can use it to make a texture in script from custom shaders etc.
    But it has a big shortcoming, it waits until the beginning of a frame to update, even when Update() is called on it in script.
    Why is this, can it not have an UpdateNow() for custom uses like texture generation?
     
  2. robinDMUnity

    robinDMUnity

    Unity Technologies

    Joined:
    Oct 13, 2020
    Posts:
    8
    Hi Andyz, may I ask why specifically you want to use CustomRenderTexture? Is it just for the ease of being able to attach a material for the update?
    Generally CustomRenderTexture has been designed to make things like multi-pass renders easier to handle.
    When you ask a CRT to update it will schedule the update and when it is time to draw the frame, all your CRT's are sorted and made sure they draw in the correct order before everything else. That might explain why there is no functionality such as UpdateNow() as it defeats that purpose.

    Is there functionality in Graphics.Blit() that is missing to achieve your goals? That might be a viable secondary route currently.
     
  3. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,285
    OK I will try Graphics.Blit if it works ok under HDRP
     
  4. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,285
    Yes Graphics.Blit is very useful, it is just odd (annoying?) that it repeats the texture across the entire render target (there is no clamp to rect) so you can not render one image here, one there etc. You have to build a shader/material to handle that it seems

    I would like a Graphics.DrawTextureToRenderTexture - src,dst, x,y,w,h (I have achieved with a Blit material but not so ideal)
     
  5. robinDMUnity

    robinDMUnity

    Unity Technologies

    Joined:
    Oct 13, 2020
    Posts:
    8
  6. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,285
    No it is to create procedural textures at runtime - indeed Blit will work, just requires a bit of shader effort which could be covered by an extra function or two in the Graphics API
     
  7. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    A Graphics.Blit option which allows for partial updates would be super useful, and hard to do with CustomRenderTexture (which supports zone based updates). Say we have a process that does:

    Code (CSharp):
    1. foreach (var layer in layers)
    2. {
    3.     Graphics.Blit(A, B, layer.material);
    4.     Swap(A,B);
    5. }
    This can let us process an arbitrary number of layers of texture data. But that gets expensive because your processing the whole texture every time. Custom Render Textures zones work well to optimize this if each layer only covers part of the texture, but then each layer would need to allocate its own CustomRenderTexture which would be very expensive memory wise verses double buffering them. So ideally, I'd love a Graphics.Blit which took a rect for what part of the target texture to update.
     
  8. linenum

    linenum

    Joined:
    Nov 16, 2020
    Posts:
    58
    This is how to create a RenderTexture from a CustomRenderTexture (with a Shader Graph shader) - based on " it waits until the beginning of a frame to update"....
    Code (CSharp):
    1.     public Shader shader;
    2.     void Start()
    3.     {
    4.         GameObject[] cubes = GameObject.FindGameObjectsWithTag("cube");
    5.         foreach (var cube in cubes)
    6.         {
    7.             StartCoroutine(SetupMainTex(cube));
    8.         }
    9.     }
    10.     IEnumerator SetupMainTex(GameObject cube)
    11.     {
    12.         Material mat = new Material(shader);
    13.         mat.SetColor("_Color1", Random.ColorHSV());
    14.         mat.SetColor("_Color2", Random.ColorHSV());
    15.         CustomRenderTexture crt = new CustomRenderTexture(16, 16);
    16.         crt.initializationMaterial = mat;
    17.         crt.initializationSource = CustomRenderTextureInitializationSource.Material;
    18.         crt.initializationMode = CustomRenderTextureUpdateMode.OnLoad;
    19.         yield return null;
    20.         RenderTexture rendTex = new RenderTexture(16, 16, 0);
    21.         Graphics.Blit(crt, rendTex);
    22.         rendTex.filterMode = FilterMode.Point; // pixelated
    23.         cube.GetComponent<Renderer>().material.SetTexture("_MainTex", rendTex);
    24.     }
     
    Last edited: Apr 29, 2023