[Solved] Textures rendering upside down and small with Pixel Shader

I’m new to HLSL, attempting to use MonoGame to do some simple post processing effects.

Here is my HLSL file, taken from this XNA tutorial

//------------------------------ TEXTURE PROPERTIES ----------------------------
// This is the texture that SpriteBatch will try to set before drawing
texture ScreenTexture;
 
// Our sampler for the texture, which is just going to be pretty simple
sampler TextureSampler = sampler_state
{
    Texture = <ScreenTexture>;
};
 
//------------------------ PIXEL SHADER ----------------------------------------
// This pixel shader will simply look up the color of the texture at the
// requested point, and turns it into a shade of gray
float4 PixelShaderFunction(float2 TextureCoordinate : TEXCOORD0) : COLOR0
{
    float4 color = tex2D(TextureSampler, TextureCoordinate);
 
    float value = (color.r + color.g + color.b) / 3; 
    color.r = value;
    color.g = value;
    color.b = value;
 
    return color;
}
 
//-------------------------- TECHNIQUES ----------------------------------------
// This technique is pretty simple - only one pass, and only a pixel shader
technique BlackAndWhite
{
    pass Pass1
    {
        PixelShader = compile ps_4_0 PixelShaderFunction();
    }
}

The only line I’ve changed is the compiler version from ps_2_0 -> ps_4_0, since MonoGame needs 4.0 (I think?)

I’m using MonoGame 3.4, and I’ve changed nothing from the initial project template except the following:

protected override void LoadContent()
{
	// Create a new SpriteBatch, which can be used to draw textures.
	spriteBatch = new SpriteBatch(GraphicsDevice);
	// TODO: use this.Content to load your game content here
	BlackAndWhiteEffect = Content.Load<Effect>("BlackAndWhite");
	Image = Content.Load<Texture2D>("smiley");
}

private Effect BlackAndWhiteEffect
{
	get;
	set;
}

private Texture2D Image
{
	get;
	set;
}

protected override void Draw(GameTime gameTime)
{

	GraphicsDevice.Clear(Color.CornflowerBlue);

	spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, BlackAndWhiteEffect);
	//spriteBatch.Begin();

	spriteBatch.Draw(Image, GraphicsDevice.Viewport.Bounds, Color.White);

	spriteBatch.End();

	base.Draw(gameTime);
}

Here is the result of the code executing in monogame:

And here is the result from an identical project created in XNA (except for ps_2_0 in the shader, as mentioned before):

Would appreciate any help. I can upload both solution files if needed.

Edit:

I believe I am seeing the same issue that this person was back in May: Shader Effect Flips Out

Could it be something to do with an OpenGL/DirectX incompatibility?

I have solved my problem, although I am not sure why exactly this solves the problem. This post was helpful to me: http://www.software7.com/blog/monogame-hlsl-shader-example-for-a-post-processing-blur-effect/

Here is my working shader:

//------------------------------ TEXTURE PROPERTIES ----------------------------
// This is the texture that SpriteBatch will try to set before drawing
texture2D ScreenTexture;

// Our sampler for the texture, which is just going to be pretty simple
sampler TextureSampler = sampler_state
{
	Texture = <ScreenTexture>; 
};

//------------------------ PIXEL SHADER ----------------------------------------
// This pixel shader will simply look up the color of the texture at the
// requested point, and turns it into a shade of gray
float4 PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : SV_TARGET0
{
	float4 color = ScreenTexture.Sample(TextureSampler, texCoord.xy);

    float value = (color.r + color.g + color.b) / 3; 
    color.r = value;
    color.g = value;
    color.b = value;
 
    return color;
}
 
//-------------------------- TECHNIQUES ----------------------------------------
// This technique is pretty simple - only one pass, and only a pixel shader
technique BlackAndWhite
{
    pass Pass1
    {
		PixelShader = compile ps_4_0_level_9_3  PixelShaderFunction();
    }
}

Here’s what I did: used Texture2D instead of Texture, changed the arguments of PixelShaderFunction (some of which I don’t use, but seem to be required), used Texture.Sample instead of tex2D, and changed to ps_4_0_level_9_3

The rest of the code remained the same.

If anyone knows why this works, I’d be happy to hear the explanation.

Edit:

For anyone experiencing this problem in the future, here is the explanation. All of the parameters are needed for the PixelShaderFuction for registers to be mapped correctly. See the post here:

http://www.software7.com/blog/pitfalls-when-developing-hlsl-shader