Sprite batch refusing to set sample state to clamp

Hi all,

I’m really not sure what the issue is since its so basic…
I draw on two render targets and a spritebatch like this:

                    _graphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                    _spritebatch.Begin(SpriteSortMode.Immediate, blendState: BlendState.Additive, effect: AmbientAndEmissionApplyEffect, samplerState: SamplerState.PointClamp);
                    _spritebatch.Draw(_gbuffer.EmissionAndMaterialRT, _gbuffer.LightsRT.Bounds, AmbientColor);
                    _spritebatch.End();

In the effect code I define the sampler like this:

Texture2D SpriteTexture;
sampler2D SpriteTextureSampler;

But I also tried to define it like this to be sure:

Texture2D SpriteTexture;
sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
	AddressU = CLAMP;
    AddressV = CLAMP;
};

However, no matter what I do, rendering insist on being wrap mode, meaning that if for example I multiply UVs by 2, I’m seeing it tile twice on X and Y axis, instead of having it clamped.

This is an issue because this effect adds blur when rendering, so I’m getting bleeding pixels from the edges due to the wrapping.

Any idea why MonoGame insist on wrapping and not clamping or what I’m doing wrong?

Thanks!

Edit:
Looks like if I do this:

for (int i = 0; i < 4; ++i) { _graphicsDevice.SamplerStates[i] = SamplerState.PointClamp; }

I finally get clamp. But why would the sampler not be index 0? Its a bit odd that it works. Ideas why?

Well, either way, no matter what, you should be explicit when declaring resources in Shader, meaning that

Texture2D  SpriteTexture

should be more like

Texture2D  SpriteTexture : register(t0)

And ofc same for sampler state (just s0).

If there would be collision with some, let’s say, include or macro, then you would get warning from compiler and save yourself these troubles. I agree it’s bit weird since spritebatch directly bind to slot 0, however to find what’s really going we would have to see bigger chunk of the code.

You can always spin up Nsight, find drawcall and confirm what is being bound where and why.

Thanks for the tip, but can you elaborate on why its important to always explicitly bind? For some reason monogame sprite effect template (what you get when you create a new one via the content manager tool) doesnt do that.

Monogame sprite effect template, if I remember correctly, doesn’t even properly define/declare constant buffer, which I assume is because of stupid ancient OpenGL SM 2.0 compatibility and they didn’t want to create compiler macro to sort out that mess because I think they always assumed Mojo hell can’t stick for long.

Anyway it is important because of issues you are having. When it is not explicitly stated compiler will assign slot order based on declaration order, it gets more complicated when you use includes.

Uniforms that are not explicitly tied in properly structured buffers are then prone to aggressive optimization. You know cases when MG users complain about their uniform being optimized out when testing stuff? Well, mostly their fault because they either don’t know how to or refuse to write cb properly (not that MG could utilize them in optimal manner, DirectX 9 legacy api issues, but it would sort out some of the issues on “user” side).

1 Like

Thanks man, appreciate the info!

1 Like