3
votes

I'm attempting to write a phong shader effect for Dx9 in RenderMonkey.

I'm getting a compile error in the pixel shader

*"invalid ps_2_0 input semantic 'POSITION0'"*

and I'm not sure how to fix it, although I know it's got to be something to do with the POSITION0 semantic in VS_OUTPUT.

I tried changing VS_OUTPUT's Pos semantic to TEXCOORD0, but then the system reports that

vertex shader must minimally write all four components of POSITION

Shaders are supplied below. Any suggestions?

Here's my vertex shader:

struct VS_INPUT 
{
   float4 Pos : POSITION0;
   float3 Normal : NORMAL0;
};

struct VS_OUTPUT 
{
   float4 Pos : POSITION0;
   float3 Normal : TEXCOORD0;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;

   Output.Pos     = Input.Pos;
   Output.Normal  = Input.Normal;

   return Output;  
}

and my pixel shader:

    float4x4 matViewProjection;

// light source
float4 lightPos;
float4 Ambient;
float4 Diffuse;
float4 Specular;

// material reflection properties
float4 Ke;
float4 Ka;
float4 Kd;
float4 Ks;
float  nSpecular;

// eye
float4 eyePosition;

struct VS_OUTPUT 
{
   float4 Pos : POSITION0;
   float3 Normal : TEXCOORD0;
};

float4 ps_main( VS_OUTPUT vsOutput ) : COLOR0
{   
   vsOutput.Pos = mul( vsOutput.Pos, matViewProjection );


   float3 ViewDirection = normalize( eyePosition.xyz - vsOutput.Pos.xyz );
   float3 LightDirection = normalize( lightPos.xyz - vsOutput.Pos.xyz );

   float3 N = normalize( vsOutput.Normal );
   float3 R = reflect( -LightDirection, N );

   float LdotN = max( 0.0, dot( LightDirection, N ) );
   float VdotR = max( 0.0, dot( ViewDirection, R ) );

   // find colour components
   float4 a = Ka * Ambient;
   float4 d = Kd * Diffuse * LdotN;
   float4 s = Ks * Specular * pow( VdotR, nSpecular );

   float4 FragColour = Ke + a + d + s;
   return FragColour;
}
2

2 Answers

5
votes

Okay, I found a solution for those interested.

The Vertex Shader should have the following structs defined:

struct VS_INPUT 
{
   float4 Pos : POSITION0;
   float3 Normal : NORMAL0;
};

struct VS_OUTPUT 
{
   float4 Pos : POSITION0;
   float4 PosOut : TEXCOORD0;
   float3 Normal : TEXCOORD1;
};

The VS_OUTPUT struct should be different in the pixel shader:

struct VS_OUTPUT 
{
   float4 PosOut : TEXCOORD0;
   float3 Normal : TEXCOORD1;
};

My problem stemmed from the fact that you can't have a POSITION semantic as input to the pixel shader. At least for ps_2_0.

1
votes

As user, one is not allowed to use the value of POSITION0 of the VertexShaderOutput in the PixelShaderFunction. This attribute seems to be cut off at some point between Vertex and Pixel Shader.

Instead you need to declare another attribute in the VertexshaderOutput, e.g.,

float4 newPosition : TEXCOORD1;

which you assign the same value as POSITION0. This new attribute, you may use ist in the PixelShaderfunction.