2017-06-10 7 views
0

私は理解できない動作をしているOpenGLアプリケーションを持っています。アプリケーションは、バックグラウンド上の直方体からなり、直方体は、以下のコードを使用して、それが画面に表示されている場所に応じて網掛けされている:OpenGLデバイスのシェーダ座標が変わっています

頂点シェーダ:

#version 450 core 

//In from VBO 
in vec3 position; 
in vec2 uv; 
in vec3 normal; 

//Out to Fragment Shader 
out vec4 screenPos; 
out vec4 fragPosition; 
out vec2 fragUV; 
out vec3 fragNormal; 

//3D Uniforms 
uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    //Screen translation 
    vec4 vertex = model * vec4(position, 1.0); 

    gl_Position = projection * view * vertex; 
    screenPos = projection * view * vertex; 

    //Out to Fragment Shader 
    fragPosition = vertex; 
    fragUV = uv; 
    fragNormal = normal; 
} 

フラグメントシェーダ:

#version 450 core 

//From Vertex Shader 
in vec4 screenPos; 
in vec4 fragPosition; 
in vec2 fragUV; 
in vec3 fragNormal; 

//To Target 
out vec4 fragmentColor; 

void main() 
{ 
    fragmentColor = vec4(screenPos.x, screenPos.y, 0.0, 1.0); 
} 

これを実行すると、明らかにという結果が得られます。画面位置はですが、以下のように予想通りに動作しません。 (目的のオブジェクトは、フォアグラウンドの緑色/赤色/黒色の直方体です。背景は期待どおりに動作しています)。

The problem

ことだとして暗い光を満たしている場所は、画面の中心にすべきことであるが、ここで正に否定(NO色)からの移行(両方の車軸に-1と1の間にある)装置座標(緑色および/または赤色)。しかしそれはそうではなく、スクリーンの中心からかなり離れていて、垂直/水平でなければならない負と正の間の線は見えません。何が起こっている?

答えて

2

何が起こっているのは、正規化されたデバイス座標を提供していないということです。あなたはクリップスペース座標を提供しました。 NDCスペースを取得するには、divide the XYZ components of clip-space by the clip-space Wが必要です。

ただし、フラグメントの位置を変更したい場合は、gl_FragCoord in the fragment shaderを使用する方がはるかに簡単です。正規化されていませんが、the viewport valuesを指定するユニフォームを提供することで、簡単に正規化できます。次に、数学演算をいくつか行い、正規化しますgl_FragCoord

uniform vec2 viewportOffset; 
uniform vec2 viewportSize; 

vec2 NormalizePosition() 
{ 
    vec2 temp = gl_FragCoord.xy - viewportOffset - (viewportSize/2); 
    return temp * (2/viewportSize); 
} 
関連する問題