Shader errors changing to DesktopGL

I’ve been tearing my hair out over this! I have a game that works fine as a Windows-only project, but I have been trying to covert it to a DesktopGL project so that I can run it on Windows and Linux. I think I’ve almost completed the task, but I’ve hit a problem that I just can’t figure out. My shaders throw up errors with DesktopGL. Here’s one such shader:

#if OPENGL
	#define SV_POSITION POSITION
	#define VS_SHADERMODEL vs_3_0
	#define PS_SHADERMODEL ps_3_0
#else
	#define VS_SHADERMODEL vs_4_0_level_9_1
	#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;

sampler s0;
bool blurApply = true;
float blurAmount = 1.0f;
float blurScaledAmount;

sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(s0, input.TextureCoordinates);
	if (blurApply)
	{
		blurScaledAmount = blurAmount * 0.0006f;
		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, 0.00f));
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, 0.00f));
		color += tex2D(s0, input.TextureCoordinates + float2(2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(-2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(3.0f * blurScaledAmount, 0.00f) * 0.25f);
		color += tex2D(s0, input.TextureCoordinates + float2(-3.0f * blurScaledAmount, 0.00f) * 0.25f);

		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, blurScaledAmount));
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -blurScaledAmount));
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, 2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, 3.0f * blurScaledAmount) * 0.25f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -3.0f * blurScaledAmount) * 0.25f);

		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, -blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, -blurScaledAmount) * 0.75f);

		color /= 17.0f;
	}
	return color;
}

technique SpriteDrawing
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};

And here’s how I access the shader in my C# code:
gaussianBlur.Parameters["blurApply"].SetValue(info.gaussianBlurApply); gaussianBlur.Parameters["blurAmount"].SetValue(info.gaussianBlurAmount);

And here’s the error that I get:
The command ""C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\MGCB.exe" /quiet /platform:DesktopGL /@:"D:\Work\Games\PACAdventure\PACAdventure\Content\Content.mgcb" /outputDir:"bin\DesktopGL\Content" /intermediateDir:"obj\DesktopGL\Content"" exited with code 2.

And here’s the console output:
1> D:/Work/Games/PACAdventure/PACAdventure/Content/shaders/GaussianBlur.fx: D:\\Work\\Games\\PACAdventure\\PACAdventure\\Content\\shaders\\GaussianBlur.fx(34,3-41): error X3025: global variables are implicitly constant, enable compatibility mode to allow modification

I have cobbled this shader together from pieces of other shaders, and I don’t know enough about them to be able to work out what’s wrong. From digging around in the forums I think I’ve worked out that the variables I define at the top need to be static constants, which seems to be what the output above is trying to tell me, but when I try to make them so, I get other errors. I’m not sure I need the #if/else stuff at the top anymore either. I wondered if anyone might be kind enough to point out the places in which I’m going wrong as I’m just randomly changing things without knowing what I’m doing!

Have you tried making blurScaledAmount a local variable instead of global?

1 Like

It’s complaining that you are doing the following.

bool blurApply = true;
float blurAmount = 1.0f;

Instead of

bool blurApply;
float blurAmount;

To say if these are constants they should either be defines or in the function.
I forget which gl or dx allows it to get overriden and the other doesn’t.
So in general if they need to be set from game1 i always to the later instead of the former so its compatable with either or.

error X3025: global variables are implicitly constant

I dunno if there are any differences for using bools but if that gives you trouble just make it a float and use 0 or 1 for true. and do a if(blurApply == 1.0f){ , }

1 Like

Ok I’ve changed blurScaledAmount to be a local variable in the function it’s used in and I have changed the remaining two global variables so that they’re not given a default value. So now my shader looks like this:

#if OPENGL
	#define SV_POSITION POSITION
	#define VS_SHADERMODEL vs_3_0
	#define PS_SHADERMODEL ps_3_0
#else
	#define VS_SHADERMODEL vs_4_0_level_9_1
	#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;

sampler s0;
bool blurApply;
float blurAmount;

sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(s0, input.TextureCoordinates);
	if (blurApply)
	{
		float blurScaledAmount;
		blurScaledAmount = blurAmount * 0.0006f;
		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, 0.00f));
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, 0.00f));
		color += tex2D(s0, input.TextureCoordinates + float2(2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(-2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(3.0f * blurScaledAmount, 0.00f) * 0.25f);
		color += tex2D(s0, input.TextureCoordinates + float2(-3.0f * blurScaledAmount, 0.00f) * 0.25f);

		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, blurScaledAmount));
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -blurScaledAmount));
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, 2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, 3.0f * blurScaledAmount) * 0.25f);
		color += tex2D(s0, input.TextureCoordinates + float2(0.00f, -3.0f * blurScaledAmount) * 0.25f);

		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(-blurScaledAmount, -blurScaledAmount) * 0.75f);
		color += tex2D(s0, input.TextureCoordinates + float2(blurScaledAmount, -blurScaledAmount) * 0.75f);

		color /= 17.0f;
	}
	return color;
}

technique SpriteDrawing
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};

However it still doesn’t work. I now get these errors:
The command ""C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\MGCB.exe" /quiet /platform:DesktopGL /@:"D:\Work\Games\PACAdventure\PACAdventure\Content\Content.mgcb" /outputDir:"bin\DesktopGL\Content" /intermediateDir:"obj\DesktopGL\Content"" exited with code 2. PACAdventureCross.Desktop

Processor 'EffectProcessor' had unexpected failure! PACAdventureCross.Desktop D:/Work/Games/PACAdventure/PACAdventure/Content/shaders/GaussianBlur.fx

And I have this in the console output:
1> D:/Work/Games/PACAdventure/PACAdventure/Content/shaders/GaussianBlur.fx
1>D:/Work/Games/PACAdventure/PACAdventure/Content/shaders/GaussianBlur.fx : error : Processor ‘EffectProcessor’ had unexpected failure!
1> System.Exception: IF src0 must have replicate swizzle
1> at TwoMGFX.ShaderData.CreateGLSL(Byte[] byteCode, Boolean isVertexShader, List1 cbuffers, Int32 sharedIndex, Dictionary2 samplerStates, Boolean debug)
1> at TwoMGFX.OpenGLShaderProfile.CreateShader(ShaderResult shaderResult, String shaderFunction, String shaderProfile, Boolean isVertexShader, EffectObject effect, String& errorsAndWarnings)
1> at TwoMGFX.EffectObject.CreateShader(ShaderResult shaderResult, String shaderFunction, String shaderProfile, Boolean isVertexShader, String& errorsAndWarnings)
1> at TwoMGFX.EffectObject.CompileEffect(ShaderResult shaderResult, String& errorsAndWarnings)
1> at Microsoft.Xna.Framework.Content.Pipeline.Processors.EffectProcessor.Process(EffectContent input, ContentProcessorContext context)
1> at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
1> at MonoGame.Framework.Content.Pipeline.Builder.PipelineManager.ProcessContent(PipelineBuildEvent pipelineEvent)
1> fail - IF src0 must have replicate swizzle
1>C:\Program Files (x86)\MSBuild\MonoGame\v3.0\MonoGame.Content.Builder.targets(84,5): error MSB3073: The command ““C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\MGCB.exe” /quiet /platform:DesktopGL /@:“D:\Work\Games\PACAdventure\PACAdventure\Content\Content.mgcb” /outputDir:“bin\DesktopGL\Content” /intermediateDir:“obj\DesktopGL\Content”” exited with code 2.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

This shader is being used with sprite batch right ?

Hold on ill make a test project and make sure it runs im pretty sure the line here
and the use of it is screwing up your shader.

sampler s0; 

try the following really quick

// sampler s0; // comment it out.

// in all the lines below change out the s0 to the SpriteTextureSampler
// as below

color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, 0.00f));

I think there is some extra do’s for spritebatch to use the texture you send in thru draw directly to set that up in the sampler state itself lemme go look. brb

Edit

here is a snippet from a very simple example project below.

float percent;

sampler2D TextureSampler : register(s0)
{
    Texture = (Texture);
};

