Wednesday, November 13, 2019

xna - How to set multiple times, in a single spritebatch, the same pixel shader parameter


I make a test with Effect class in XNA and I want to set multiple times the same parameters (MyParameter in below code).


My code is :


[...]
//In Engine class
Effect ShaderEffect = GameEngine.Instance.Content.Load(@"shaders\test");

spriteBatch.Begin(
SpriteSortMode.Deferred,
BlendState.AlphaBlend,

SamplerState.PointWrap,
DepthStencilState.Default,
RasterizerState.CullNone,
ShaderEffect);

[...]

//in drawable class
foreach(//big loop) {
ShaderEffect.Parameters["MyParameter"].SetValue(//random vector4);

spriteBatch.Draw(
SpriteSheet,
ScreenRect,
sprite_to_draw.Rectangle,
color,
rotation,
Scene.getInstance().Camera.Position,
sprite_to_draw.SpriteEffect,
layer
);

}

[...]

//In Engine class
spriteBatch.End();
[...]

But on my screen it look like the Parameter "MyParameter" is not overwrite.


So can I overwrite it and If yes do you know how ?



Thanks



Answer



I'm afraid there is not an easy solution to this problem, because you can not add extra information to the vertices generated by SpriteBatch.


Like Blau said, you can change the SpriteBatch to Immediate mode, or call Begin() and End() every time you change the parameter, but you will get a ton of draw calls and won't be batching anything anymore. I can think of two additional solutions:


1) SpriteBatch.Draw takes a color parameter and stores it inside each vertex of the quads it generates. You can then get this value back in your custom shaders. If you do not need to use the default color tinting, and your only parameter is a float4 like in your example, you could hijack the color parameter for your needs, and override the default pixel shader so that it does not tint the sprite.


float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// Do whatever you want with the color parameter
// Sample texture but ignore color because it's not really a color
return tex2D(TextureSampler, texCoord);

}

2) Implement your own SpriteBatch with a custom vertex struture that stores the additional information that you need for the shader, so that you do not need to change parameters between drawing each sprite. You can check the following question for some ideas on how to implement it yourself.


How exactly does XNA's SpriteBatch work?


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...