Search Unity

CommandBuffer.Blit() from camera target very slow on iOS OpenGL ES2.0 (fine in Android / iOS Metal)

Discussion in 'General Graphics' started by StuntFriar, Jan 4, 2016.

  1. StuntFriar

    StuntFriar

    Joined:
    Sep 10, 2015
    Posts:
    8
    Hi all,

    I'm trying to implement a water shader which requires me to do a frame grab before rendering my transparent objects (I'm using forward rendering) - which I'm doing via a command buffer blit onto a temporary render target, fairly straightforward stuff:
    Code (CSharp):
    1. // copy screen into temporary RT
    2. int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
    3. commandBuffer.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Point);
    4. commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID);
    5.  
    6. // 'cam' is the current camera
    7. cam.AddCommandBuffer(CameraEvent.AfterSkybox, commandBuffer);
    This is very similar to the "Blurry Refractions" sample code from the Unity Blog entry on command buffers, and is being used as an alternative to the very expensive GrabPass technique, and has been a huge performance boost on Android (OpenGL ES2.0 &3.0) and iOS (Metal), being almost free-of-charge according to the profiler (taking up 0.01ms or less).

    However, this same step (labelled as "RenderTexture.GrabPixels" in the profiler) takes anywhere between 20ms to 120ms on my iOS devices when running in OpenGL ES2.0 - basically anything older than an iPhone 5s. It sounds like Unity is reverting to a CPU read/copy.

    At first I thought maybe I was doing something wrong elsewhere in my code, but then I tried building, running and profiling the actual "Blurry Refractions" example on an iPhone 5s and I'm getting similar results: about 0.01ms in Metal, but 25ms when I force it to run in GLES2.

    Just to re-iterate, the same thing runs fine in Android + GLES2.

    Has anyone else come across this problem and found some ridiculously simple solution (i.e. clicking on a checkbox somewhere)?

    TIA
     
    hippocoder likes this.
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    No checkbox. I think it's probably worth reporting as a bug, but I suspect it's just disabled for compatibility and as you say reverts to a cpu copy.

    Back then (for the other brothers), I simply rendered to a texture to begin with and saved myself the hassle, that's the fast workaround I guess.
     
  3. StuntFriar

    StuntFriar

    Joined:
    Sep 10, 2015
    Posts:
    8
    I was afraid of that... T_T

    The thing about that approach is that, if I wanted a frame grab of just my opaque objects (it's a water shader, after all...), I'd still have to somehow interrupt the renderer with something like a GrabPass or Commandbuffer, no? (Which presumably may result in a similar CPU read/copy thingy)

    I might give it a stab, though - spend the whole Christmas holidays with this little gremlin chewing on my subconscious.