float4 MainPS(float4 position : SV_Position, float4 color : COLOR0, float2 TextureCoordinates : TEXCOORD0) : COLOR0
{
    float4 col = tex2D(TextureSampler, TextureCoordinates)* color;
    col.rgb = (col.r + col.g + col.b) / 3.0f * percent; // grey scale and darken
    return col;
}

the : register(s0) should still work with spritebatch directly as shown here.
to link your defined sampler to register s0 which spritebatch is setting the texture t0 to match if i have that right.

1 Like

Hold on im going to try to get your shader to compile i might of missed a couple things to get this to work.

1 Like

Many thanks for your help so far @willmotil . I’ve modified my shader to work like your example (I think), but I get this “swizzle” error still.

1>D:/Work/Games/PACAdventure/PACAdventure/Content/shaders/GaussianBlur.fx : error : Processor 'EffectProcessor' had unexpected failure!
1>  System.Exception: IF src0 must have replicate swizzle
1>     at TwoMGFX.ShaderData.CreateGLSL(Byte[] byteCode, Boolean isVertexShader, List`1 cbuffers, Int32 sharedIndex, Dictionary`2 samplerStates, Boolean debug)
1>     at TwoMGFX.OpenGLShaderProfile.CreateShader(ShaderResult shaderResult, String shaderFunction, String shaderProfile, Boolean isVertexShader, EffectObject effect, String& errorsAndWarnings)
1>     at TwoMGFX.EffectObject.CreateShader(ShaderResult shaderResult, String shaderFunction, String shaderProfile, Boolean isVertexShader, String& errorsAndWarnings)
1>     at TwoMGFX.EffectObject.CompileEffect(ShaderResult shaderResult, String& errorsAndWarnings)
1>     at Microsoft.Xna.Framework.Content.Pipeline.Processors.EffectProcessor.Process(EffectContent input, ContentProcessorContext context)
1>     at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
1>     at MonoGame.Framework.Content.Pipeline.Builder.PipelineManager.ProcessContent(PipelineBuildEvent pipelineEvent)
1>  fail - IF src0 must have replicate swizzle

Here is my new shader code:

#if OPENGL
	#define SV_POSITION POSITION
	#define VS_SHADERMODEL vs_3_0
	#define PS_SHADERMODEL ps_3_0
#else
	#define VS_SHADERMODEL vs_4_0_level_9_1
	#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;

bool blurApply;
float blurAmount;

sampler2D SpriteTextureSampler : register(s0)
{
	Texture = (Texture);
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates);
	if (blurApply)
	{
		float blurScaledAmount;
		blurScaledAmount = blurAmount * 0.0006f;
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, 0.00f));
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, 0.00f));
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-2.0f * blurScaledAmount, 0.00f) * 0.5f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(3.0f * blurScaledAmount, 0.00f) * 0.25f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-3.0f * blurScaledAmount, 0.00f) * 0.25f);

		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, blurScaledAmount));
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -blurScaledAmount));
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, 2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -2.0f * blurScaledAmount) * 0.5f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, 3.0f * blurScaledAmount) * 0.25f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -3.0f * blurScaledAmount) * 0.25f);

		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, blurScaledAmount) * 0.75f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, -blurScaledAmount) * 0.75f);
		color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, -blurScaledAmount) * 0.75f);

		color /= 17.0f;
	}
	return color;
}

technique SpriteDrawing
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};

Ok it works but your shader code the numbers your using need to be modified i think to sample properly i didn’t try to do that here just made it run.

The bool was the problem for that src0 swizzle message … i just yanked it out.

game1 test.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace HowToGausianBlurAndys
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D texture;
        Effect effect;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            texture = Content.Load<Texture2D>("cutePuppy");
            effect = Content.Load<Effect>("GausianBlurEffect");
            effect.CurrentTechnique = effect.Techniques["Blur"];
            effect.Parameters["blurAmount"].SetValue(1f);
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            effect.CurrentTechnique = effect.Techniques["Blur"];

            spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, effect, null);
            spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.Red);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

shader… 2 different examples one is commented out.

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

float blurAmount;

