Search Unity

Why my Blit( <RenderTexture> , <Material> ) doesn't work?

Discussion in 'General Graphics' started by andrew-lukasik, Apr 26, 2019.

  1. andrew-lukasik

    andrew-lukasik

    Joined:
    Jan 31, 2013
    Posts:
    249
    Can someone tell why this doesn't work:
    Code (CSharp):
    1. public void Blit ( RenderTexture rt , Material mat )
    2. {
    3.     Graphics.Blit( rt , mat );
    4. }
    ...while this works just fine:
    Code (CSharp):
    1. public void Blit ( RenderTexture rt , Material mat )
    2. {
    3.     var copy = RenderTexture.GetTemporary( rt.descriptor );
    4.     {
    5.         Graphics.Blit( rt , copy );
    6.         Graphics.Blit( copy , rt , mat );
    7.     }
    8.     RenderTexture.ReleaseTemporary( copy );
    9. }
    It's confusing because it throws no errors and documentation states no special requirements about this first overload.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    What are you expecting Graphics.Blit(rt, mat); to do? If it's to replicate the code you have in the second option, that's not what it does. That option is equivalent to:

    Graphics.Blit(rt, null, mat, -1);

    It will do a blit to the current active texture target. You can't read from and render to the same render textures.* To apply a shader to a render texture you have to render the results to a new render texture, or copy the original and blit back. CopyTexture might be a faster option than a straight blit too.

    * iOS devices can do it, but only using specially written shaders, and only from and to the same pixel. Compute shaders can do it using RWTextures, but there are a lot of gotchas, including the possibility of some reads being from already modified pixels meaning the shader won't act like you expect.
     
    andrew-lukasik likes this.
  3. andrew-lukasik

    andrew-lukasik

    Joined:
    Jan 31, 2013
    Posts:
    249
    Oh, that makes so much sense now. Thank you for this clarification!