Sleek Render - Lightning Fast Mobile Post Processing Effects

Thanks for the advice @Kumo-Kairo , it’s a shame, HDR allows so many good visual effects. I want to achieve an effect like the temporary highlights of the poker cards in this screenshot: https://www.cheatorhackgames.co/wp-content/uploads/2018/08/scatter-holdem-poker-cheat-codes.jpeg (for the record I do not use this website and cheat it’s just the result of my google image search)
I think in this game they’re using HDR and bloom to achieve this. How would you achieve an effect like this without using HDR?

That doesn’t look like bloom to me, it looks like a simple sprite used for the glow. It’s not the most efficient technique, but on a canvas you could replicate that effect by simply having a dark transparent quad covering the whole screen, with the well lit items simply being in front of it.

I don’t think it’s just a sprite, it is at least a shader effect on the cards. You can probably see better on that video:
https://www.youtube.com/watch?v=m2woQB13ChA

Yes I thought I could also do it with a whole screen dark quad but I thought they did this effect by changing the whole scene brightness and boost hdr on the cards to highlight them.

@madgreg , @Adam-Bailey is right - it’s just a visual effect based on particles (with possible flipbook animation, but it depends on FXer’s skills). Whole screen dim is best done in a per-object tint where we only darken the non-interesting things without any masks. But making it layer-based rendering with a fullscreen gray quad followed by highlighted objects would also work OK, but it’s much more fillrate-heavy (bad for mobile), and you are usually using some kind of tint on sprite anyways (to allow for alpha blending).
Using HDR here is an overkill. You’d be surprised how many effetcs in mobile are done without any post processing whatsoever. It’s usually harder to implement that using some generic approaches (like HDR for masking), but if you want performance - there’s just no way around (no one said gamedev is easy).

You have actually almost cracked one possible scenario. But why do you think it’s easy to “decrease the whole scene brightness”, but hard to “make certain objects have initial brightness”? What is brightness here? I guess everything on the scene is some kind of unlit sprite, so “decreasing the whole scene brightness” us just simple tinting of all sprites to darker gray, leaving some of them untouched.

1 Like

This is, as already pointed out, a mix of sprites + additive and alpha-blended shader and particles on a spline + additive shader. Or even some spritesheet (either pulled off with a particle system or not).

I guess not even the creator of that game would even consider a fullscreen FX for highlighting just a few details. Probably he’s not even using any composite shader for the cards.

If the FX you’re looking for requires sharp, clear angles, you would at least need to render those sprites separately on an FX camera, or have a plugin that lets you filter out some layers.

Such crisp, almost pixel perfect, glow is definitely something heavier to pull out with a postFX rather than using a few old-school tricks, especially on mobile, where downscaling is a frequent choice.

Think of a 4K display running a 4K glow with multiple passes on a mobile. Sure, now you can rescale the resolution to have fixed dpi, but that’s just running around the problem.

While I love SleekRender and hope more speed-oriented postFX like this existed, as soon you begin adding some features like hi-resolution rendering to it, it may eventually backfire making everything slower.
So, well, probably is technically possible, but making a copy of the SleekRender shader and working from there.

Speaking from personal experience, applying a post-fx to the whole scene just to highlight a few objects is very prone to getting the unexpected to glow, I’d suggest you to take another route :slight_smile:

1 Like

Yes, I knew that using PostProcess was overkill, I used the Unity PostProcess stack to do this in my prototype because it was easier to achieve the same visual result so I can see if it looks good in my game. Now I’m in the process of finding a way to do this while keeping good performance. That’s why I wanted to try SleekRender to see how it improves the perf of the post process. But yeah it might not be the way to go.
I already tried with additive but the result doesn’t look as “burned” as I wanted. But maybe there’s something I missed, I’m going to try again and maybe tweak my additive texture.
Thanks for your inputs.

2 Likes

Hi there!

I’m not sure if I’ve already asked about this, but just in case: :stuck_out_tongue:

