頂点シェーダーには、モデル座標での頂点の位置である gl_Vertex (固定パイプラインを使用しない場合は別のもの) があります。モデル マトリックスに gl_Vertex を掛けると、ワールド座標で頂点の位置が得られます。これを可変変数に割り当て、フラグメント シェーダーでその値を読み取ると、ワールド座標でのフラグメントの位置が得られます。
ここでの問題は、モデル マトリックスとビュー マトリックスの両方の組み合わせである OpenGL のデフォルトのモデル ビュー マトリックスを使用する場合、必ずしもモデル マトリックスを持っているとは限らないことです。私は通常、1 つのモデルビュー マトリックスではなく、2 つの別個のマトリックスを使用することで、この問題を解決します。
- モデル マトリックス (モデル座標をワールド座標にマッピング)、および
- ビュー マトリックス (ワールド座標をカメラ座標にマップします)。
したがって、2 つの異なるマトリックスを頂点シェーダーに別々に渡すだけです。定義することでこれを行うことができます
uniform mat4 view_matrix;
uniform mat4 model_matrix;
頂点シェーダーの先頭。そして、ftransform() の代わりに、次のように言います。
gl_Position = gl_ProjectionMatrix * view_matrix * model_matrix * gl_Vertex;
メイン プログラムでは、これらの新しい行列の両方に値を書き込む必要があります。まず、ビュー マトリックスを取得するには、glLoadIdentity()、glTranslate()、glRotate()、または gluLookAt() または通常どおりに好きなものを使用してカメラ変換を行いますが、glGetFloatv(GL_MODELVIEW_MATRIX, &array); を呼び出します。行列データを配列に取得するため。次に、同様の方法でモデル マトリックスを取得するには、glLoadIdentity(); も呼び出します。glTranslate()、glRotate()、glScale() などでオブジェクトの変換を行い、最後に glGetFloatv(GL_MODELVIEW_MATRIX, &array); を呼び出します。OpenGL から行列データを取得して、頂点シェーダーに送信できるようにします。特に、オブジェクトの変換を開始する前に glLoadIdentity() を呼び出す必要があることに注意してください。通常、最初にカメラを変換してからオブジェクトを変換すると、ビューとモデルの両方の機能を実行する 1 つのマトリックスになります。ただし、別のマトリックスを使用しているため、glLoadIdentity() でカメラを変換した後にマトリックスをリセットする必要があります。
gl_FragCoord はピクセル座標であり、ワールド座標ではありません。