Sleek Render - Lightning Fast Mobile Post Processing Effects

LOTR:WITN was a PS360 game, so it’s running on a 2005 console. Best example of god rays here:

Of course, those consoles had an abundance of bandwidth and fillrate versus mobile.

To incorporate into Sleek render, you’d need to find an efficient way to create a radial blur. If possible, that could then be used in various effects. Just filter scene based on brightness, radial blue about a point, and blend back. Where Gaussian blurs are well accelerated, I don’t know of any radial blur solution. My game uses repeated scaling to create volumetric shadows.

@SoftwareGeezers I remember reading an article on original Infinity Blade rendering, they have used a similar technique for their god rays using a directional blur. There’s really little difference between different blur techniques save for texture cache utilization (I see quite a lot of Gaussian Blur implementations that are not cache-effective though). The only two problems would be the pass count + resolution dependent blur - rememeber the old legacy Unity Blur effect which didn’t blur quite as much when was used on high-res screens. Infinity Blade guys had just a few target devices which allowed to hard-tweak the pass count and blur offsets, which simplified the problem a bit. Can’t find the article anymore, but I will post it here if I’ll find it.

As for XBOX360 / PS3 bandwidth - you are right, those consoles used quite a lot of power (around 100W according to NVIDIA reports) as well as the fact that GPUs there are Immediate Mode rather than Tiled (on mobiles) which allows for a lot more separate passes with very little additional overhead.

You can even look further back at PS2 / XBOX with games like DOUBLE S.T.E.A.L which used famous Kawase blur for Bloom and Light Streaks and it worked by utilizing multi-pass blur even back then (and it was 2004-2005). By multi-pass I mean 5-7-9 or more slightly downscaled passes which it’s still quite expensive for a lot of Android devices.

Images

But yeah, it depends on a project and sometimes can be implemented relatively effectively. But this particular case of god rays requires at least some degree of artistic tweaking of additional parameters and, in my experience, creates a lot of confusion for most users (it may be non-intuitive, but the majority of users don’t want to tweak or change anything, especially if some changes are required for the package to work correctly).

I would better focus my still limited time to more general things and overall education on graphics programming.

1 Like

Hey!
The work you have done is quite amazing.I have a question that is it possible for you to provide the “blur” effect ? Right now only Bloom, Colorize,Vignette and Brightness/Contrast are there. Or is there any way to use blur effect by tweaking some parameters?

Thanks,

Hi @shirish_Jain
What do you mean by “blur” effect? Would you post a reference screenshot here?

Hi!

I have a performance issue with two cameras setup. I have the main camera with Sleek Render Post Process on it. Previously I used Screen Space - Overlay for UI and everything worked flawlessly with almost nonexistent performance effect. But now I need to use a second camera for my UI and it crushes the performance. From stable 60 FPS it drops to about 45 even without any effects enabled in the settings file.

What can I do to fix it?

@pensionerov What you mean by “worked flawlessly” is that the frame budget was below 16.6 ms, even if it was around 15-16ms. Adding just one heavy ~5 ms operation like two-camera setup which is quite heavy on mobiles due to full-frame resolve (which becomes even worse on hi-DPI screens), you suddenly go out of those 16.6 ms for a frame, going below 60 FPS. So it’s not just some one thing that “breaks” everything, it’s all gradually piling up together increasing overall frame time. Two Cameras doesn’t even sound like it’s something heavy, but for Android mobiles it usually is.

The only easy way to fix it is to go back to one camera setup to get the needed ~5 ms back. It’s worth spending time on making your UI look good and work OK with that one-camera setup, it’s really the fastest solution you can get.
Also, while supporting the package, I noticed that often the 3D scene rendering itself is quite heavy (using standard shaders is a good way to blow the frame budget), so optimizing 3D scene materials and shaders is also a thing to consider.

Thank you for your answer, but it seems to be some one thing. I tested two cases.

  1. Two cameras setup with Sleek Render Post Process disabled on heavy load with lots of particles and enemies on screen. Result: stable 60 fps.
  2. Two cameras with Sleek Render Post Process enabled on main camera, but without any effects active in Sleek Render Settings and the same scene without enemies and some other stuff disabled (so the load from everything on scene was <= then in case 1). Result: 45-50 fps.

So it seems to me, that just the fact of having Sleek Render Post Process enabled in two cameras setup without actual effects is a heavy thing. Is it an expected behaviour?

@pensionerov Sleek Render without any effects has a few seemingly empty passes that still do some work. It’s considered the base overhead of the package and it takes some frame budget. That base overhead is mitigated when effects themselves are starting to enable. It’s needed to avoid resource creation hiccups and enabling / disabling / fading effects difference in overall cost of the effects stack, which allows for smoother framerates with fewer possible hiccups.

This base overhead, when combined with your two camera passes, takes your framerate down to 45-50 fps.

