Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

OnPreRender/OnPostRender counterpart in SRP?

Discussion in 'Graphics Experimental Previews' started by kraihd, Jun 13, 2018.

  1. kraihd

    kraihd

    Joined:
    Sep 10, 2015
    Posts:
    9
    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?
     
  2. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    You can find your answer is this post : https://forum.unity.com/threads/fee...e-render-pipelines.470095/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<Camera> 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.
     
  3. kraihd

    kraihd

    Joined:
    Sep 10, 2015
    Posts:
    9
    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?
     
    Last edited: Jun 15, 2018
  4. kenamis

    kenamis

    Joined:
    Feb 5, 2015
    Posts:
    327
    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?
     
  5. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,087
    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.
     
  6. partha-d

    partha-d

    Joined:
    May 28, 2018
    Posts:
    8
    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
     
  7. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    14
    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!
     
  8. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    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
     
  9. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    336
    what about after the rendering?
     
  10. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    507
    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...
     
  11. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    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.
     
    jimmikaelkael and DGordon like this.
  12. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    347
    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.
     
    jimmikaelkael likes this.
  13. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    14
    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
     
  14. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    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.
     
  15. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    14
    you mean I can use the ReadPixel() like in the Update() function ?
     
  16. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    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-Technologi...testframework.graphics/Runtime/ImageAssert.cs

    The important part of the code is this :
    Code (CSharp):
    1. var rt = RenderTexture.GetTemporary(width, height, 24);
    2.             Texture2D actual = null;
    3.             try
    4.             {
    5.                 camera.targetTexture = rt;
    6.                 camera.Render();
    7.                 camera.targetTexture = null;
    8.  
    9.                 actual = new Texture2D(width, height, format, false);
    10.                 RenderTexture.active = rt;
    11.                 actual.ReadPixels(new Rect(0, 0, width, height), 0, 0);
    12.                 RenderTexture.active = null;
    13.  
    14.                 actual.Apply();
    15.  
    16.                // At this stage, the texture "actual" can be read form the CPU and contains what the camera sees.
    17.  
    18.                 AreEqual(expected, actual, settings);
    19.             }
    20.             finally
    21.             {
    22.                 RenderTexture.ReleaseTemporary(rt);
    23.                 if (actual != null)
    24.                     UnityEngine.Object.Destroy(actual);
    25.             }
     
  17. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    14
  18. dariuszpietrala

    dariuszpietrala

    Joined:
    Oct 5, 2012
    Posts:
    148
    Hi,

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

    Code (CSharp):
    1. public RawImage image;
    2. RenderTexture rt;
    3. Color transparent = new Color(0, 0, 0, 0);
    4.  
    5. void Start()
    6. {
    7.     rt = new RenderTexture(512, 256, 32);
    8.     GetComponent<Camera>().targetTexture = rt;
    9.     image.texture = rt;
    10. }
    11. void OnPreRender()
    12. {
    13.     Graphics.SetRenderTarget(rt);
    14.     RenderTexture.active = rt;
    15.     GL.Clear(true, true, transparent);
    16.  
    17.     Graphics.SetRenderTarget(null);
    18.     RenderTexture.active = null;
    19. }
    The texture is used in UI and it needs to be cleared before any rendering starts (for transparency).
    I added:

    Code (CSharp):
    1. public RawImage image;
    2. RenderTexture rt;
    3. Color transparent = new Color(0, 0, 0, 0);
    4.  
    5. void Start()
    6. {
    7.     rt = new RenderTexture(512, 256, 32);
    8.     GetComponent<Camera>().targetTexture = rt;
    9.     image.texture = rt;
    10.     RenderPipeline.BeginCameraRendering(GetComponent<Camera>());
    11.     RenderPipeline.beginCameraRendering += OnBeginCameraRender;
    12. }
    13. void OnBeginCameraRender(Camera cam)
    14. {
    15.     Graphics.SetRenderTarget(rt);
    16.     RenderTexture.active = rt;
    17.     GL.Clear(true, true, transparent);
    18.  
    19.     Graphics.SetRenderTarget(null);
    20.     RenderTexture.active = null;
    21. }
    But this clears the texture completely. How to do it in the LRP?
     
  19. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    245
    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 ?
     
  20. dariuszpietrala

    dariuszpietrala

    Joined:
    Oct 5, 2012
    Posts:
    148
    Sorry for the delay. I'll try to make a small project at the weekend and I'll let you know.
     
  21. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    990
    Curious where these are now.. Has there been already some work done to get the post callbacks in built-in HDRP?
     
  22. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    870
    No public static event Action<Camera> endCameraRendering; ?
     
  23. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    870
    Please add UnityEngine.Experimental.Rendering.RenderPipeline.endCameraRendering, it would be immensely helpful.
     
    PolayToy and kmedved like this.
  24. Atrixx

    Atrixx

    Joined:
    Feb 8, 2012
    Posts:
    17
    It would be extremely helpful - would someone from the unity team be able to shred some light if this event callback will come to the engine?

    @Remy_Unity
     
  25. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    365
    We are adding endcamera and endframe for 19.1. Also we will expose a render context in those callbacks.
     
    Thrawn75 and rizu like this.
  26. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    990
    Thrawn75 likes this.
  27. Thrawn75

    Thrawn75

    Joined:
    Nov 16, 2014
    Posts:
    2,138
    Looking forward to merging that PR @phil_lira. Thanks.
     
  28. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    990
    There are now merged but how do you actually use these from c#?

    Edit: Nevermind, peeked inside dll and finally found that RenderPipelineManager has these now. Docs don't list the endCameraRendering one yet but it's there.
     
    Last edited: Feb 28, 2019
  29. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    183
    Hey, I've been trying to do something like temporarily change fog settings for certain cameras through script.

    With legacy Render pipeline, just adding a script that has OnPreRender() and OnPostRender() methods to a camera and it works. But now I have to add an event listener to a global RenderPipelineManager, which fires events everytime any camera tries to render something. And I have to compare the camera component to determine if that specific camera is my desired one or not. And this gets worse if the number of cameras is big.

    If possible, why don't you expose those events from a Camera component? Then I'll add an event listener to that camera only and I don't have to bother all the other cameras at all.
     
  30. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    990
    But you can't really have tons of active cameras in the first place due to the performance, can you elaborate your setup more?

    You could also alternatively only do the callback for the frame (instead of camera) and use some lookup list there for cameras you need to change but I doubt you can't get measurable perf wins with this.
     
  31. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    183
    A scene has a bunch of inactive cameras, and they renders to a rendertexture occasionally. When they do render, I want to do something before and after the render.
    In worst case scenario, if the thing I want to do differs between cameras, then I need to add bunch of event listeners to RPM.
    This case is quite hypothetical and not practical use case, and there can be a workaround to minimize the event listeners. But adding an event listener to a specific camera looks more neat and clearer to me, though...

    And you're right, some time after I wrote this I had the same thought. None of my project had a lot of 'active' cameras all at once. Maybe 5 at maximum? That would be a reasonable count.
     
  32. Thrawn75

    Thrawn75

    Joined:
    Nov 16, 2014
    Posts:
    2,138
    Hi,
    I'm getting distorted geometry (wrong position and/or scale) when using DrawMeshNow in endCameraRendering hook.
    Same code works fine if it's called from OnRenderObject in standard pipeline.
    Is there any limitation regarding DrawMeshNow?
    Thanks.
     
  33. reintseri

    reintseri

    Joined:
    Aug 25, 2017
    Posts:
    7
    Hi all, I have a bunch of 2018.x projects where I would need the endFrameRendering hook of >2019.1. Is there anyway to inject this hook into SRP (HDRP) myself? The 2018 projects are quite huge and a bunch of stuff breaks due to other changes. I'm trying to figure out if I should try to migrate the projects or try to find an inject point in 2018 Unity.
     
  34. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,476
    I'm still confused how to use this, where is RenderPipelineManager being called from and where do you put your EndCameraRendering code?
     
  35. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    990
    here's example for BeginCameraRendering:
    https://github.com/0lento/OcclusionProbes/blob/package/OcclusionProbes/OcclusionProbes.cs#L41
    https://github.com/0lento/OcclusionProbes/blob/package/OcclusionProbes/OcclusionProbes.cs#L62

    https://github.com/0lento/OcclusionProbes/blob/package/OcclusionProbes/OcclusionProbes.cs#L79
    (just ignore my #ifdefs)
     
    ItsJayD and monark like this.