世界での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:完全なコードを追加
頂点シェーダーには、モデル座標での頂点の位置であるgl_Vertex(または固定パイプラインを使用しない場合は何か)があります。モデル行列にgl_Vertexを乗算すると、ワールド座標での頂点の位置が得られます。これをvarying変数に割り当て、その値をフラグメントシェーダーで読み取ると、フラグメントの位置が世界座標で取得されます。
ここでの問題は、モデルとビューマトリックスの両方の組み合わせである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はピクセル座標であり、世界座標ではありません。
または、z座標をw座標で除算することもできます。これにより、透視投影が本質的に行われなくなります。あなたにあなたの元の世界座標を与えます。
すなわち。
depth = gl_FragCoord.z / gl_FragCoord.w;
もちろん、これはクリップされていない座標に対してのみ機能します。
しかし、とにかくクリップされたものを気にする人はいますか?
ワールド/モデルマトリックスをユニフォームとして頂点シェーダーに渡し、それを頂点位置で乗算して、変動としてフラグメントシェーダーに送信する必要があります。
/*Vertex Shader*/
layout (location = 0) in vec3 Position
uniform mat4 World;
uniform mat4 WVP;
//World FragPos
out vec4 FragPos;
void main()
{
FragPos = World * vec4(Position, 1.0);
gl_Position = WVP * vec4(Position, 1.0);
}
/*Fragment Shader*/
layout (location = 0) out vec4 Color;
...
in vec4 FragPos
void main()
{
Color = FragPos;
}