3

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またはクリッピングプレーンを考慮していません。

4

2 に答える 2

2

私は数学を通してそれを理解しました。:) 私が望んでいたように、追加の行列変換は必要ありません。分割は 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>

予想どおり、pixelWidthピクセルpixelHeightが正方形の場合は同じです。

于 2012-06-11T14:26:45.527 に答える
1

頂点シェーダーには、ピクセルのワールドスペース幅などはありません。「幅」は、指定されたZ距離でのみピクセルに投影されます。一般に、ピラミッドはピクセルに投影されます。

どうぞ:

  1. 2つのスクリーンポイントを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. 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は、それぞれxとyの式pの偏導関数を返します。偏差は、ローカル差分を使用して計算されます。dFdx(dFdx(n))などの高階導関数を暗示する式は、dFdx(dFdy(n))などの混合次導関数と同様に、未定義の結果をもたらします。式pは連続的であると想定されているため、不均一な制御フローを介して評価された式は未定義である可能性があります。

于 2012-06-07T18:34:33.850 に答える