27

世界のどの xyz 位置に応じて色を調整したいのですか。

フラグメントシェーダーでこれを試しました:

varying vec4 verpos;

void main(){
    vec4 c;
    c.x = verpos.x;
    c.y = verpos.y;
    c.z = verpos.z;
    c.w = 1.0;

    gl_FragColor = c;
}

カメラの角度/位置によって色が変わるようですが、カメラの位置/角度から座標を独立させるにはどうすればよいですか?

これが私の頂点シェーダーです。

varying vec4 verpos;

void main(){
    gl_Position = ftransform();
    verpos = gl_ModelViewMatrix*gl_Vertex;
}

Edit2:タイトルを変更したので、画面座標ではなく、世界座標が必要です!

Edit3:完全なコードを追加しました

4

4 に答える 4

33

頂点シェーダーには、モデル座標での頂点の位置である gl_Vertex (固定パイプラインを使用しない場合は別のもの) があります。モデル マトリックスに gl_Vertex を掛けると、ワールド座標で頂点の位置が得られます。これを可変変数に割り当て、フラグメント シェーダーでその値を読み取ると、ワールド座標でのフラグメントの位置が得られます。

ここでの問題は、モデル マトリックスとビュー マトリックスの両方の組み合わせである OpenGL のデフォルトのモデル ビュー マトリックスを使用する場合、必ずしもモデル マトリックスを持っているとは限らないことです。私は通常、1 つのモデルビュー マトリックスではなく、2 つの別個のマトリックスを使用することで、この問題を解決します。

  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 はピクセル座標であり、ワールド座標ではありません。

于 2011-02-04T15:18:54.957 に答える
13

または、z 座標を w 座標で除算することもできます。これにより、基本的に透視投影が取り消されます。あなたの元の世界座標を与えます。

すなわち。

depth = gl_FragCoord.z / gl_FragCoord.w;

もちろん、これはクリップされていない座標に対してのみ機能します..

しかし、とにかくクリップされたものを誰が気にしますか?

于 2012-02-16T23:36:05.463 に答える
-1

最も簡単な方法は、可変変数を介して頂点シェーダーからワールド位置を渡すことです。

ただし、本当に から再構築する必要がある場合、gl_FragCoordこれを行う唯一の方法は、gl_FragCoord 座標に至るすべてのステップを逆にすることです。本当にこれを行う必要がある場合は、OpenGL の仕様を参照してください。変換についての深い理解が必要になるためです。

于 2011-02-04T15:19:51.820 に答える