35

私は GLSL のシェーダーについて頭を悩ませようとしています。いくつかの有用なリソースとチュートリアルを見つけましたが、基本的で些細であるべき何かの壁にぶつかり続けています。現在のフラグメント?

と言って最終的な色を設定しますgl_FragColor = whateverが、どうやらそれは出力専用の値です。計算を実行できるように、入力の元の色をどのように取得しますか? それはどこかの変数にある必要がありますが、その名前を知っている人がいるとしたら、これまでに出くわしたチュートリアルやドキュメントに記録されていないようで、私を壁に追いやっています.

4

7 に答える 7

16

フラグメント シェーダは頂点属性としてgl_Colorとを受け取ります。また、値を書き込むことができる、、、 のgl_SecondaryColor4 つの可変変数も取得します。元の色をそのまま渡したい場合は、次のようにします。gl_FrontColorgl_FrontSecondaryColorgl_BackColorgl_BackSecondaryColor

gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = gl_SecondaryColor;
gl_BackColor = gl_Color;
gl_BackSecondaryColor = gl_SecondaryColor;

頂点シェーダーに続くパイプラインの固定機能は、これらを [0..1] の範囲にクランプし、頂点が前面か背面かを判断します。次に、通常どおり、選択した (前面または背面) 色を補間します。gl_Colorフラグメント シェーダーは、選択され、クランプされ、補間された色をおよびとして受け取りますgl_SecondaryColor

たとえば、次のような標準的な「死の三角形」を描いた場合:

glBegin(GL_TRIANGLES);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(-1.0f, 0.0f, -1.0f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(1.0f, 0.0f, -1.0f);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3d(0.0, -1.0, -1.0);
glEnd();

次に、次のような頂点シェーダー:

void main(void) {
    gl_Position = ftransform();
    gl_FrontColor = gl_Color;
}

次のようなフラグメント シェーダを使用します。

void main() {
    gl_FragColor = gl_Color;
}

固定機能パイプラインを使用している場合と同様に、色を送信します。

于 2010-04-29T23:34:25.740 に答える
14

マルチパス レンダリングを実行する場合、つまり、フレーム バッファにレンダリングした後、前のレンダリングを使用する 2 番目のレンダリング パスを実行する場合の答えは次のとおりです。

  1. 最初のパスをテクスチャにレンダリングする
  2. このテクスチャを 2 番目のパスにバインドします
  3. シェーダーで事前にレンダリングされたピクセルにアクセスする

3.2 のシェーダー コード:

uniform sampler2D mytex; // texture with the previous render pass

layout(pixel_center_integer) in vec4 gl_FragCoord;
// will give the screen position of the current fragment

void main()
{
  // convert fragment position to integers
  ivec2 screenpos = ivec2(gl_FragCoord.xy);
  // look up result from previous render pass in the texture
  vec4 color = texelFetch(mytex, screenpos, 0);
  // now use the value from the previous render pass ...
}

レンダリングされたイメージを処理する別の方法は、 OpenGL を使用したOpenCL -> OpenCL 相互運用です。これにより、より多くの CPU のような計算が可能になります。

于 2010-04-30T10:47:37.943 に答える
8

「フラグメントの現在の値」と呼ばれるものが、フラグメント シェーダーが実行される前にレンダー ターゲットにあったピクセルの色の値である場合、いいえ、それは利用できません。

その主な理由は、フラグメント シェーダーが実行された時点ではまだ不明である可能性があるためです。フラグメント シェーダーは並行して実行され、(ハードウェアによっては) 同じピクセルに影響を与える可能性があり、通常、何らかの FIFO から読み取る別のブロックが、後でそれらをマージする役割を果たします。そのマージは「ブレンディング」と呼ばれ、まだプログラム可能なパイプラインの一部ではありません。これは機能が固定されていますが、フラグメント シェーダーが生成したものとピクセルの以前のカラー値を組み合わせるさまざまな方法があります。

于 2010-04-30T08:15:51.077 に答える
4

このような現在のピクセル座標でテクスチャをサンプリングする必要があります

vec4 pixel_color = texture2D(tex, gl_TexCoord[0].xy);

注 - 私が見たように、texture2D は GLSL 4.00 仕様で非推奨になっています - 同様のテクスチャを探してください... フェッチ関数。

また、gl_TexCoord[0].xy の代わりに独自のピクセル座標を指定する方がよい場合もあります。その場合は、頂点シェーダーを次のように記述します。

vec2 texCoord を変化させます。

ボイドメイン(ボイド)
{
   gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0 );
   texCoord = 0.5 * gl_Position.xy + vec2(0.5);     
}

フラグメント シェーダーでは、gl_TexCoord[0].xy の代わりにその texCoord 変数を使用します。

幸運を。

于 2010-09-01T09:04:06.803 に答える
3

フラグメント シェーダーの要点は、出力カラーを決定することです。それをどのように行うかは、何をしようとしているのかによって異なります。

頂点シェーダーの出力に基づいて補間された色を取得するように設定することもできますが、より一般的な方法は、頂点シェーダー補間から渡されたテクスチャ座標を使用して、フラグメント シェーダーでテクスチャ ルックアップを実行することです。 . 次に、選択したライティングの計算と、シェーダーが行うその他の目的に従って、テクスチャ ルックアップの結果を変更し、それを gl_FragColor に書き込みます。

于 2010-04-30T01:06:33.127 に答える
-3

フラグメントの現在の色を取得する方法

できないと言う人もいますが、私はこれがうまくいくと言います:

//Toggle blending in one sense, while always disabling it in the other.   
void enableColorPassing(BOOL enable) {
 //This will toggle blending - and what gl_FragColor is set to upon shader execution
   enable ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
   //Tells gl - "When blending, change nothing" 
   glBlendFunc(GL_ONE, GL_ZERO); 
}

その呼び出しの後、gl_FragColor は、シェーダーが各ピクセルで初めて実行されるときにカラー バッファーのクリア カラーに等しくなり、実行ごとの出力は、連続する実行ごとに新しい入力になります。

まあ、少なくとも私にとってはうまくいきます。

于 2012-11-09T04:55:24.093 に答える