I want to compute the eye-space width of a pixel's projected pyramid at the current vertex location in a glsl vertex shader, but I can't seem to get the math right. Here is an obviously incorrect example:
// GLSL VERTEX SHADER
#version 410 compatibility
uniform vec4 viewport; // same as glViewport
in vec4 gl_Vertex;
void main ()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
float pixelWidth = gl_Position.z / viewport.z;
<snip>
But this does not account for the FOV or clipping planes.
I worked through the math and figured it out. :) As I had hoped there are no additional matrix transformations required, just one divide:
// GLSL VERTEX SHADER
#version 410 compatibility
uniform vec4 viewport; // same as glViewport
in vec4 gl_Vertex;
float pixelWidthRatio = 2. / (viewport.z * gl_ProjectionMatrix[0][0]);
void main ()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
float pixelWidth = gl_Position.w * pixelWidthRatio;
<snip>
Or alternatively:
<snip>
float pixelHeightRatio = 2. / (viewport.w * gl_ProjectionMatrix[1][1]);
void main ()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
float pixelHeight = gl_Position.w * pixelHeightRatio;
<snip>
As expected, pixelWidth
and pixelHeight
are the same if the pixels are square.