Since Sleek Render is definitely the one and only asset caring about performance and mobile, is there any chance to have some basic sunshafts?
It’s been a life that I’m looking for “parallel” sunshafts on the whole store, but found nothing ready out of the box. Would be some sort of 1) grabbing the shiniest mask representing the lights 2) Bleeding on a direction until it either fades out or “hits” something in the Zbuffer 3) uses the appropriate direction of a directional light.
I know it could be faked with some particles or static objects, but it’s not always possible to do that.
I’ve seen a similar effect on an action game in the LoTR series, and looked pretty nice.

Best,
Alessandro

Hi, @NeatWolf
The first thing that comes to mind is the original Infinity Blade release, they even have a paper on rendering somewhere, but I can’t find it anymore. They have used simple non-depth-tested shafts with simple downscaled blur.

The problem with depth-tested post processing sun shafts is that it’s insanely heavy to use depth buffer tests on the “soft” side (shader code) on all tile-based GPUs (Adrenos / Malis) and tile-based-deferred (PowerVRs - basically all iOS devices, even the newest ones that have different markings are the same PowerVRs).
Depth buffer is used internally on hardware, usually needed only for hardware depth testing and doesn’t leave Tile Memory at all. The only way to get depth buffer values is to either write it in alpha as “one over depth”, or render the scene twice using a different shader that outputs that use the same one-over-depth way.
First way requires customizing all used shaders in the game (which usually has to be done anyway), and sometimes not available for usage because things like Unity Terrain seem to be already using alpha channel for some internal data.
Second way increases bandwidth pressure considerably, incurring an additional resolve between the two passes. It’s also will be heavy if the geometry is relatively dense (it’s similar to forward rendering shadows where we always have an additional “depth-only” pass from the Light’s point of view to get depth values for “soft” comparison)

This is usually the way to go on mobile, I would personally do it just as you’ve said - making the effects art-based rather than relying on generic post processing effects. It surely depends on a case, but usually it’s worth the hassle - it won’t incur any additional resolves, doesn’t require customizing alpha-write of all in-game shaders and is generally more flexible in setup.

If you’ll be able to write the name of the game and point to places in a game where this effect occurs, I will be able to reverse engineer it and post here about the ways they handle sun shafts, some performance considerations and the possibility of adding it to Sleek Render.

Cheers

1 Like

Thanks for the in-depth reply. :slight_smile:
I actually have “Disable Depth and Stencil” checked out in my Android project Player settings :stuck_out_tongue:

Yes, using the depth buffer was just an idea from someone (me) who really loves postFXs, has got quite some insight on how they work or on a high abstraction level, I enjoy looking and reading docs and videos from SIGGRAPH but never got to the point of writing one full time (and for some basic things I should probably do).
So I was missing some parts of the knowledge and experience you disclosed, thanks for sharing :slight_smile:

Found it! It is LoTR - War in The North.

Now, let’s just focus on the FX, one of the things I remember the game for :stuck_out_tongue:

It’s very subtle, but looks really nice (IMO) against forests, castle walls and open areas:

https://www.youtube.com/watch?v=wDyi0K6lWZo

In the video it’s a bit hard to see, since the player wasn’t just staring at the sky and at the postFX like I was :stuck_out_tongue:

Here in the picture it is a little bit more evident.
It could either use an angle relative to the camera and the parallel light source (so, facing the light source the bleeding goes stright down at maximum intensity, and disappears when facing the opposite way), or just have a fixed, slanted angle.
To me, at the time, looked pretty good, since most solutions were definitely heavier and had some banding.
This approach is definitely not physically accurate, but it should be (relatively) fast and smooth, since it’s basically bleeding the z-buffer mask diagonally in screen space.
Not sure if it can be achieved using a threshold luma value, or a specific color range/hue (it even worked smoothly with clouds IIRC, being effectively god-rays) to get a texture/mask, bump its brightness a bit and actually starting from there to create the effect.

One naive approach I used when developing with GameMaker “back in the days” was to create an actual god rays fx was to store the mask once, and blend it multiple times according some steps in a number calculated according the current fps, scaling them proportionally to give some sense of perspective.
Yup, shaders still weren’t available so everything ran on software, but on a limited screen resolution (320x240).
I guess that creating a shader like the above may involve a similar process.
For the curious ones:

Cheers,
Alessandro