sampler2D SpriteTextureSampler : register(s0)
{
	Texture = (Texture);
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates);
	float blurScaledAmount;
	blurScaledAmount = blurAmount * 0.0006f;
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, 0.00f));
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, 0.00f));
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(2.0f * blurScaledAmount, 0.00f) * 0.5f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-2.0f * blurScaledAmount, 0.00f) * 0.5f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(3.0f * blurScaledAmount, 0.00f) * 0.25f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-3.0f * blurScaledAmount, 0.00f) * 0.25f);

	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, blurScaledAmount));
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -blurScaledAmount));
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, 2.0f * blurScaledAmount) * 0.5f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -2.0f * blurScaledAmount) * 0.5f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, 3.0f * blurScaledAmount) * 0.25f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(0.00f, -3.0f * blurScaledAmount) * 0.25f);

	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, blurScaledAmount) * 0.75f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, blurScaledAmount) * 0.75f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(-blurScaledAmount, -blurScaledAmount) * 0.75f);
	color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(blurScaledAmount, -blurScaledAmount) * 0.75f);

	color /= 17.0f;
	// Color here is the input color from spriteBatch.Draw(, ,, Color.White , , , );  white doesn't change anything.
	return color * input.Color;
}


technique Blur
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};



//_______________________
// or like this
//_______________________


//#if OPENGL
//#define SV_POSITION POSITION
//#define VS_SHADERMODEL vs_3_0
//#define PS_SHADERMODEL ps_3_0
//#else
//#define VS_SHADERMODEL vs_4_0_level_9_1
//#define PS_SHADERMODEL ps_4_0_level_9_1
//#endif
//
//float blurAmount;
//
//sampler2D TextureSampler : register(s0)
//{
//	Texture = (Texture);
//};
//
//// You would need to use your own vertex shader and sort of force mg to use it after begin was called by overridding it. 
//// Which im not gonna go into typically at that point its time to start drawing with quads and get full control over the effect.
////struct VertexShaderOutput
////{
////	float4 Position : SV_POSITION;
////	float4 Color : COLOR0;
////	float2 TextureCoordinates : TEXCOORD0;
////};
////
////float4 MainPS(VertexShaderOutput input) : COLOR
//
//float4 MainPS(float4 position : SV_Position, float4 shadedColor : COLOR0, float2 TextureCoordinates : TEXCOORD0) : COLOR0
//{
//	float4 color = tex2D(TextureSampler, TextureCoordinates);
//	float blurScaledAmount = blurAmount * 0.0006f;
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(blurScaledAmount, 0.00f));
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(-blurScaledAmount, 0.00f));
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(2.0f * blurScaledAmount, 0.00f) * 0.5f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(-2.0f * blurScaledAmount, 0.00f) * 0.5f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(3.0f * blurScaledAmount, 0.00f) * 0.25f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(-3.0f * blurScaledAmount, 0.00f) * 0.25f);
//
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, blurScaledAmount));
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, -blurScaledAmount));
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, 2.0f * blurScaledAmount) * 0.5f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, -2.0f * blurScaledAmount) * 0.5f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, 3.0f * blurScaledAmount) * 0.25f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(0.00f, -3.0f * blurScaledAmount) * 0.25f);
//
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(blurScaledAmount, blurScaledAmount) * 0.75f);
//	color += tex2D(TextureSampler, TextureCoordinates.xy + float2(-blurScaledAmount, blurScaledAmount) * 0.75f);
//	color += tex2D(TextureSampler,  TextureCoordinates.xy + float2(-blurScaledAmount, -blurScaledAmount) * 0.75f);
//	color += tex2D(TextureSampler,  TextureCoordinates.xy + float2(blurScaledAmount, -blurScaledAmount) * 0.75f);
//
//	color /= 17.0f;
//	return color * shadedColor;
//}
//
//technique Blur
//{
//	pass P0
//	{
//		PixelShader = compile PS_SHADERMODEL MainPS();
//	}
//};

Thats actually the blur shader running tinted to red via draw its just the sampling numbers are off.

1 Like

You can add this to that shader then switch techniques in draw as required.
Instead of using the bool

or just use a float instead of the bool as previously described.

