2012-06-07 53 views
3

我想计算一个像素投影金字塔在glsl顶点着色器中当前顶点位置处的眼睛空间宽度,但我似乎无法得到正确的数学。这是一个明显不正确的例子:GLSL顶点着色器中的眼睛空间像素宽度

// 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> 

但是这并没有考虑FOV或剪切平面。

回答

1

我完成了数学计算。 :)至于我曾希望有不需要额外的矩阵变换,只是一个鸿沟:

// 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> 

或者:

<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> 

正如预期的那样,pixelWidthpixelHeight是,如果像素是正方形相同。

0

顶点着色器中,没有像像素的世界空间宽度那样的东西。 “宽度”仅在给定的Z距离处投影到像素中。一般来说,你有一个金字塔投影到一个像素。

在这里你去:

  1. 转换的两画面,点到NDC点:

    vec2 Screen = vec2(ScreenWidth, ScreenHeight); 
        vec3 Point1 = vec3(ScreenPt1/Screen * 2.0 - vec2(1.0), 1.0); 
        vec3 Point2 = vec3(ScreenPt2/Screen * 2.0 - vec2(1.0), 1.0); 
    
  2. Unproject NDC点到世界空间中的位置:

    vec4 R1 = vec4(Point1, 1.0); 
        vec4 R2 = vec4(Point2, 1.0); 
    
        R1 = Projection.GetInversed() * R1; 
        R1 = ModelView.GetInversed() * R1; 
        R1 /= R1.W; 
    
        R2 = Projection.GetInversed() * R2; 
        R2 = ModelView.GetInversed() * R2; 
        R2 /= R2.W; 
    
  3. 查找R1和R2之间的距离。

片段着色器你可以使用本地的衍生物。看看这里:

http://www.opengl.org/sdk/docs/manglsl/xhtml/dFdx.xml

和这里:

http://www.opengl.org/sdk/docs/manglsl/xhtml/fwidth.xml

仅可在片段着色器,dFdx和dFdy分别返回表达式p的偏导数在x和y。偏差是使用局部差分来计算的。像dFdx(dFdx(n))这样的混合阶导数,含有高阶导数的表达式如dFdx(dFdx(n))具有未定义的结果。假定表达式p是连续的,因此,通过非均匀控制流评估的表达式可能是不确定的。

+1

这些函数仅在片段着色器中可用,我在询问顶点着色器,所以这对我没有帮助。 – atb

+1

查看我更新的答案。 –

+0

好的,使用你的语义我需要在顶点着色器当前顶点z深度处的“像素金字塔”的世界空间宽度。你的答案仍然不能帮助我,但感谢您的信息。 – atb