Wait what? PC HD? You surely know that PC and Mobile usually have different approaches due to different GPU rendering architectures, right? :slight_smile:
I will take a look at the game though. PC reverse-engineering is not as insightful, but I think I’ll be able to get some general info.
Can you point out a few other places where this effect can be seen? And the minimal graphics settings it’s visible on? I’m not sure if I’ll be able to invest much time in it, so it would be helpful to get some directions.

Sure :slight_smile:
“PC HD” was just the postfix of the youtube video… from 2011. That is, about 4 mobile generations ago :stuck_out_tongue:
At the moment I can’t remember of other games using it.
Nevermind, it was simply in my wishlist, I don’t need it at the moment, feel free to focus on the asset, I’ll eventually give it a go as a personal experiment, as soon as I have some spare time :slight_smile:

Thanks for your continuous support on the asset :slight_smile:
Best,
Alex

You would be surprised to know that even new mobile phones still use graphics chips from 2008, and they are pretty common nowadays (up to 50% on global Android mobile market - check Mali 400 / Adreno 305 / 306 etc.), not to mention the different rendering architecture of PC which makes it possible to use certain techniques on much older hardware efficiently (immediate mode, not optimized for lower power consumption).

What’s even worse - old graphics chips are used on higher density screens - same chips that worked relatively OK on 800x480 are used on modern 2100x1280 screens which have 7 times more pixels in total, which also has negative impact on performance and higher development pressure on addressing those high-res screens.

I’m not really surprised since I develop/profile/optimize for mobile, and you know that some of the points you mentioned can be circumvented with basically no perceivable loss.
No need to get into details or debates, we’re both busy with work, I was merely expressing a wish about a shader I’d had loved to see implemented.

I’m a proud Sleek Render user, for a reason - I value your skills and background :slight_smile:
Best,
Alex

1 Like

Hello! Thank you for a great asset!
I have one question. Is it normal that menu settings dosen’t show on inspector? Unity 2018.3.0f2
4204666--372991--upload_2019-2-11_18-51-57.png

@RockSPb yes, you seem to be using default settings that are in-memory and not serialized (so Sleek Render has something to work with until a User has overridden that value). You should replace them with your custom ones by drag-and-dropping a Settings Asset into that field and tweak the values in that asset instead (it’s clearly written in the ReadMe file, but I guess I should put a warning into the inspector itself so it’s more apparent). Custom settings are created from the Right-Click → Create menu in the project window.

Oh, this was a bad screenshot. This behavior happens with custom settings.
4207588--373339--upload_2019-2-12_13-37-53.png

@RockSPb - click on the New Sleek Render Settings and a new Inspector Window would open allowing you to tweak those settings. It works the same as the Unity’s Post Processing settings where everything is tweaked on another screen, not in the component on your Game Object.

Sorry, I thought something went wrong)
Maybe it’s better to modify this line to prevent dark spots when brightness is less than 1?

vignetteAlpha *= 1.0h - rawBloomIntencity ;

//to

vignetteAlpha *= 1.0h - rawBloomIntencity * min(_BloomIntencity, 1.0h);

4222540--375166--upload_2019-2-16_12-22-51.png

4222540--375169--upload_2019-2-16_12-24-22.png

1 Like

This is a good example of things that can (and should) be kept out of the shader.

  1. It’s totally OK to check the value at edit time before even starting to render things.
  2. Sometimes users mean to use that lower intensity values (in cases of low-key scenes for example)
  3. Adding this little min call to the post processing shader adds at least one clock cycle to the GPU (it depends on hardware, but in this case it will take at least one additional cycle) which results in hundreds of thousands of completely wasted GPU clock cycles that can be eliminated at edit time. Keep in mind that even downscaled post processing passes usually take quite a lot of shaded fragments.
    This is why Sleek Render is fast (at least it tries to be) - because every single clock cycle is counted.

If you need that input validation, add it either to the settings inspector as a lowest possible value, or validate it when changing (on the C# / CPU side once per value change). Put things where they belong.

I know how GPU work) but it’s not just a clamping of overall brightness, this multiplying fix dark spots when intensity is low, overall bloom intensity is still less then 1. But I agree, it should be more optimal way. In my case 1 gives too much bloom, so I need some sort of fix.