float4 RegularPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates);
	// Color here is the input color from spriteBatch.Draw(, ,, Color.White , , , );  white doesn't change anything.
	return color * input.Color;
}


technique Basic
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL RegularPS();
	}
};

// in game1

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            if(info.gaussianBlurApply)
                 effect.CurrentTechnique = effect.Techniques["Blur"];
            else
                 effect.CurrentTechnique = effect.Techniques["Basic"];

            spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, effect, null);
            spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.Red);
            spriteBatch.End();

            base.Draw(gameTime);
        }
1 Like

Thanks so much for your help @willmotil! My game now builds successfully! There’s something wrong with it since most of my graphics aren’t showing, but that’ll be an unrelated problem I’m sure. I can’t thank you enough though, I’m so clueless when it comes to shaders!

Im going to change that above post to a better working version in a second that also lets you select the number of samples to increase the quality of the blur.

Actually ill repost it here.

Controls Hit f1 to change it from bluring to not bluring.

You can change the number of samples per dimension the total samples made are samples * samples and it samples in a square around each pixel by half the samples x and y.

Game1 here and shader below.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace HowToGausianBlurAndys
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D texture;
        Effect effect;

        bool _useBlur = true;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            texture = Content.Load<Texture2D>("cutePuppy");
            effect = Content.Load<Effect>("GausianBlurEffect");
            effect.CurrentTechnique = effect.Techniques["Blur"];
            effect.Parameters["numberOfSamplesPerDimension"].SetValue(20);
            effect.Parameters["pixelResolutionX"].SetValue(1f / texture.Width);
            effect.Parameters["pixelResolutionY"].SetValue(1f / texture.Height);
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            if (IsPressedWithDelay(Keys.F1, gameTime))
                _useBlur = ! _useBlur;

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);


            if (_useBlur)
                effect.CurrentTechnique = effect.Techniques["Blur"];
            else
                effect.CurrentTechnique = effect.Techniques["Basic"];

            spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, effect, null);
            spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.Red);
            spriteBatch.End();

            base.Draw(gameTime);
        }

        #region helper functions

        public bool IsPressedWithDelay(Keys key, GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(key) && IsUnDelayed(gameTime))
                return true;
            else
                return false;
        }

        float delay = 0f;
        bool IsUnDelayed(GameTime gametime)
        {
            if (delay < 0)
            {
                delay = .25f;
                return true;
            }
            else
            {
                delay -= (float)gametime.ElapsedGameTime.TotalSeconds;
                return false;
            }
        }

        #endregion
    }
}

Shader

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

int numberOfSamplesPerDimension = 10;
float pixelResolutionX;
float pixelResolutionY;

sampler2D SpriteTextureSampler : register(s0)
{
	Texture = (Texture);
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates);
	float halfnumberOfSamplesPerDimension = numberOfSamplesPerDimension / 2.0f;
	for (float u = 0.0f; u < numberOfSamplesPerDimension; u += 1.0f)
	{
		for (float v = 0.0f; v < numberOfSamplesPerDimension; v += 1.0f)
		{
			float su = (u - halfnumberOfSamplesPerDimension) * pixelResolutionX;
			float sv = (v - halfnumberOfSamplesPerDimension) * pixelResolutionY;
			color += tex2D(SpriteTextureSampler, input.TextureCoordinates + float2(su, sv));
		}
	}
	color /= numberOfSamplesPerDimension * numberOfSamplesPerDimension;
	// Color here is the input color from spriteBatch.Draw(, ,, Color.White , , , );  white doesn't change anything.
	return color * input.Color;
}

technique Blur
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};

float4 RegularPS(VertexShaderOutput input) : COLOR
{
	float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates);
	// Color here is the input color from spriteBatch.Draw(, ,, Color.White , , , );  white doesn't change anything.
	return color * input.Color;
}

technique Basic
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL RegularPS();
	}
};

1 Like

You’re some kind of wizard lol. Thanks a lot for this, I’m going to tinker with the shader more when I’ve worked out why everything else is missing!

Welcome

I wish i was i’ve been stuck on my one shader problem for like forever.

Anyways just keep practicing you know after you do something enough you get better and better at it.

1 Like