I’m using Monogame 3.01 for Windows DirectX and am working with 2D sprites, however need to apply effects to each sprite. PixelShaders seem ideal but I’ve hit a brick wall trying to use them. My HLSL file is as follows;
float brightnessEffect;
float colorEffect;
// Our texture sampler
texture Texture;
sampler TextureSampler = sampler_state
{
Texture = <Texture>;
};
struct PixelInput
{
float2 TexCoord: TEXCOORD0;
};
float RGBCVtoHUE(in float3 RGB, in float C, in float V)
{
float3 Delta = (V - RGB) / C;
Delta.rgb -= Delta.brg;
Delta.rgb += float3(2,4,6);
Delta.brg = step(V, RGB) * Delta.brg;
float H;
H = max(Delta.r, max(Delta.g, Delta.b));
return frac(H / 6);
}
float3 RGBtoHSL(in float3 RGB)
{
float3 HSL = 0;
float U, V;
U = -min(RGB.r, min(RGB.g, RGB.b));
V = max(RGB.r, max(RGB.g, RGB.b));
HSL.z = (V - U) * 0.5;
float C = V + U;
if (C != 0)
{
HSL.x = RGBCVtoHUE(RGB, C, V);
HSL.y = C / (1 - abs(2 * HSL.z - 1));
}
return HSL;
}
float3 HUEtoRGB(in float H)
{
float R = abs(H * 6 - 3) - 1;
float G = 2 - abs(H * 6 - 2);
float B = 2 - abs(H * 6 - 4);
return saturate(float3(R,G,B));
}
float3 HSLtoRGB(in float3 HSL)
{
float3 RGB = HUEtoRGB(HSL.x);
float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
return (RGB - 0.5) * C + HSL.z;
}
float4 PixelShaderFunction(PixelInput input) : COLOR0
{
float4 colour = tex2D(TextureSampler, input.TexCoord);
float3 hslColour = RGBtoHSL(float3(colour.r,colour.g,colour.b));
hslColour.z +=brightnessEffect;
hslColour.z = saturate(hslColour.z);
hslColour.x += colorEffect;
if (hslColour.x > 1)
{
hslColour.x -=1;
}
hslColour.x = saturate(hslColour.x);
float3 newrgb = HSLtoRGB(hslColour);
return float4(newrgb.r, newrgb.g, newrgb.b, colour.a);
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}
The pixelshader is supposed to apply a colour and brightness effect to the sprite based on the HSL colour space. The fx file compile ok using the /DX11 switch. In the draw method I have
textureE.SetValue(cr.texture);
brightnessE.SetValue(Stage.Effects.Brightness / 100f);
colourE.SetValue(Stage.Effects.Color / 200f);
_effect.CurrentTechnique.Passes[0].Apply();
sb.Draw(cr.texture, new Microsoft.Xna.Framework.Rectangle(0, 0, 480, 360), Color.White);
which loops through all the sprites where texture,brightnessE, colourE are Effect Parameters.
The spritebatch runs in immediate mode, but although the brightness can be changed I never see a texture on the screen. It seems odd that I have to pass a texture as an effect parameter when the texture is part of the sprite batch draw.
Any idea what I’m doing wrong? Thank in advance.