My pixel shader input is a follows
struct VertexShaderOut
{
float4 Position : POSITION0;
float2 TextureCoordinates : TEXCOORD0;
float4 PositionClone : TEXCOORD1; // Final position values must be cloned to be used in PS calculations
float3 Normal : TEXCOORD2;
//float3x3 TBN : TEXCOORD3;
float CullFace : VFACE; // A negative value faces backwards (-1), while a positive value (+1) faces the camera (requires ps_3_0)
};
I'm using ps_3_0 and I wish to utilise the VFACE semantic for correct lighting of normals depending on the cull mode.
If I add the VFACE semantic then I get the following errors:
error X5639: dcl usage+index: position,0 has already been specified for an output register error X4504: overlapping output semantics
Why would this occur? I can't see why there would be too much data.
EDIT:
Vertex Shader:
VertexShaderOut VertexShaderFunction(VertexShaderIn input)
{
VertexShaderOut Output = (VertexShaderOut)0;
// 'input.Position.w' should always equal 1
input.Position.w = 1;
// [Transformation]
// • Multiplying input.Position by World, then the result by ViewProjection is fast
// • Concatenating World and ViewProjection matrices then multiplying input.Position by the result is slower
input.Position = mul(input.Position, World);
Output.Position = mul(input.Position, ViewProjection);
// [Texel To Pixel Align]
// • Half pixel offset for correct texel centering)
// • Should be done AFTER transformation
Output.Position.xy -= HalfPixelTexel.xy;
// [Texel To Pixel Align]
// • Adjust uv coordinates so they use the correct texture from the texture atlas
Output.TextureCoordinates = input.TextureCoordinates;
// [Normal]
// • Use world transform with normals to avoid problems with different coordinate systems
Output.Normal = mul(float4(input.Normal.xyz, 0), World).xyz;
//Output.TBN[0] = normalize(mul(input.Tangent, (float3x3)WorldViewIT)); // X Axis
//Output.TBN[1] = normalize(mul(input.BiTangent, (float3x3)WorldViewIT)); // Y Axis
//Output.TBN[2] = normalize(mul(input.Normal, (float3x3)WorldViewIT)); // Z Axis
// [Position Clone]
// • POSITION0 values can't be used in the pixel shader so they must be passed in via another semantic
Output.PositionClone = Output.Position;
// [VFace]
//Output.CullFace = 0;
//Output.CullFace = sign(dot(ViewInv[3].xyz - Output.Position, Output.Normal));
return Output;
}
Pixel Shader:
PixelShaderOutput PixelShaderFunction(VertexShaderOut input)
{
PixelShaderOutput output = (PixelShaderOutput)0;
// [Scale Texture Coordinates] (Page 12 - Texture Atlas Paper)
// • To access all texels of a texture of dimensions 'width' by 'height' once and only once, models need to use:
// • u-coordinates in the range [.5 / width, 1 - (.5 / width)]
// • v-coordinates in the range [.5 / height, 1- (.5 / height)]
// • This prevents bleeding of textures (like wrapping) when using an atlas
// Scaling method - Works with both quadrangles and arbitrary geometry with original uv coordinates between 0 and 1
float s = (BackBufferDim - 1.0f) / BackBufferDim;
float o = 0.5f / BackBufferDim;
input.TextureCoordinates.xy *= s;
input.TextureCoordinates.xy += o;
// Wrap coordinates in [0, 1) range (for both tiling and scrolling)
// Use 'frac(texCoord) * n' to wrap in [0, n) range
float2 texCoords0 = frac(input.TextureCoordinates.xy); //* input.NumTiles.xy);
float2 texCoords1 = frac(input.TextureCoordinates.xy); //* input.NumTiles.zw);
// Adjust uv coordinates so they use the correct texture from the texture atlas
texCoords0 = CalculateAtlasUV(texCoords0, SourceRectangle0);
texCoords1 = CalculateAtlasUV(texCoords1, SourceRectangle1);
float4 colour0 = tex2D(TextureSampler, texCoords0);
float4 colour1 = tex2D(TextureSampler, texCoords1);
// [Linear Interpolation]
// • Based on colour1 alpha (therefore colour1 takes precedence over colour0)
// • output = lerp(A, B, C);
// • output = A * (1 - C) + B * C;
float4 colour = lerp(colour0, colour1, colour1.a);
// [Flash]
// • Interpolate between final colour and flash colour based on the flash timer value
colour = lerp(colour, float4(1, 1, 1, 1), FlashAmount);
// [Colour]
output.Color = colour;
// [Tangent/Normal]
// • Get value in the range of -1 to 1
//float3 n = 2.0f * tex2D(BumpMapSampler, input.TextureCoordinates) - 1.0f;
// Multiply by the tangent matrix
//n = mul(n, input.Tangent);
// Output normal
output.Tangent.xyz = normalize(input.Normal) * 0.5f + 0.5f;
//output.Tangent *= input.CullFace;
output.Tangent.w = 1;
// [Specular, Glow, Reflection]
// • Completely optional
//output.SGR.r = tex2D(SpecularSampler, input.TextureCoordinates);
//output.SGR.g = tex2D(GlowSampler, input.TextureCoordinates);
//output.SGR.b = tex2D(ReflectionMap, input.TextureCoordinates);
//output.SGR.w = 0;
// [Depth]
// • Flip to keep accuracy away from floating point issues
output.Depth.r = 1.0f - (input.PositionClone.z / input.PositionClone.w);
output.Depth.a = 1;
return output;
}