Screen Space Shader

I’m trying to generate screen space UV coordinates in a fragment shader and I can’t quite seem to get it to turn out right.

I’ve used a snipet that I found on the forums and it’s pretty close:

float4 clipSpace = mul(UNITY_MATRIX_MVP, v.vertex);
clipSpace.xy /= clipSpace.w;
clipSpace.xy = 0.5 * clipSpace.xy + 0.5;
o.uv2 = clipSpace.xy;

However objects with many faces it always seems to be a little bit off. I know this must be possible since this code in a surface shader works fine:

void surf(Input i, inout SurfaceOutput o)
{
    float2 screenUV = i.screenPos.xy / i.screenPos.w;
    ...

However I would rather not use a surface shader, I just want to know how the surface shader is calculating its screenPos variable and what I’m doing wrong.

The top image is the x coordinate of the screen space UV’s generated by a surface shader. Notice that the gradient is nice and smooth unlike the bottom image which is generated by my fragment shader.

Thanks for your help!

In case anyone stumbles across this I figured it out:

	v2f vert(appdata_full v)
	{
		o.scrPos = ComputeScreenPos(o.pos);

	fixed4 frag(v2f i) : COLOR
	{
		float2 uv2 = (i.scrPos.xy/i.scrPos.w);

I guess it doesn’t work to do all the calculations per vert, some have to be done per pixel.