PDA

View Full Version : world to pixel size in vertex shader

sdrouin
02-13-2011, 10:38 AM
What is the most efficient way to compute, in a vertex shader, the screen size (in pixels) of sphere of radius 1 centered on the current vertex?

I need to apply a transform on vertices based on how big a sphere centered on each vertex projects on the screen.

s.

NeXEkho
02-13-2011, 12:37 PM
I *think* it'd be 1.0/the vertex's position's W component but I'm not sure.

Dark Photon
02-13-2011, 06:13 PM
What is the most efficient way to compute, in a vertex shader, the screen size (in pixels) of sphere of radius 1 centered on the current vertex?

Presumably you mean for a perspective projection, as this is almost a non-problem in orthographic.

The general solution is complicated by the fact that the angle subtended by each pixel decreases as you move away from the eye-space -Z axis, and further that if the sphere is close enough to the eyepoint, you can't even see a full diameter of the sphere (because your view is blocked by closer portions of the sphere).

But if you can assume the sphere isn't very close to the eyepoint, and you just want an approximation for when the sphere is directly in front of you in eye-space (i.e. its center is on the eye-space -Z axis) then...

...you can easily see with a quick picture that the sphere's size on the near clip plane is n/d, where n = near clip plane distance and d = -sphere_center_eye.z (sphere_center_eye is the sphere's center in eye-space).

Divide that (n/d) by the width of the screen in eye-space (r-l) and multiply by the resolution, and you have this approximation in pixels.

If you need a better answer based on where the sphere is on the screen, you can always take the eye-space vertex position, displace it left and right in eye-space by a half-unit perpendicular to a vector to the eye, project those points through clip space to NDC space, subtract them, and then map to pixel units.

I *think* it'd be 1.0/the vertex's position's W component but I'm not sure.

No. The vertex's clip-space W component (pos_clip.w) is just -pos_eye.z, so the reciprocal doesn't get you even the projected width of the sphere on the screen in eye-space, unless the near clip value == 1. Even then you still need to convert from eye-space units to pixel-space units.

NeXEkho
02-13-2011, 06:36 PM
That is a good point, I can't believe I just said that now I've had some sleep :p