3
votes

i have a 640x480 rendertarget (its the main backbuffer).

im passing a fullscreen quad to the vertex shader, the fullscreen quad has coordinates between [-1,1] for both X and Y, that means that i only pass the coordinates into the pixel shader with no calculation:

struct VSInput
{
    float4 Position : SV_POSITION0;
};

struct VSOutput
{
    float4 Position : SV_POSITION0;
};

VSOutput VS(VSInput input)
{
    VSOutput output = (VSOutput)0;
    output.Position = input.Position;
    return output;
}

but on the pixel shader, the x and y coordinate for each fragment is in screen space (0 < x < 640 and 0 < y < 480). why is that? i always thought that the coordinates would get interpolated on their way to the pixel shader and be set between -1,1 and in this case even more so because I'm passing the coordinates between -1 and 1 hardcoded on the vertex shader!

but truth is, this pixel shader works:

float x = input.Position.x;

if(x < 200)
    output.Diffuse = float4(1.0, 0.0, 0.0, 1.0);
else if( x > 400)
    output.Diffuse = float4(0.0, 0.0, 1.0, 1.0);
else
    output.Diffuse = float4(0.0, 1.0, 0.0, 1.0);

return output;

it outputs 3 color stripes on my rendering window, but if i change the values from screen space (the 200 and 400 from the code above) to -1,1 space and use something like if(x < 0.5) it wont work.

i already tried

float x = input.Position.x / input.Position.w;

because i read somewhere that that way i could get values between -1,1 but it doesn't work either.

thanks in advance.

1

1 Answers

4
votes

From the MSDN on the Semantics-page about SV_POSITION:

When used in a pixel shader, SV_Position describes the pixel location.

So you are seeing expected behavior.

The best solution is to pass screen space coordinates as an additional parameter. I like to use this "full-screen-triangle" vertex shader:

struct VSQuadOut {
    float4 position : SV_Position;
    float2 uv: TexCoord;
};

// outputs a full screen triangle with screen-space coordinates
// input: three empty vertices
VSQuadOut VSQuad( uint vertexID : SV_VertexID ){
    VSQuadOut result;
    result.uv = float2((vertexID << 1) & 2, vertexID & 2);
    result.position = float4(result.uv * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
    return result;
}

(Original source: Full screen quad without vertex buffer?)