What you need to understand that 60 fps doesn’t mean “it runs without problems”, it just happens to run under 16.6 ms, whether it’s 1 ms or 16.5 ms for a frame.

Let’s discuss this for a moment.

Say your scene with one camera and without any effects takes 8 ms. Adding Sleek Render increases overall budget by, say, 5 ms, which is makes it 13 ms in total. Thus your scene is rendered at 60 fps regardless of whether Sleek Render is enabled or not because total cost is less than 16.6. Mobile builds in Unity just can’t update faster than that, and this is why you can see that stable 60 fps cap.

Now, take that same one-camera scene again, 8 ms without any effects. Adding a second camera to it will increase overall budget by, say, same 5 ms, which makes it 13 ms in total again. It’s still less than 16.6 and it runs at 60 fps.

Adding Sleek Render to your two camera setup will increase frame time by another 5 ms (as well as adding a second camera to a Sleek Render scene) which will make it 18 ms in total, which is now more than 16.6. It looks like something has suddenly “broken”, while in reality you have just spent your 16.6 budget and FPS became lower than 60. (18 ms is 55 FPS).

50 FPS is actually 20 ms of frame budget, but you get the idea. We could have started with 10 ms base time for your scene + 5 ms for Sleek Render or a second camera. Adding just one more thing that takes more than 1.6 ms will blow the frame budget.

One instance of Sleek Render has the same budget regardless of number of cameras used in the scene. If you add more cameras to your scene, you’ll see more dropping of framerate proportional to the number of cameras. Number of cameras and Sleek Render performance do not correlate in any way.

Well, thank you for the detailed explanation. Never thought, that rendering UI with a camera instead of overlay would cost me as much as the whole post-processing.

Keep in mind that it’s not really the rendering itself, it’s the intermediate processes of switching render targets / copying current target contents to main memory (resolves) which break tiled mobile GPU optimizations.
Here’s an amazing talk on Adreno GPU architecture and optimizations (it’s mostly the same with PowerVR / Mali)
https://www.youtube.com/watch?v=JvMQUz0g_Tk

It’s mobile VR oriented (GLES 3.0), but it has some good insights on what’s happening on the GPU other than the rendering itself

1 Like

Thank you very much! I’ll take a look.

Hi,
Blur effect basically is when you move very fast (let’s say you have pressed a nitro button during car racing) then surrounding objects should start appearing blurry.This effect is supported on Post-Processing stack with the name “Motion Blur”. Here I am attaching the screenshot of the same.

4354930--393904--Motion_blur.PNG

@shirish_Jain Oh, I see, so you mean motion blur then. It’s not possible to achieve with Sleek Render right now and most likely it won’t be supported in nearest future because effective implementation requires fake (extremely lowpoly) geometry on your scene in place of real objects to simplify motion vectors calculation. So it’s not a drag-and-drop solution (it adds one essential part to your asset pipeline that has to be worked on constantly).
In my experience, anything other than drag-and-drop generates a lot of negative feedback for the package and increases overall support pressure.

I have released a housekeeping micro-update with a bumped minimum required Unity version (2017.1.0f3) and moved package assets from the Plugins folder (often people just moved it outside anyway and new files from updates ended up in a different .NET assembly, breaking the compilation).

It’s a totally housekeeping update intended for new people for easier future updates, existing users can completely ignore it.

New updates are coming soon.

3 Likes

Hi,
Thanks for replying.Just a small request, do you know any good asset on asset store which can help me resolving this problem?

Thanks,

Hello! I’ve bought the Sleek Render asset and am really enjoying its great performance! However, I’m looking to squeeze a little more juice out so that my game can run at 60 fps on low-end devices (it was barely hitting 60 before adding Sleek, which costs 10-15 fps on my Fire HD 8). I want to render the main scene at a lower resolution in order to keep the fps as high as possible. I got it working, but I want to make sure this is the recommended route. I basically just took this link from the first page and copied its method into Sleek Render. However, Sleek Render is doing a lot of its own thing, so I don’t know if this is advisable:

//SleekRenderPostProcess.cs

        private RenderTexture tempRT;

        private void OnPreRender() {
            // Exaggerated to make sure it's working. TODO: Make this dynamic based on framerate :)
            tempRT = RenderTexture.GetTemporary(Screen.currentResolution.width / 10, Screen.currentResolution.height / 10, 16);
            Camera.main.targetTexture = tempRT;
        }

        // This used to be OnRenderImage
        private void OnPostRender()
        {
            ...
            // Applying post processing steps
            ApplyPostProcess(tempRT);
            // Last step as separate pass. null -> back buffer
            Camera.main.targetTexture = null;
            Compose(tempRT, null);
            RenderTexture.ReleaseTemporary(tempRT);
        }

