Shader that uses its own results

Hello everybody!

I’m trying to create a shader, that will use as input texture its own result from the previous frame.
I’ve set an orthographic camera (clears depth only) aiming at the plane with camera’s rendertexture, but it produces strange results (looks like the view you get when placing two mirrors in front of each other).

So… What’s the best way to create such a shader in Unity?

An easier way to use the exact RenderTexture as input, is to use Graphics.Blit (or a ComputeShader if you’re only making an Windows DirectX11 version). That way the object you’re rendering automatically fits the entire screen (Graphics.Blit creates a quad with the size of the screen, DirectCompute uses the input texture directly).

Make sure the shader you’re using to process the texture always succeeds the depth test (ZTest Always). It’s also good idea to render to a different RenderTexture than what you’re reading from. So you can either switch between two RenderTextures as input and output, or create and destroy new RenderTextures for each frame. Set up your RenderTexture with 0 depth, and Linear Read/Write.

I should mention that it’s worth experimenting with ignoring everything I’ve said, just for pure fun. I’ve created some of the weirdest and creepiest effects that way ^^. (Although in some cases you’d simply get a black texture as a result, I’ve seen ghostly characters appear that I never added as input, made the texture slowly melt away, and added weird melting effects)

Thank you for the suggestion!
I’ve tried it using Blit in orthographic camera’s script, but the result still looks like endlessly repeated images.
My steps are:

  1. Create a plane (10x10 size)
  2. Create a rendertexture for it (1024x1024)
  3. Add an orthographic camera aiming at the plane with the orthographic size set to 512
  4. In camera’s OnRenderImage use Graphics.Blit to process renderered texture

What am I doing wrong?

You don’t need a Camera or any geometry to use Graphics.Blit. It can be called from almost any script you want, at pretty much any time. It creates its own screen-sized polygon, and renders it using the material you provide.

  1. Set any Inputs you might need on the material you want to use
  2. Set the active RenderTexture (This might not be necessary. I remember having issues were the ‘dest’ parameter wasn’t actually being applied correctly)
  3. Call Graphics.Blit, and pass along the Material you want to use. The source parameter can be null, unless you want to set a Texture called _MainTex.
  4. Set the texture you used for Dest(ination) as an input for your next frame.
  5. repeat.

Thank you so much for your help!
You saved my day))