Error when building shader: Invalid input semantic

I get this error when trying to build the following shader:
Lighting.fx(30,18-27): error X4502: invalid input semantic ‘POSITION’: Legal indices are in [1,15]
Lighting.fx(30,18-27): error X4502: invalid ps_3_0 input semantic ‘POSITION’
Lighting.fx(30,18-27): error X4502: invalid input semantic ‘POSITION’: Legal indices are in [1,15]
Lighting.fx(30,18-27): error X4502: invalid ps_3_0 input semantic ‘POSITION’

I am using dotnet core on MacOS High Sierra (Can provide more information if need). I tried experimenting with gradually removing and reintroducing my uniform variables, and as soon as I introduce light_diffuse, I start getting the errors. I was able to get the shader to build If I change the #define for SV_POSITION to POSITION1, but then I get a runtime exception about shader compilation, obviously that is causing it to generate bad GLSL. I have very little experience with HLSL, I am a little more comfortable in GLSL, I am at a loss for what is going on here.

#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;
float4 light_pos;

float4 light_diffuse;
//float4 light_specular;

float light_constant;
float light_linear;
float light_quadratic;

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;

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

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

float4 MainPS(VertexShaderOutput input) : COLOR
{
  float distance = length(light_pos - input.Position);
  float attenuation = 1.0 / (light_constant + light_linear * distance +
    		    light_quadratic * (distance * distance));

  float4 ambient = AmbientColor * AmbientIntensity;
  float4 diffuse = light_diffuse * attenuation;
  //float4 specular = light_specular * attenuation;

  //float4 lightIntensity = ambient + diffuse + specular;

  float lightIntensity = ambient + diffuse;
	return tex2D(SpriteTextureSampler, input.TextureCoordinates) * lightIntensity;
}

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

You don’t define the vertex shader in the effect?

I created this using the “Sprite Effect” template, and it generated without the vertex shader. I am assuming it uses the default sprite vertex shader, the shader did work exactly as I expected when I just had the logic for ambient lighting in there, so I know it is picking up and using the correct vertex shader.

POSITION0 ?

Try that

I have, I get the same exact errors except instead of the error saying “Invalid input semantic ‘POSITION’”, it says 'Invalid input semantic ‘POSITION0’".

The “Legal indices are in [1, 15]” part is what led me to try using POSITION1, while that compiles in the content builder, it leads to a shader compilation error at runtime since it generates bad GLSL.

Doesn’t look like there’s anything wrong with it but I do notice you’re using input.Position which is reserved for the hardware and not normally used in the pixel-shader as far as I know(I’ve run into a problem like this before when I didn’t know) - it might even be what’s causing the issue.

To have a position you can use, you’d need to define a vertex-shader in there too to over-ride the default one and add a separate position entry in the struct (so a use-able one can be passed into the PS)
Something like this might be needed:

float4x4 MatrixTransform;
matrix World;

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

VertexShaderOutput MainVS(float4 position : SV_POSITION, float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
    VertexShaderOutput output;
    output.Position = mul(position, MatrixTransform);
    output.myPosition = mul(position, World);
    output.Color = color;
    output.TextureCoordinates = texCoord;
    return output;
}


float4 MainPS(VertexShaderOutput input) : COLOR
{
  float distance = length(light_pos - input.myPosition); // <--- now using myPosition
/// ETC...
}

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

Probably using identity matrix anyway for transforms - as long as “MatrixTransform” is in there, I believe spritebatch will pass to that, but you’ll proly need to SetParam for “World” (identity usually when using spritebatch)

[Edit: If it’s a post-processing effect (like lighting a finished rendertarget, you could also use the textureCoordinates as (0-1, 0-1) screen coordinates instead).]
[Edit: I realized too that if you use my example where myPosition is float3, you’d probably need light_pos to be float3 too (or use light_pos.xyz)]

1 Like

Thanks for the good answer. I made a new Effect that includes the vertex shader and adding a new output variable with the TEXCOORD1 semantic helped. My new conundrum is how do I use the position and texture from SpriteBatch.Draw(). I could obvious set those uniform values before every draw call but it would be great if I could use the values pass into Draw() directly.

I forgot. This is very important too(in case anyone forgets it):

fx = Content.Load<Effect>("testfx");
fx.Parameters["MatrixTransform"].SetValue(Matrix.CreateOrthographicOffCenter(
0, 1024, 768, 0, -2000.0f, 2000.0f));

You can just use the position accepted in the vertex shader and pass it directly as myPosition to the pixel shader (no need to multiply by “world” since it’s identity - unless you actually pass a modified world matrix to the Begin) - so, you’ll be using the interpolated position & texture coordinate submitted by Draw(). The texture coordinates will be in 0-1 space so if you needed to know the exact positions on the texture map, you could multiply by texture width & height to get the original coordinates (if needed).

thank you! you saved me from spending another hour to solve this weird error.
this error message is misleading and has nothing to do with the actual error.

1 Like