Idea: Packed Blur for Monochromatic Textures

Started by
-1 comments, last by yuri410 9 years, 1 month ago
When trying to blur a monochromatic in a separate X-Y Gauss blur, one can have the following PS code.
#define SAMPLE_COUNT 25

sampler2D tex : register(s0);
float weights[SAMPLE_COUNT];
float2 offsets[SAMPLE_COUNT];

float4 main(float2 uv : TEXCOORD0) : COLOR
{
	float color = 0;

	for (int i = 0; i < SAMPLE_COUNT; i++)
		color += tex2D(tex, uv + offsets[i]).r * weights[i];

	return float4( color, color, color, 1);
}
The issue is, even if only taking the only one channel out of it or just use L8 format, the amount of texture look up is there. With large amount of samples this can have significant performance loss. So the idea is, why not pack each 2x2 area into a A8R8B8G8 texture and blur it together?
dDOehWO.png
After packing the texture size and the amount of blur samples will be half.

So I had 2 types of blur to compare, one traditional blur, and one packed blur has the process like: Pack->BlurX->BlurY->Unpack. When I render a 1280x720p blur, it took 1.51ms(fps=661) for the traditional mode, with packed blur it is 0.58ms(fps=1716).

There is one downside, that the pixels within the 2x2 quad are not blurred so there might be details remaining. I ended up a bilinear filtering when unpacking the texture. I checked the diff shown below.

[table][tr][td=15]Original[/td][td]SF7xoUM.png[/td][/tr][tr][td]Traditional Gauss Blur[/td][td]dvJG298.png[/td][/tr][tr][td]Packed Gauss Blur[/td][td]TWSpCTb.png[/td][/tr][tr][td]Diff with a high scale which seems in hundreds range in linear.[/td][td]jVtCAiS.png[/td][/tr][/table]

I guess this would come in handy for blurring the objects' drop shadows on screen.
Here is the packer
float4 main(float2 uv : TEXCOORD0) : COLOR
{
	float4 r;
	r[0] = tex2D(tex, uv).r;
	r[1] = tex2D(tex, uv + float2(1.0 / TEX_WIDTH, 0.0)).r;
	r[2] = tex2D(tex, uv + float2(0.0, 1.0 / TEX_HEIGHT)).r;
	r[3] = tex2D(tex, uv + float2(1.0 / TEX_WIDTH, 1.0 / TEX_HEIGHT)).r;
	return r;
}
Here is the unpacker
float4 main(float2 uv : TEXCOORD0) : COLOR
{
	float2 c = float2(TEX_WIDTH, TEX_HEIGHT) * uv / 2;
	float2 cfrac = frac(c);

	float4 colors = tex2D(tex, uv);

	float lvl = lerp(
		lerp(colors[0], colors[1], cfrac.x),
		lerp(colors[2], colors[3], cfrac.x), cfrac.y);

	return float4(lvl, lvl, lvl, 1);
}

This topic is closed to new replies.

Advertisement