2

テクスチャマップを使用してグリッド値を保持するOpenGLES流体シミュレーションに取り組んでいます。次のループを模倣するグリッドを反復処理する必要があります。

for (int r = 0; r < 128; r++)
   for (int c = 0; c < 128; c++)
      process grid element at (c,r)

グリッドを反復処理するために、四辺形を埋めるだけで、フラグメントプログラムがフラグメントごとに呼び出されます。テクスチャ座標(0,0)、(1,0)、(0,1)、(1,1)は、頂点(-1、-1)、(+ 1、-1)、(-1)に関連付けられています、+ 1)、(+ 1、+ 1)と、クワッドを(三角ストリップとして)FBOにアタッチされた128x128テクスチャマップに次のようにレンダリングします。

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, texFrameBuffer);
glViewport(0, 0, TEX_IMAGE_WIDTH, TEX_IMAGE_HEIGHT); // 128 x 128

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glEnableVertexAttribArray(positionAttr);
glVertexAttribPointer(positionAttr, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
glEnableVertexAttribArray(texCoordAttr);
glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, 0, 0);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

頂点シェーダーは、位置とテクスチャの座標を変更せずに通過させるだけです。どのテクスチャ座標が生成されているかを理解するために、テクスチャ座標を画像に取り込むことにしました。フラグメントプログラムは、指定された2Dテクスチャ座標を出力カラーの赤と緑のチャネルに割り当てます。

varying vec4 texCoord;
void main() {
  gl_FragColor = vec4(texCoord.st,0,1);
}

次にglGetTexImage()、テクスチャ画像をクライアントスペースに読み戻すために使用します。以下は、画像の各ピクセルに対して生成されたテクスチャ座標(s、t)のサンプルです。

(column, row) = [s, t] -> (128*s, 128*t)

(0,0) = [0.00392157, 0.00392157] -> (0,0)
(1,0) = [0.01176471, 0.00392157] -> (1,0)
(2,0) = [0.01960784, 0.00392157] -> (2,0)
(3,0) = [0.02745098, 0.00392157] -> (3,0)
(4,0) = [0.03529412, 0.00392157] -> (4,0)
(5,0) = [0.04313726, 0.00392157] -> (5,0)
(6,0) = [0.05098040, 0.00392157] -> (6,0)
(7,0) = [0.05882353, 0.00392157] -> (7,0)
(8,0) = [0.06666667, 0.00392157] -> (8,0)
(9,0) = [0.07450981, 0.00392157] -> (9,0)
(10,0) = [0.08235294, 0.00392157] -> (10,0)
<snip>
(125,0) = [0.98039222, 0.00392157] -> (125,0)
(126,0) = [0.98823535, 0.00392157] -> (126,0)
(127,0) = [0.99607849, 0.00392157] -> (127,0)
(0,1) = [0.00392157, 0.01176471] -> (0,1)
(1,1) = [0.01176471, 0.01176471] -> (1,1)
(2,1) = [0.01960784, 0.01176471] -> (2,1)
<snip>
(124,127) = [0.97254908, 0.99607849] -> (124,127)
(125,127) = [0.98039222, 0.99607849] -> (125,127)
(126,127) = [0.98823535, 0.99607849] -> (126,127)
(127,127) = [0.99607849, 0.99607849] -> (127,127)

さて、質問に移りましょう。私はこれらの生成された座標を理解しようとしています。魔法の値0.00392157(0.5 * 1/127.5)です。事前に加算された丸め値として機能する0.5の係数を理解していますが、なぜ127.5なのですか? (0.5 * 1/128.0)もっと意味がありますか?誰かがこれらの座標を説明できますか?テクスチャ座標から整数グリッド座標を生成したいだけです(sampler2Drect OpenGL ESではありません)。

4

1 に答える 1

3

私はいつもこれに苦労しているので、説明できるか見てみましょう。

グリッドの1行を想像してみてください。次の図では、その行の各フラグメント(0-127)に番号を付けています。ピクセルの下にもいくつかのテクスチャ座標を配置しました。左端が0.0で、右端が1.0であることに注意してください。

 +-----------+-----------+-----------+-----------+---    ---+-----------+
 |           |           |           |           |          |           |
 |           |           |           |           |          |           |
 |     0     |     1     |     2     |     3     |   . . .  |    127    |
 |           |           |           |           |          |           |
 |           |           |           |           |          |           |
 +-----------+-----------+-----------+-----------+---    ---+-----------+
 ^           ^           ^           ^                      ^           ^
 |           |           |           |                      |           |
 |           |           |           |                      |           |
0/128       1/128       2/128       3/128                127/128     128/128

レンダリングでフラグメントをテクスチャリングする場合は、フラグメントの中心のテクスチャ座標を使用します。ここで、番号はです。フラグメント0の中心が0/128(別名0)と1/128(別名.0078125)の中間にあることに注意してください。それは1/256(別名.00390625)です。

したがって、式は次のように表現した方がよいと思います。

coordinate = (pixelId + 0.5) / 128

これがあなたと同じような答えを得るPythonです:

for i in range(128):
   print (0.5 + i) / 128


0.00390625
0.01171875
0.01953125
0.02734375
0.03515625
0.04296875
...
0.97265625
0.98046875
0.98828125
0.99609375

私の結果とあなたの結果の違いは、あなたの値がシェーダーからそれらを返すために1つの[8ビット]カラーチャネルに絞り込まれたという事実と関係があるのではないかと思います。

これがお役に立てば幸いです。

于 2012-05-10T03:00:20.833 に答える