Just want to make sure I’m on the right track, and help anyone else using this package looking to do this.

Next step is to figure out how to implement my own “displacement” effects in the stack.

Also - small point of advice: the asset store pictures should be updated. The bloom there looks awful compared to what is now implemented. I actually looked at Sleek a few months ago and passed because the effect didn’t look good. I’m sure you’re losing sales over it

Ah, I spoke too quickly. While the downscale is happening, the bloom has been lost. I’ll post back if I can figure out a way to achieve both

Hi @Frenchie92 , thanks for supporting Sleek Render.
Also thanks for looking at this issue and trying to implement it yourself first to get a broader picture before looking for help. It really saves a lot of time (both yours and mine).

As for the question itself - you’re on a right track trying to downscale your main 3D scene to squeeze some performance from your game.

However!

Let’s go step by step here.

First - Fire HD 8 seems like a pretty powerful device to me (PowerVR G6200 GPU) on a not-really-dense screen - 800 x 1280 pixels on 8 inches. It’s just around 190 ppi of density. Lowering main resolution will probably start looking a bit pixelated pretty soon. It’s not some 5 inch phone with 1520 pixels screen. This downscaling technique is generally advised for lower end devices with high pixel density.
[I have explained why sometimes adding Sleek makes games run below 60 fps on devices here. ]( Sleek Render - Lightning Fast Mobile Post Processing Effects page-5#post-4353145)
I see a lot of games which are made from sub-optimal shaders for 3D geometry, which sometimes can lead to not-very-best performance of the main render scene in the first place (while still being in that 16 ms budget). It’s not to say that Sleek Render is free in terms of performance (it’s not), it’s just that almost always there are ways to optimize 3D shaders to squeeze some GPU clock cycles without using downscaling technique.

Second - this downscaling technique can sometimes lead to worse performance than rendering everything without it. This happens because rendering something to an intermediate texture on mobile GPUs is an inherently slow process (not the rendering itself, but the memory resolve after it). Sometimes GPU clock cycles saved by rendering to a downscaled target are not enought to compensate for the time required for that memory resolve after rendering. It really requires careful calculations and experiments. Moreover, this technique is more tricky to implement in Unity than in “raw” form of using OpenGL / Metal / Vulkan pipelines directly because Unity is trying to be too helpful sometimes (this is exactly why they have implemented scriptable rendering pipeline - to make Unity less helpful).

Third - at first glance on your custom Sleek Render code it seems that the last Compose step is still done in full rez (Compose is currently the heaviest of all the Sleek Render passes) and it should really be applied to a downscaled texture of the scene too, or you won’t get full boost of performance.

Fourth - this downscaling feature is a pretty commonly requested thing in Sleek Render and it’s currently in development internally. Unfortunately, I’m busy as hell on my day job (working 7 days a week for past few months) and can’t find tangible amount of uninterrupted time to get the functionality to a customer-ready grade of quality and stability. It will be there eventually, it’s just a bit more tricky to get everything right (last time I checked, for example, that GetTempRT function generated a few bytes of garbage every frame in certain Unity versions, and rendering a scene without a camera that doesn’t have a target render texture, even if it doesn’t render anything, leads to a black screen). The functionality will be there eventually - it’s the first thing I will release in the next update (when it will be implemented). Can’t tell any exact ETA unfortunately.

Fifth - yes, you are quite right about the store content. I have a bunch of assets lying around but just can’t get to updating the store listing. I will do it right after releasing the next functional update.

In the meantime, I can help you by looking at your Android build with or without Sleek Render added to see if any shaders for 3D geometry can be easily optimized. It usually takes around 30 minutes and it provides a lot of insights on internals of your rendering pipeline and shaders. Please contact me through my support e-mail, or using direct messages here on forum for further assistance.

3 Likes

Thanks for the reply @Kumo-Kairo !

  1. It’s an older generation Fire HD 8 with an ARM Mali-T720 MP2, but point taken. Almost everything rendered in my game is via a custom shader. I’m barely hitting 60 fps without Sleek on that device so my budget is effectively 0 ms. I wanted to see if the game looked better at lower res with Sleek or higher res without it and pick from there. The models are voxel-inspired, so I can get away with a lower res.

  2. Understood. I observed this penalty when rendering to an intermediate rendertexture set to full resolution. I had to cut the resolution down pretty dramatically to get back to 60 fps, but I wasn’t sure if I was doing the downscaling properly.

  3. The tempRT being passed to Sleek was allocated above at a lower resolution (in this test, 10% just to make sure it was working. Ideally I’d render around 75%)

  4. Yeah… I’ve had a lot of issues with RenderTextures as well. It’s part of what led me to buying your asset :slight_smile:

Thanks for the offer to help look at my build directly! I’ll message you outside of this forum.

I don’t know where to get it from. It’s not available in the Asset Store