CustomRenderTexture shortcomings for making new texture

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?

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.

OK I will try Graphics.Blit if it works ok under HDRP

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)

Is your goal to add multiple textures together in one larger texture? Then something like this might help Unity - Scripting API: Texture2D.PackTextures.

If not, then I think using Blit with a custom shader is indeed the best option to copy to smaller rectangles in a texture.

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

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:

foreach (var layer in layers)
{
    Graphics.Blit(A, B, layer.material);
    Swap(A,B);
}

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.

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"…

    public Shader shader;
    void Start()
    {
        GameObject[] cubes = GameObject.FindGameObjectsWithTag("cube");
        foreach (var cube in cubes)
        {
            StartCoroutine(SetupMainTex(cube));
        }
    }
    IEnumerator SetupMainTex(GameObject cube)
    {
        Material mat = new Material(shader);
        mat.SetColor("_Color1", Random.ColorHSV());
        mat.SetColor("_Color2", Random.ColorHSV());
        CustomRenderTexture crt = new CustomRenderTexture(16, 16);
        crt.initializationMaterial = mat;
        crt.initializationSource = CustomRenderTextureInitializationSource.Material;
        crt.initializationMode = CustomRenderTextureUpdateMode.OnLoad;
        yield return null;
        RenderTexture rendTex = new RenderTexture(16, 16, 0);
        Graphics.Blit(crt, rendTex);
        rendTex.filterMode = FilterMode.Point; // pixelated
        cube.GetComponent<Renderer>().material.SetTexture("_MainTex", rendTex);
    }