I’ve been running through tutorials on shaders over the last few days, and I’m having an issue that I can’t explain, and I’m sure I’m just missing something as a newbie to this stuff. This is a 2D game so there’s no projection going on.
The goal of this shader is to take each section of a tile (which I’ve divided up mathematically into a top/bottom border, a left/right border, a corner, and a main tile section) and blend it gradually away (alpha-wise) towards the edges. I want to be able to use the “style” integer to be able to control which configuration of blending is being used. Style 4 is to make no changes to the tile’s alpha, and it’s used for the middle section, so I figured it would be a good test value since it should just draw every section with full alpha.
I’m not sure if I’m not calling the effects correctly or what, but when I call the shader I wrote, it draws a very strange result, and if I call the default .fx file (what you get if you create a new effect in Monogame Content Pipeline and then just run it), I get a black screen.
Here’s the code for my shader (hopefully the formatting is readable):
int style;
sampler s0;
sampler Sampler0 : register(s0) { };
float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
float4 color = tex2D(s0, coords);
if (style == 0)
{
if (coords.x < coords.y) color.a = coords.x;
else color.a = coords.y;
}
else if (style == 1) color.a = coords.y;
else if (style == 2)
{
if (coords.y < 1 - coords.x) color.a = coords.y;
else color.a = 1 - coords.x;
}
else if (style == 3) color.a = coords.x;
else if (style == 5) color.a = 1 - coords.x;
else if (style == 6)
{
if (coords.x < 1 - coords.y) color.a = coords.x;
else color.a = 1 - coords.y;
}
else if (style == 7) color.a = 1 - coords.y;
else if (style == 8)
{
if (1 - coords.x < 1 - coords.y) color.a = 1 - coords.x;
else color.a = 1 - coords.y;
}
return color;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}
And here’s how I’m calling it:
GameDataManager.BeginNormalEffectBatch(testBlend);
testBlend.Parameters["style"].SetValue(4);
testBlend.CurrentTechnique.Passes[0].Apply();
Which hits:
public static void BeginNormalEffectBatch(Effect effect)
{
if (debugMode)
{
NormalBatchesThisFrame++;
EffectBatchesThisFrame++;
}
Batch.Begin(sortMode: SpriteSortMode.Immediate, blendState: BlendState.AlphaBlend, samplerState: SamplerState.PointClamp, effect: effect);
}
…and then (after some math) the drawing happens:
int variant = screenTiles.Tiles[x, y].Variant; GameDataManager.Batch.Draw(testTiles2.Texture, new Rectangle(point1, size1), testTiles2.GetTileRectBorderCorner(id, variant), Color.White); GameDataManager.Batch.Draw(testTiles2.Texture, new Rectangle(point2, size2), testTiles2.GetTileRectBorderHorizontal(id, variant), Color.White);
When I run this, I get something that looks like it’s drawing the tiles as requested, but they aren’t textured - rather they seem to entirely use the one pixel at the top left of the section of texture I’ve provided, or something similar, because the output is reminiscent of an intellivision or atari game:
The tiles are drawn with my shader, but the “Character” test image (a placeholder for where the player’s animated character will appear) is drawn without. Here’s what the tiles look like when drawn without the shader, using a SpriteBatch with no “effect”:
Any help would be greatly appreciated…I don’t know anyone who is knowledgeable on this subject