# Simple Optimized Blur Shader

I have a vertex-fragment shader that use the Unity3D GrabPass functionality (it grabs the screen). And I apply my GrabPass to have a transparent effect.

GrabPass {
"_GrabTex"
}

sampler2D   _GrabTex;

// float4 grabPassPos : TEXCOORD4 is used to apply the grabbed texture in
// the right place and is calculated in the vertex
half4 transparent = tex2Dproj(_GrabTex, UNITY_PROJ_COORD(IN.grabPassPos));
half4 baseColor = transparent;
return baseColor;

I am searching a simple way of blurring my grabbed texture. I don't know how to apply my blur because it's a tex2Dproj and I don't know where to apply it.
I am searching for a one pass optimized simple blur but I don't know if it's possible.
I know a bit about Gaussian and Box blur which seems to be the simplest but how can I apply them in a tex2Dproj ?

Thanks a lot !

## 1 Answer

I don't have pretty much any experience with Unity, so this might not be the most efficient way to do it (and my coordinate calculation might actually be wrong). But it should give you some idea:

All you have to do is evaluate the color at different pixels/coordinates and blend them together, probably doing so based on their actual brightness.

For a simple kernel like

0 1 0
1 2 1
0 1 0

This is quite trivial:

// First get the colors at all these positions.
// Note that the offsets (0.1f/0) might not be the perfect values for you.
// If you want to blur exactly 1 pixel distance you'd use "1 / screenwidth" or "1 / screenheight" here.
float2 centercoord = UNITY_PROJ_COORD(IN.grabPassPos);
half4 top = tex2Dproj(_GrabTex, centercoord + float2(0, -.01f));
half4 bottom = tex2Dproj(_GrabTex, centercoord + float2(0, .01f));
half4 left = tex2Dproj(_GrabTex, centercoord + float2(-.01f, 0));
half4 right = tex2Dproj(_GrabTex, centercoord + float2(.01f, 0));
half4 center = tex2Dproj(_GrabTex, centercoord);

// Now blend the colors together, using the weightings from the kernel (see above).
return (top + bottom + left + right + center + center) / 6.0f;

For more complex kernels you'd most likely want to use an array containing the kernel values and do everything in a loop.

• Bilateral blurring is an optimized version of symmetric kernels that should be mentioned. Jun 7, 2013 at 11:27
• It seems to be close to box blur no ? I tested it it's a good effect but maybe not enough smooth. Should I iterate the process ?
– MaT
Jun 7, 2013 at 11:36
• You can use a bigger kernel (like 5x5) and use gaussian blur with it. You should just put it into a loop as mentioned. Jun 7, 2013 at 11:42
• Unfortunately I don't have access in loop. I tried to fill the whole kernel but I think it's useless.
– MaT
Jun 7, 2013 at 11:55
• The kernel just determines the weighting of the surrounding pixels. You don't necessarily have to use one, you can just hardcode the transformation as I did above. Jun 7, 2013 at 13:34