OnPreRender/OnPostRender counterpart in SRP?

Using SRP, the messages OnPreRender/OnPostRender are not called.
Is this a temporary issue or a designed feature?
If the latter, what is the counterpart to call Graphics drawing functions?

You can find your answer is this post : Feedback Wanted: Scriptable Render Pipelines page-8#post-3408481

The closest match you can find are those:

  • public static event Action<Camera[ ]> beginFrameRendering;
    Called when SRP rendering begins. Do things like make frame dependent geometry or similar from this callback. Called by default in HD / LW pipe. If you write a custom pipe you need to issue the call yourself.

  • public static event Action beginCameraRendering;
    Called when camera rendering begins (per camera). Do things like camera dependent effects (planer reflection) or similar from this callback. Called by default in HD / LW pipe. If you write a custom pipe you need to issue the call yourself.

Is there no way to call events in HD/LW pipeline not at the beginning but at the end of rendering?
And does the fact the pipes are designed not to call functions in their rendering mean that we can no longer use Graphics.DrawMeshNow or any GL drawing functions under them?

I’m wondering this too. In the HDRP, I’m trying to use Graphics.DrawTexture specifically on a camera with a RenderTexture target texture and I tried using it within beginCameraRendering and beginFrameRendering with no results. Is this intended and/or are there alternatives?

We are working on adding in more callback hooks to LW pipeline currently. They will be quite different to the old hooks though and will be a combination of SRP context and Command buffers. There will not be arbitrary access to rendering like there is now. This is needed so that we can ensure that state is preserved in a valid way. This is one of the biggest issues with the old renderer.

Hi
How can I hook the Camera rendering events like OnPreRender, OnPostRender, OnRenderImage into SRP render loop .
If not possible what are their equivalents in SRP

how to use that beginFrameRendering event in our script?
I try to write that function but its not exist.

I need to use the ReadPixel() function for my texture

thanks!

What are you trying to achieve here ? First, ReadPixel can be a quite heavy operation, depending what and how you want to do with it. Second, the mentioned events are called before the rendering, so you will probably not read anything usefull.

To use it you create a function with the correct argument (Camera[ ] for beginFrameRendering and Camera for beginCameraRendering), and assign it to the current RenderPipeline.beginFrameRendering or RenderPipeline.beginCameraRendering

what about after the rendering?

Could you please develop your answer ?

I’m a publisher and I need to port my HBAO asset to the HDRP. I understand how to subscribe to beginCameraRendering event, but what to do in this event to inject your command buffer at an appropriate rendering stage ?
It seems there’s no rendering context passed as parameter so I’m kind of lost…

Sadly, for the moment we haven’t added a way to inject commands in the render context in those callbacks.
something like this is planned, to inject commands at some precises points in the render loop, but the team is trying to figure out a safe way to do it, that could also be coherent between LW and HD pipes.

So it is not an easy task.

2 Likes

Like a lot of others, I rely on 3rd party devs to shore up whatever isnt built into the engine, and I can already see that as much as I love HDRP, Im going to be waiting on some post processing stuff to make its way over.

I just hope this wont become a vaporware promise while trying to unify the two, and rather that some way of allowing devs to create whatever post processing stuff they want will be given to HD within a timeline of HD coming out of preview.

1 Like

Hi sorry for late reply, before the LRP I use the ReadPixel() on OnPostRender function.
I need that to copy image from Camera RenderTexture, and then read the pixel on certain coordinate

You can still use ReadPixel() in your scripts, but just no more in the callback we had before. It will grab what is currently on the screen.

you mean I can use the ReadPixel() like in the Update() function ?

Yes. It can be really slow, but it works.
This is how we use it in our graphic tests to capture the rendering of a camera, and it works with the built-in pipeline, lightweight, and HD : https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.testframework.graphics/Runtime/ImageAssert.cs

The important part of the code is this :

var rt = RenderTexture.GetTemporary(width, height, 24);
            Texture2D actual = null;
            try
            {
                camera.targetTexture = rt;
                camera.Render();
                camera.targetTexture = null;

                actual = new Texture2D(width, height, format, false);
                RenderTexture.active = rt;
                actual.ReadPixels(new Rect(0, 0, width, height), 0, 0);
                RenderTexture.active = null;

                actual.Apply();

               // At this stage, the texture "actual" can be read form the CPU and contains what the camera sees.

                AreEqual(expected, actual, settings);
            }
            finally
            {
                RenderTexture.ReleaseTemporary(rt);
                if (actual != null)
                    UnityEngine.Object.Destroy(actual);
            }
3 Likes

nice, thanks Remy!

Hi,

I need to clear a renderTexture. I did it like this:

public RawImage image;
RenderTexture rt;
Color transparent = new Color(0, 0, 0, 0);

void Start()
{
    rt = new RenderTexture(512, 256, 32);
    GetComponent<Camera>().targetTexture = rt;
    image.texture = rt;
}
void OnPreRender()
{
    Graphics.SetRenderTarget(rt);
    RenderTexture.active = rt;
    GL.Clear(true, true, transparent);

    Graphics.SetRenderTarget(null);
    RenderTexture.active = null;
}

The texture is used in UI and it needs to be cleared before any rendering starts (for transparency).
I added:

public RawImage image;
RenderTexture rt;
Color transparent = new Color(0, 0, 0, 0);

void Start()
{
    rt = new RenderTexture(512, 256, 32);
    GetComponent<Camera>().targetTexture = rt;
    image.texture = rt;
    RenderPipeline.BeginCameraRendering(GetComponent<Camera>());
    RenderPipeline.beginCameraRendering += OnBeginCameraRender;
}
void OnBeginCameraRender(Camera cam)
{
    Graphics.SetRenderTarget(rt);
    RenderTexture.active = rt;
    GL.Clear(true, true, transparent);

    Graphics.SetRenderTarget(null);
    RenderTexture.active = null;
}

But this clears the texture completely. How to do it in the LRP?

Hi,

This seams to work as expected, the texture is cleared, but nothing is written back to it. Could you maybe send a small repro project ?

Sorry for the delay. I’ll try to make a small project at the weekend and I’ll let you know.