This is my third blog in the chain of Post Processing effects in Unity. In my previous blog we have tried to create Night Vision Effect. Here in this blog , lets create blur effect. This effect mainly comes to play when the player is severely injured or Drunk. The other day when i was playing GTA, i have noticed a nice blur effect applied, when the character is drunk. So lets create the same effect. I have borrowed character and animations from Mixamo and here i am gonna show you that drunk blur kind of effect.
Before even jumping into Unity Shader programming, lets first understand the algorithm to blur any image. How do they blur the given image? There are 2 algorithms to blur an image - Box Blur and Gaussian Blue. Here for this example i am only applying Box blur along y axis only.
Box blurring is one of the technique we use to blur image.
Here a pixel color value is decided by the average of 9 pixel colors surrounding it.
If you see the below diagram, if X is a pixel color value, then X = (A+B+C+D+E+F+G+H)/9.
Likewise this continues for all pixels in the image and finally we get a blur image.
Here in our example to keep things really simple, lets stick to one axis. Lets say a pixel color value of an image is decided by average of 5 pixel colors and 5 pixel colors below.
So we loop 10 times here and take the average of 10 pixels to decide each pixel color of an image.
X = (A + B + C + D + E + F + G + H + I + J)/10
So yes that the trick to blur an image.
and here is the code we write in our fragment shader section:
fixed4 frag(vertexOutput i) : SV_TARGET
{
float4 pixelColorValue = 0;
for (float index = 0; index < 10; index++)
{
float2 uv = i.uv + float2(0, (index / 9 - 0.5) * _BlurStrength);
pixelColorValue += tex2D(_MainTex, uv);
}
pixelColorValue = pixelColorValue / 10;
return pixelColorValue;
}
If you observe the above code, i have done the same thing as we have discussed. i.UV gives the position of a particular pixel on the image.
In the above for loop, we are taking 10 pixel samples and calculating the sum value.
And then here: pixelColorValue = pixelColorValue / 10; , we are taking average value.
This is done for all the pixels in the image and we get a blur effect.
Complete Code:
Shader "ShaderLearning/BlurEffectShaderPP"{
Properties
{
//MainTex is the keywork lol :D
_MainTex("Basic Texture", 2D) = "white" {}
_Color("Main Color", Color) = (1,1,1,1)
_BlurStrength("Blur Strength", float) = 0
}
Subshader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
half4 _Color;
float _BlurStrength;
struct vertexInput
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct vertexOutput
{
float4 pos : SV_POSITION;
float2 uv: TEXCOORD0;
};
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(vertexOutput i) : SV_TARGET
{
float4 pixelColorValue = 0;
for (float index = 0; index < 10; index++) //Adding pixel color value of 5 above and 5 below pixels
{
float2 uv = i.uv + float2(0, (index / 9 - 0.5) * _BlurStrength);
pixelColorValue += tex2D(_MainTex, uv);
}
pixelColorValue = pixelColorValue / 10; //Taking average of a pixel value
return pixelColorValue;
}
ENDCG
}
}
}
Effect Output:
Comments