title: HLSL and XNA: How do I get the position and color of surrounding pixels of the current pixel shader iteration?
body: <p><b>Abstract and Goal:</b></p>
  
  <p>I am trying to make a shader to perform a simple window effect for a game editor. The effect will draw a frame with a low value border color and a high value highlight. I've tried many methods, but overall I have only come up with one possible solution to achieve this using the GPU.</p>
  
  <p>First I create a custom vertex type for storing the XY coordinates of a vector in screen space.</p>
  
  <pre><code>using Microsoft.Xna.Framework;
  using Microsoft.Xna.Framework.Graphics;
  
  namespace WindowsGame1 {
      public struct Vertex2D : IVertexType {
          public Vector2 Position;
          public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(new VertexElement(0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0));
  
          public Vertex2D(float x, float y) {
              Position = new Vector2(x, y);
          }
  
          VertexDeclaration IVertexType.VertexDeclaration {
              get {
                  return VertexDeclaration;
              }
          }
      }
  }
  </code></pre>
  
  <p>Next I create an instance of a custom Window class. The constructor sets up the vertex buffer and sets the view, projection, and color parameters in the effect.</p>
  
  <p>Here is the effect file.</p>
  
  <pre><code>float4x4 view;
  float4x4 projection;
  float4 color;
  float shadowPercent = 0.36893203883495145631067961165049;
  float highlightPercent = 1.262135922330097087378640776699;
  Texture2D targetTexture;
  
  struct FillVertexShaderInput {
      float4 position : POSITION0;
  };
  
  struct FillPixelShaderInput {
      float4 position : POSITION0;
  };
  
  struct BorderPixelShaderInput {
      float4 position : SV_Position;
  };
  
  // Transforms color component range from 0-255 to 0-1.
  float4 ClampColor(float4 color) {
      return float4(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
  }
  
  // Shifts the value of a color by a percent to get border color and highlight color from a fill color.
  float4 ShiftValue(float4 color, float percent) {
      return float4(clamp(color[0] * percent, 0, 1), clamp(color[1] * percent, 0, 1), clamp(color[2] * percent, 0, 1), clamp(color[3] * percent, 0, 1));
  }
  
  FillPixelShaderInput FillVertexShader(FillVertexShaderInput input) {
      FillPixelShaderInput output;
      output.position = mul(mul(input.position, view), projection);
      return output;
  }
  
  float4 FillPixelShader(FillPixelShaderInput input) : COLOR0 {
      return color;
  }
  
  float4 BorderPixelShader(BorderPixelShaderInput input) : COLOR0 {
      // Get color of pixel above?
      // float4 tempColor = texture.Sample(sampler, (input.position[0], input.position[1] - width));
      return color;
  }
  
  technique Frame {
      // Store Texture2D, sampler2D, and others to be stored between passes?
      /*Texture2D texture;
      sampler2D sampler;
      float width;
      float height;
      texture.GetDimensions(width, height);
      color = ClampColor(color);
      float4 shadowColor = ShiftValue(color, shadowPercent);
      float4 highlightColor = ShiftValue(color, highlightPercent);*/
  
      pass Fill {
          VertexShader = compile vs_2_0 FillVertexShader();
          PixelShader = compile ps_2_0 FillPixelShader();
      }
  
      pass Border {
          PixelShader = compile ps_4_0 BorderPixelShader();
      }
  }
  </code></pre>
  
  <p>I would like to be able to store the data between passes, but I don't know if that is possible so I tried storing a render target in XNA and using it as a parameter for the next pass.</p>
  
  <p>Here is the Draw code of the Window.</p>
  
  <pre><code>public void Draw(Game1 game) {
      // rectangle is a simple window for this test.
      RenderTarget2D target = new RenderTarget2D(game.GraphicsDevice, rectangle.Width, rectangle.Height);
      game.GraphicsDevice.SetRenderTarget(target);
      game.GraphicsDevice.BlendState = BlendState.AlphaBlend;
      game.GraphicsDevice.Clear(Color.Transparent);
      game.GraphicsDevice.SetVertexBuffer(vertexbuffer);
      effect.Techniques["Frame"].Passes["Fill"].Apply();
      game.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
      game.GraphicsDevice.SetRenderTarget(null);
      effect.Parameters["targetTexture"].SetValue(target);
      effect.Techniques["Frame"].Passes["Border"].Apply();
  }
  </code></pre>
  
  <p>If I can get the position and color of surrounding pixels of the current pixel in a pixel shader, I can determine what color to draw the pixel at the current position. The Fill works fine. I just don't know the best way to go about drawing the border shadow and highlight. Also I am having problems with the alpha blending. Everything except the window is the default dark purple color, even though I set alpha blending and clear the render target buffer to transparent.</p>
  
  <p>Thanks in advance if you decide to help.</p>