Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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;
}
share|improve this question

1 Answer 1

up vote 1 down vote accepted

Hmm, ordinarily the POSITION0 is not part of the pixel shader input struct, nor VFACE part of the vertex shader output. Try removing those from the struct and adding them as a separate output parameter from the vertex shader, and input parameter to the pixel shader. It's a little weird, but perhaps internally, VFACE uses the same register as POSITION0 (which would be possible because the former is only for pixel shaders and the latter only for vertex shaders).

That is, your shader prototypes might look something like:

struct VertexShaderOut
{
    float2 TextureCoordinates       : TEXCOORD0;
    float4 PositionClone            : TEXCOORD1;
    float3 Normal                   : TEXCOORD2;
    //float3x3 TBN                  : TEXCOORD3;
};

void VertexShaderFunction(
        VertexShaderIn input,
        VertexShaderOut output,
        float4 outPos : POSITION0)
{
    // ...code...
}

void PixelShaderFunction(
        VertexShaderOut input,
        float CullFace : VFACE)
{
    // ...code...
}
share|improve this answer
    
If I do that the I get: error X4541: vertex shader must minimally write all four components of POSITION. I'll add the original .fx file I am currently using. –  user1423893 Jul 10 '12 at 19:38
    
@user1423893 I forgot to mention, VFACE should be a separate input parameter for the pixel shader, as well. –  Nathan Reed Jul 10 '12 at 20:46
    
It fixed the problem by using a separate input parameter for the VFACE semantic. Thank you. –  user1423893 Jul 10 '12 at 21:28
    
@user1423893 Glad to hear it! Don't forget to click the check-mark button next to the answer to mark it as "accepted", for other users. –  Nathan Reed Jul 10 '12 at 22:14
    
Can't see the check mark. Maybe I'm not looking hard enough or Chrome is not displaying it? I clicked around the page and voted the answer up though. –  user1423893 Jul 10 '12 at 23:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.