0
\$\begingroup\$

I have the following h and v blur:

Horz

  texture tex;
   sampler2D s = sampler_state {
      texture = <tex>;
   };

   int tWidth;
   int tHeight;
   float blurSize = 9.0;
   float4 ps_main(VS_OUTPUT Input) : COLOR0
   {
      float2 pxSz = float2(1.0 / tWidth,1.0 / tHeight);
      float4 outC = 0;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(-4.0 * pxSz.x * blurSize,0)) * 0.05;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(-3.0 * pxSz.x * blurSize,0)) * 0.09;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(-2.0 * pxSz.x * blurSize,0)) * 0.12;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(-pxSz.x * blurSize,0)) * 0.15;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,0)) * 0.16;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(pxSz.x * blurSize,0)) * 0.15;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(2.0 * pxSz.x * blurSize,0)) * 0.12;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(3.0 * pxSz.x * blurSize,0)) * 0.09;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(4.0 * pxSz.x * blurSize,0)) * 0.05;
      outC.r = 0;
      outC.g = 0;
      outC.b = 0;
      outC.a *= 0.8;
      return outC;
   }

vert

  texture tex;
   sampler2D s = sampler_state {
      texture = <tex>;
   };

   int tWidth;
   int tHeight;
   float blurSize = 9.0;
   float4 ps_main(VS_OUTPUT Input) : COLOR0
   {
      float2 pxSz = float2(1.0 / tWidth,1.0 / tHeight);
      float4 outC = 0;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,-4.0 * pxSz.y * blurSize)) * 0.05;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,-3.0 * pxSz.y * blurSize)) * 0.09;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,-2.0 * pxSz.y * blurSize)) * 0.12;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,-pxSz.y * blurSize)) * 0.15;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,0)) * 0.16;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,pxSz.y * blurSize)) * 0.15;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,2.0 * pxSz.y * blurSize)) * 0.12;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,3.0 * pxSz.y * blurSize)) * 0.09;
      outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(0,4.0 * pxSz.y * blurSize)) * 0.05;
      outC.r = 0;
      outC.g = 0;
      outC.b = 0;
      outC.a *= 0.8;
      return outC;
   }

When the blur size is < 5, it looks like Photoshop's, but when I bring it up to make drop shadows, it starts looking like this:

enter image description here

Top is my game, bottom is photoshop. Notice the lines that form on mine. I think it stems from reaching the edge of the texture maybe. What could I do to make it look more like Photoshop's?

Thanks

\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

When blurSize gets too large, the texture samples will be spaced so far apart from each other that some pixels that should be in the blur will be missed. This can easily lead to aliasing. To do really large blurs you would have to sample a lot more pixels, but since that's slow (and/or impossible depending on the limit for texture samples on your GPU), you could repeat the blur several times, or you could downsample the image to a smaller size, blur it, and then upsample with bilinear filtering. Either approach will yield a good approximation of a large blur radius.

\$\endgroup\$
2
  • \$\begingroup\$ Can you please expand on this? Specifically the bilinear filtering portion. \$\endgroup\$ Nov 22, 2013 at 0:58
  • \$\begingroup\$ @mk1 Bilinear filtering is just the filtering mode you can set on your textures to make it interpolate smoothly between pixels when the image is expanded, rather than making each pixel a hard-edged square. It's a hardware feature; you just turn it on in the sampler state. \$\endgroup\$ Nov 22, 2013 at 3:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .