0
votes

I want to apply a pixel shader onto my background sprite, to create some sort of lighting. So i draw a Render Target with the light on it and want to merge it onto the background via the Pixel shader. This is the essential code:

  GraphicsDevice.Clear(Color.Black);

    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

    lighting.Parameters["lightMask"].SetValue(lightingMask);
    lighting.CurrentTechnique.Passes[0].Apply();

    spriteBatch.Draw(hexBack, new Vector2(0, 0), Color.White);

    spriteBatch.End();

In this case, hexBack is the Rendertarget with a simple sprite drawn in it and lightingMask is the rendertarget with the light texture in it. Both are Backbuffer width and height.

So when i try to run the program, it crashes with: XNA Framework Reach profile requires TextureAddressMode to be Clamp when using texture sizes that are not powers of two.

So i tried to set up clamping, but i cant find a way to get it working.

The shader code:

texture lightMask;
sampler mainSampler : register(s0);
sampler lightSampler = sampler_state{Texture = lightMask;};

struct PixelShaderInput
{
    float4 TextureCoords: TEXCOORD0;

};

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{

    float2 texCoord = input.TextureCoords;

    float4 mainColor = tex2D(mainSampler, texCoord);
    float4 lightColor = tex2D(lightSampler, texCoord);

    return mainColor * lightColor;
}

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

Thanks for your help!

pcnx

2
@Elideb: Do you have a reference to back that up? I'm pretty sure there is only a memory penalty (not performance) for using non-power-of-two textures, as XNA has to pad them out to power-of-two size (and therefore wrapping won't work). Also the look shouldn't be affected unless you're actually using wrapping.Andrew Russell
Also, @pcnx, SpriteBatch.Begin uses LinearClamp by default. So you must be setting it to LinearWrap or similar somewhere else in your code?Andrew Russell
@AndrewRussell: I was drawing from past experiences with cheap cards. Comment removed.Elideb

2 Answers

0
votes

If you are unable to use power of two textures, you have to change your Spritebath.begin call and specify a SamplerState. The minimum to specify should be

public void Begin (
         SpriteSortMode sortMode,
         BlendState blendState,
         SamplerState samplerState,
         DepthStencilState depthStencilState,
         RasterizerState rasterizerState
)
0
votes

The error refers to your texture addressing mode (ie: does the texture wrap around at the edges, or is it clamped at the edges). Nothing to do with a shader.

Use one of the overloads for SpriteBatch.Begin (MSDN) that takes a SamplerState, and pass in SamplerState.LinearClamp (MSDN).

The default for SpriteBatch.Begin is SamplerState.LinearClamp, so you must be setting a different state (eg: LinearWrap) onto the graphics device somewhere else in your code? Don't do that.

(Alternately: change from the Reach profile to the HiDef profile in your project settings.)