Quote: "Why it has several cameras?"
For ease of development - it kept the shader simple. When I've decided on the final method I'm going to use I can then see what optimisations are possible. For example, combining the three camera renders into a single render with three passes (horizontal blur, vertical blur, screen display) might be faster. Not sure till I try. For the moment though I'm concentrating on trying to get decent variable width blur at an acceptable speed.
One possibility which looks promising from some quick tests is to use a non-Gaussian blur as in this revised shader code:
// This basic blur shader produces a variable width blur for each pixel.
// It is designed to work with a simple 2x2 quad with corners clockwise from top left
// (-1, 1), (1, 1), (1, -1), (-1, -1).
// This version uses a triangular set of weights computed in the shader.
// The blurring is done in two techniques - a horizontal blur followed by a vertical one.
// These two techniques should probably be combined into a single technique.
//Written by Green Gandalf.
// Date created 25 August 2013.
float2 invImageSize = {0.0, 0.0};
//const int blurWidth = 7; // not sure how to pass this from DBPro
texture source < string Name=""; >;
sampler2D sourceSample = sampler_state
{
Texture = <source>;
AddressU = Clamp; AddressV = Clamp;
MinFilter = Point; MagFilter = Point; MipFilter = None;
};
struct VSInput
{ float4 pos : POSITION;
};
struct VSOutput
{ float4 pos : POSITION;
float2 UV : TEXCOORD0;
float2 temp : TEXCOORD1;
};
struct PSOutput
{ float4 colour : COLOR;
};
VSOutput VS( VSInput In, VSOutput Out )
{ Out.UV = In.pos.xy * float2(0.5,-0.5) + 0.5;
Out.pos = In.pos;
Out.pos.xy = In.pos.xy + float2( -invImageSize.x, invImageSize.y );
Out.temp = In.pos.xy;
return Out;
}
PSOutput PSHorizontalBlur(VSOutput In, PSOutput Out, uniform int blurWidth)
{ float4 colour = tex2D( sourceSample , In.UV) * blurWidth;
float sum = blurWidth;
for (int i = 1; i < blurWidth; i++)
{ colour += (tex2D( sourceSample, In.UV - float2 (i*invImageSize.x, 0.0) )
+ tex2D( sourceSample, In.UV + float2 (i*invImageSize.x, 0.0) )) * (blurWidth-i);
sum += 2 * (blurWidth-i);
}
Out.colour = colour/sum;
return Out;
}
PSOutput PSVerticalBlur(VSOutput In, PSOutput Out, uniform int blurWidth)
{ float4 colour = tex2D( sourceSample , In.UV) * blurWidth;
float sum = blurWidth;
for (int i = 1; i < blurWidth; i++)
{ colour += (tex2D( sourceSample, In.UV - float2 (0.0, i*invImageSize.x) )
+ tex2D( sourceSample, In.UV + float2 (0.0, i*invImageSize.x) )) * (blurWidth-i);
sum += 2 * (blurWidth-i);
}
Out.colour = colour/sum;
return Out;
}
PSOutput PS(VSOutput In, PSOutput Out)
{ Out.colour = tex2D( sourceSample , In.UV );
return Out;
}
technique blurH3
{ //blur the image horizontally
pass BlurH
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSHorizontalBlur(3);
}
}
technique blurV3
{ //blur the image vertically
pass BlurV
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSVerticalBlur(3);
}
}
technique blurH7
{ //blur the image horizontally
pass BlurH
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSHorizontalBlur(7);
}
}
technique blurV7
{ //blur the image vertically
pass BlurV
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSVerticalBlur(7);
}
}
technique blurH19
{ //blur the image horizontally
pass BlurH
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSHorizontalBlur(19);
}
}
technique blurV19
{ //blur the image vertically
pass BlurV
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_3_0 PSVerticalBlur(19);
}
}
technique screen
{ //render the quad normally
pass BlurV
{ VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_2_0 PS();
}
}
The problem with that is that the width has to be hard coded into the various techniques - and the blur isn't as good as Gaussian blur. However after you've run the shader a few times on the same image it's as good as Gaussian blur (because of the
central limit theorem). It might be faster still to use a simple box filter at the heart - again, after about 12 iterations, I'd expect that to look like Gaussian blur too for the same reason. I'm still getting speed issues though.
Such extreme blurs are probably fine though at the end of a scene when nothing much is happening and you just want something like a fade out combined with increasing blur.
If I understood the method sufficiently I could use TheComet's suggestion.