Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Adding multiple frames to get a ghosting or a echo effect eith decay

Discussion in 'Shaders' started by luigis, Nov 15, 2022.

  1. luigis

    luigis

    Joined:
    Oct 30, 2013
    Posts:
    25
    Hello to everyone,
    I'm in URP and I would like to get an effect in a final render that echos past frames with a fade to get a sort of trails or ghosting or onion skin effect.

    I've seen many tests but nothing I can work with (i'm not a expert programmer)

    I would like to:
    • store a list of Textures
    • fill the last frame in the list and remove the first
    • blit all the frames until the last of the list
    The next step I would like to put a decay value so the first frame is less visible then the last
    This is the code i'm trying to do I know i'm missing something crucial but I need help to understand what's missing please!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Gg_FrameBuffer : MonoBehaviour
    6. {
    7.     public RenderTexture RT;
    8.     public Camera _camera;
    9.     public List<RenderTexture> frames;
    10.     public int samples = 25;
    11.  
    12.     private void Start()
    13.     {
    14.  
    15.         RT = new RenderTexture(Screen.width, Screen.height, 32);
    16.         frames = new List<RenderTexture>();
    17.  
    18.         frames.Capacity = samples;
    19.         for (int i = 0; i < frames.Capacity; i++)
    20.         {
    21.             frames.Add (new RenderTexture(RT));
    22.         }
    23.     }
    24.  
    25.     void Update()
    26.     {
    27.  
    28.     }
    29.  
    30.     void OnRenderImage(RenderTexture source, RenderTexture target)
    31.     {
    32.  
    33.         frames.RemoveAt(0);
    34.         frames.Add(source);
    35.  
    36.         for (int i = 0; i < frames.Capacity; i++)
    37.         {
    38.             Graphics.Blit(frames[i], target);
    39.         }
    40.  
    41.     }
    42. }
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,495
    Depending on what you want to do, it can be a lot cheaper to simply render your object multiple times be recording their state for the last few frames. You can duplicate the object a few times and have the duplicates update with increasing delay and more and more transparency and whatnot. (or simply apply the state to the character and manually render, but this would be more expensive since the draw calls wouldn't be batched).

    Another option would be to simply have 1 RT to store your ghosting effect, you don't need multiple.

    Basically, render your ghosting objects to this buffer as a regular render instead of to the main camera buffer, then at end of rendering opaques, BLIT it to the main camera RT using depth so it doesn't get applied overtop other objects and alpha value to reduce how much of the color is blended in (write the depth value to main buffer also, if alpha == 1), then the magic comes after... at end of frame you can do a BLIT or Compute pass over this RT that reduces the alpha values by 1/GhostFrames. So, with each frame, the ghosted colors will continually reduce, and the one at the tail will be completely gone after GhostFrames count and then the frame after the next will be gone, etc...

    This is much cheaper than having a bunch of RT frames that also grow in count with ghost frames count... No matter the amount of ghost frames you have, the cost of this method will remain the same as if you had only 1 ghost frame.

    You may want the effect to be frame-independent though, then I would recommend rendering the character as normal, and simply only render it again when a specific time has elapsed.

    I would definitely go with the first option though, as it's much simpler to implement, and camera movements are automatically taken care of instead of trying to shift around the ghosting texture. And especially if it's a 3D game moving in all axis, then the RT method can really break down.
     
    Last edited: Nov 16, 2022
  3. luigis

    luigis

    Joined:
    Oct 30, 2013
    Posts:
    25
    Thank you for your time!
    Basically this is not a game but a visual mapped for a live event.
    I don't have a object but a complex particle system ( I upload a sample) Is really hard and has a big cost duplicate all the trail lines that you can see in the sample, so I would try the RT way!

    I will try the second method and report the progress ASAP thank you!!
     

    Attached Files:

  4. luigis

    luigis

    Joined:
    Oct 30, 2013
    Posts:
    25
    I'm trying to test the blit function. Is it possible that URP pipeline has another approach to the blit function?
     
  5. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,495
    For URP, you have to use the "RenderPass" system.
     
    luigis likes this.