I’m working on a fake motion blur solution for the common “wagon wheel” problem in Unity 5.
At the beginning I wanted to create a local radial motion blur as Image Effect but it’s too hard for me, so I’m trying different approaches.
As now, I just need an shader to perform a radial blur on a texture using a float value (angle) as input, but I’m quite noob on shaders.
Here is an example of what I would like to reproduce:
Does anyone have some suggestions? I’d really appreciate some help!
If you want to try using the 5.4 betas you can use this:
However doing this as an effect on the texture itself can be quite expensive. It requires you sample the texture multiple times in your shader. You can do some hacks like lowering the mip map to reduce the number of texture samples, but it will also blur details that wouldn’t blur normally. The really cheap method of doing this is have two textures, one blurred and one not, and fade between them. This is what a lot of racing games of the PS2/Xbox through PS3/Xbox 360 eras did, and even what the original Halo games did for the warthog.
That blur shader works by sampling the texture 100 times … which is very expensive. However the idea is the same for a spin blur, just rotating the texture each time instead of scaling. Something like 8 texture samples is okay, even 16 isn’t totally crazy, but that’s a total count so if you’ve got normal maps, and metallic / smoothness maps, and occlusion maps you can only realistically do 4 samples of each texture which doesn’t produce a very pleasing blur (also a normal map blurred this way produces kind of bad results).
And that’s what I get for different values of the angle.
This is not cheap at all, because I use one sample for each degree of the angle.
For example, in the last image (360°) I use 360 samples, which is so expensive.
Maybe I should make it tweakable with some kind of downsampling.
Hi!! I need your help again. I modified the shader so now it supports downsampling and some other optimizations.
I’m trying to make an Image Effect with it, and I know how to do it (using the Blit function), but it seems that Blit doesn’t work with surface shaders, producing black textures.
So, how can I convert this surface shader in a fragment shader with ColorMask RGBA?
For a blit shader you want as basic of a vertex / fragment shader as possible. Create a new unlit shader in Unity and you can mostly copy your surf function into that then fix the issues. Main things are you’re directly outputting a fixed4 instead of o.Albedo and o.Alpha, and the “IN.uv_MainTex” is going to be “i.uv” or something like that.
So basically I’ve been working on a HDRP project and I had to convert the code to Shader Graph but instead of using nodes I put the code inside a Custom Function Node
All you need is add this code with the following inputs and outputs
Inputs:
MainTex: Texture2D
UV: Vector2
SS: Sampler State
Angle: Vector1
Just a performance consideration for both the text and the graph version of this shader: I wouldn’t use it for realtime rendering but only for baking a radially blurred pool/array/spritesheet of textures.
Very interesting technique, basically it blurs the meshes by sampling them multiple times with lowered alpha, exactly the same way we blur textures. I’ll definitely give it a try.