# How to make other semantics behave like SV_Position?

I'm having a lot of trouble with shadow mapping, and I believe I've found the problem. When passing vectors from the vertex shader to the pixel shader, does the hardware automatically change any of the values based on the semantic?

I've compiled a barebones pair of shaders which should illustrate the problem.

struct Vertex {
float3 position : POSITION;
};

struct Pixel {
float4 position : SV_Position;
float4 light_position : POSITION;
};

cbuffer Matrices {
matrix projection;
};

Pixel output;
output.position = mul(float4(input.position, 1.0f), projection);
output.light_position = output.position;
// We simply pass the same vector in screenspace through different semantics.
return output;
}


And a simple pixel shader to go along with it:

struct Pixel {
float4 position : SV_Position;
float4 light_position : POSITION;
};

float4 RenderPixelShader(Pixel input) : SV_Target {
// At this point, (input.position.z / input.position.w) is a normal depth value.
// However, (input.light_position.z / input.light_position.w) is 0.999f or similar.
// If the primitive is touching the near plane, it very quickly goes to 0.

return (0.0f).rrrr;
}


How is it possible to make the hardware treat light_position in the same way which position is being treated between the vertex and pixel shaders?

This differrence is almost exclusive to the Z component, as the X and Y values of light_position are behaving as expected.

EDIT: Aha! (input.position.z) without dividing by W is the same as (input.light_position.z / input.light_position.w). Not sure why this is.

EDIT 2: Dividing (output.light_position) by (output.light_position.w) in the vertex shader causes really odd behavior, where (input.light_position.z / input.light_position.w) will be either 0 or 1 based on the camera's position and angle.

EDIT 3: Moving the projection multiplication into the pixel shader doesn't seem to make any difference. This means that the hardware is doing something to the SV_Position semantic which is critical to make it work.

EDIT 4: (input.light_position.z / input.light_position.w) IS behaving like depth, it's just that the precision seems to have decreased unbelievably. Only does it approach 0 once it's primitive literally intersects the near plane.

• could you add an image, and your pixelshader source code? And also dont forget that you have to divide your position thats no the System Semantic for position with it´s W component. the hardware does that for you on the system semantics. – Tordin Jun 4 '14 at 7:48
• Did you try to increase your near plane? That generally helps. – catflier Jun 4 '14 at 16:07
• You know, if you divide xyzw (instead of xyz) by w, it will not matter if the hardware divides by w again... because w will be 1.0. Not sure how relevant that is here, but that is one reason you should divide the enitre vector by w, not just the first 3-components. That said, w is usually assigned 1/w when the hardware does this division (clip-space -> NDC) so that you can reverse the transformation. – Andon M. Coleman Jun 5 '14 at 2:45
• Changed everything as I made a smaller program which narrowed down the problem. – object Jun 6 '14 at 15:35