I have this shader:

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

   int tWidth = 1;
   int tHeight = 1;
   int blurLength = 3;

   float4 ps_main(VS_OUTPUT Input) : COLOR0
      float weight = 1.0 / (blurLength * blurLength);
      float2 pxSz = float2(1.0 / tWidth,1.0 / tHeight);
      float4 color = Input.Color * tex2D(s, Input.TexCoord.xy);
      float4 outC = 0;
      int x = 0;
      int y = 0;
        int numSubtr = (blurLength - 1) / 2;
        x -= numSubtr;
        y -= numSubtr;
        int count = 0;
        for(int i = x; i < x + blurLength; ++i)
            for(int j = y; j < y + blurLength; ++j)
                outC += Input.Color * tex2D(s, Input.TexCoord.xy + float2(i * pxSz.x,j * pxSz.y)) * weight;
      return outC;

When I load it I get: enter image description here

What could be wrong? (using hlsl ps 2.0 I think)



You need to declare blurLength as a static int for this to work. When unrolling a loop, the iteration count has to be a compile-time constant; without the static on there, the compiler has to assume you might change the value of the parameter at runtime.

  • \$\begingroup\$ Well that is the thing, I do want to change these at runtime. And another thing, I tried to manually do it and when blurLength is > 3 (say 5 or 9) it does not run my shader. What can I do if I want dynamic bluring? \$\endgroup\$
    – jmasterx
    Aug 18 '12 at 0:48
  • \$\begingroup\$ Not changing at runtime in this instance means not changing during shader execution. Making the variable a constant input allows the host application code to change the value still. \$\endgroup\$ Aug 18 '12 at 2:24
  • \$\begingroup\$ @Milo PS 2.0 does not support dynamic branching, so any loops must be unrolled and must have a compile-time constant iteration count. To get blurs of different sizes, you would have to have a different shader for each blur size. As for why you can't get blurLength > 3, probably you have too many texture samples in that case. PS 2.0 only supports a limited number of texture samples. If you're doing a box or Gaussian blur, though, it is separable, so you can do it in two passes: a 1D blur on each row followed by a 1D blur on each column. That will be faster than doing it all in one pass anyway. \$\endgroup\$ Aug 18 '12 at 3:24
  • 4
    \$\begingroup\$ @SeanMiddleditch Actually, in this case the blur size must be a compile-time constant, so the host application cannot change the value even between draw calls. \$\endgroup\$ Aug 18 '12 at 3:26
  • 1
    \$\begingroup\$ The host application can change constants between draw calls - it just requires recompiling the shader. :). You're right though that it can't be a constant input, my mistake. \$\endgroup\$ Aug 18 '12 at 18:40

You may be running out of instructions of one or the other flavor, according to MSDN, SM2.0 is quite restricted. The diagnostics of the shader compiler is rather horrible at times.

Shaders have restrictions for maximum instruction counts. Total Instruction slots: 96 (64 arithmetic and 32 texture).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.