Shader doesn't work in a particular case


I’ve made a shader which works as expected, but I’m having trouble implementing it. This is in my Draw method:


        spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, currentEffect, null);


        spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, null);
        spriteBatch.Draw(gameScreen, new Rectangle(0, 0, 1920, 1080), Color.White);

currentEffect is the effect. When I place it in the second spritebatch.begin it works as expected, yet placing it in the first causes it to work for one frame, then stop. I’m not sure if it something stupid or maybe something a little more complex. I will happily share more code if you require it,


If I’m not mistaken, effects sometimes require SpriteSortMode.Immediate

You can try doing it the same way it’s done here

Note that if you have a lot of draw calls in your first method this will slow your game down a bit, in which case you might want to consider why you want it applied to the whole game (slow) instead of applying it to the render target (faster).

SpriteSortMode.Immediate will force the image to be drawn immediately (slow) while SpriteSortMode.Deffered (or any other SpriteSortMode) will batch them together (fast).

Thanks for the response.

The confusing thing is that it works in the second, which has deferred, but not the first, which also has deferred.

The second point is interesting. I thought this would be faster as my game is 256x256, and im scaling it up to potentially 1920x1080, would this not mean that it is faster to apply the effect before drawing to the screen. I might be wrong though, im new to render targets.

Ok, I think i have a misunderstanding of how shaders work with render targets. I thought that in the first call of Begin() if I used a shader there it would apply the shader to the 256x256 render target, but i don’t think it does. Is this true? And is there a way to make it faster as it seems a little stupid apply a shader to a 1920x1080 screen when i’m only drawing in 256x256.

I assume you are drawing many things in your draw method. Think of it this way, the effect has to be executed on each and everything that you draw independently, which means it’s being executed many times when you run it on the whole thing.

If you’re using a render target, it only has to be executed once. If the effect is the same either way you do it, and you’re going to be using a render target anyway, it makes sense to do it on the render target.

There may be a way to do it without render targets, but I look at this way, your 256*256 pixel art game is going to run just fine on most things if you’re a little unoptimized at the cost of being lazy.

Can’t tell what your code is doing wrong but deferred should be able to work with effects if you’re using it properly.

Maybe read this

I don’t know what your effect is doing, but it sounds like you’re drawing everything in the first render target, then the second render is there solely to make it fit the screen. If that’s the case, I suspect that maybe the first frame is remaining on the render when it draws the following times and interfering with it.

You might try calling GraphicsDevice.Clear() right after switching to the null render target. You could also try setting the BlendState to Opaque for the 2nd SpriteBatch.

I think his first draw call is drawing many sprites rather than a single render target, and then his second one works while drawing just one render target.

In that case it’s impossible to tell what the issue really is, but I fail to see why (if it works as intended) he wouldn’t just do it on the second call anyway.

Thanks everyone. I think the issue was exactly what jamie alluded too. I think it was lagging and skipping the draw calls because it had to apply the shader to every object. I didn’t know that shaders were called on each object, and since my shader is rather heavy it makes sense that it would lag. Thanks everyone