Shader working in DesktopGL, but not WindowsDX

I’ve got a simple DesktopGL project with a shader that draws circles.

I tried doing the same in a Windows DirectX project, but the shader won’t compile and the error message isn’t helpful.

Severity	Code	Description	Project	File	Line	Suppression State
Error	MSB3073	The command "dotnet C:\Users\laurs\.nuget\packages\monogame.content.builder.task\3.8.0.1641\build\\..\tools\netcoreapp3.1\any\mgcb.dll /quiet /@:"E:\Code\DXCircles\Content\Content.mgcb" /platform:Windows /outputDir:"E:/Code/DXCircles/Content/bin/Windows/Content" /intermediateDir:"E:/Code/DXCircles/Content/obj/Windows/Content" /workingDir:"E:/Code/DXCircles/Content/"" exited with code 1.	DXCircles	C:\Users\laurs\.nuget\packages\monogame.content.builder.task\3.8.0.1641\build\MonoGame.Content.Builder.Task.targets	138	

The full 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;
float TestingTesting;
float2 CircleCenter;
float CircleRadius;

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

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

float4 MainPS(VertexShaderOutput input) : COLOR
{
	return tex2D(SpriteTextureSampler,input.TextureCoordinates) * input.Color;
}

float4 CirclePS(VertexShaderOutput input) : COLOR
{
	float distanceToCenter = length(input.Position.xy - CircleCenter);
	float a = distanceToCenter - CircleRadius;
	a = clamp(a, 0, 1);
	a = 1 - a;
	
	float4 retval = tex2D(SpriteTextureSampler, input.TextureCoordinates) * input.Color;
	retval.a *= a;
	return retval;
}

float4 CircleOutlinePS(VertexShaderOutput input) : COLOR
{
	// Positioning of the outline. -1 for inside radius, 0 for around radius and 1 for outside radius.
	int linePosition = -1;
	float lineThickness = 2;
	float distanceToCenter = length(input.Position.xy - CircleCenter);
	float a = abs(distanceToCenter - (CircleRadius + lineThickness * linePosition)) + 1 - lineThickness / 2;
	a = clamp(a, 0, 1);
	a = 1 - a;

	float4 retval = tex2D(SpriteTextureSampler, input.TextureCoordinates) * input.Color;
	retval.a *= a;
	return retval;
}

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

technique Circle
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL CirclePS();
	}
};

technique CircleOutline
{
	pass P0
	{
		PixelShader = compile PS_SHADERMODEL CircleOutlinePS();
	}
};

The problem seems to be related to using the Position input, but I don’t know how to get it to work.

When I added a new shader through the pipeline tool it had

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

and I couldn’t use Position in DesktopGL either, but it worked after changing it to SV_Position (something I saw in another post)

It’s not a big problem, I can continue using DesktopGL, but I’d like to understand what’s wrong.

Use the monogame content tool to compile the shader and you will get error information

However one thing I can see is that you define SV_POSITION then use SV_Position, not the same

2 Likes

Thanks, I didn’t know that I’d get different error messages when building in the content tool instead of VS.

I hadn’t touched the defines at all, they are what I got from a new sprite effect file from the content tool.

Shader model ps_4_0_level_9_1 doesn't allow reading from position semantics.

Apparently I can’t use Position in DirectX 9 at all.

I set ps_4_0 and vs_4_0 instead and set the graphics profile to HiDef and it works. Only problem at this point is that OpenGL and DirectX have flipped Y compared to each other, but that just means I can’t use 100% the same code for both.

1 Like