Mostly Image Effects are costly because of the fillrate and bandwidth. Your 3D objects take up only so much screen space and it’s possible to render a lot of them, while keeping the total count of rendered pixels low. Mobile GPUs usually have a lot of optimization techniques like early rejection that works like additional “occlusion culling”, so a lot of object pixels are not rendered at all (less pixel shader calls)
If you stack up three or four full screen semi-transparent textures, it will slow the rendering down to a halt, much like a three-four pass full screen image effect. You can try it right away using UI textures (they are alpha blended-only)
Moreover, built in OnRenderImage and Graphics.Blit take up lots of CPU time too, and they don’t always allow downsampling (which is a common technique in real-world post process effects).
So if you render a scene to a full-sized render texture and then render this texture on a full screen quad, it’s basically rendering twice the pixel count (close to a rendering the same scene twice). Add additional shader logic to that and you get a lot of wasted fillrate.
Another problem on mobiles is dependent texture reads that are used for things like AO, pixel ripple effects etc. This is due to the fact that mobile GPUs are usually tile-based and random texture read operations are costly because they require a full VRAM fetch.
I’m making a mobile-oriented post processing stack that doesn’t use OnRenderImage or built-in Graphics.Blit. Right now I have implemented fast bloom that is barely slowing the devices down - it renders at 60 fps on most of them, event on full screen final compose pass.
I’ve already submitted it to the assetstore and it’s waiting the review process. You will be able to grab it while it’s free, and look at how things are done there (rendering pipeline and shaders).