12

スプライト シートとして使用したいテクスチャ (この場合は 8x8 ピクセル) があるとします。サブイメージ (スプライト) の 1 つは、次のイメージのように、テクスチャ内の 4x3 のサブ領域です。

ここに画像の説明を入力

(四隅の正規化されたテクスチャ座標が表示されます)

テクスチャ座標を 4px x 3px サイズのクワッドに割り当てて、効果的に探しているスプライトにする方法は基本的に 2 つあります。最初の最も簡単な方法は、サブ領域の角でテクスチャをサンプリングすることです。

ここに画像の説明を入力

// Texture coordinates

GLfloat sMin = (xIndex0                  ) / imageWidth;
GLfloat sMax = (xIndex0 + subregionWidth ) / imageWidth;
GLfloat tMin = (yIndex0                  ) / imageHeight;
GLfloat tMax = (yIndex0 + subregionHeight) / imageHeight;

この方法を最初に実装したときは、ca. 2010 年に、スプライトがわずかに「歪んでいる」ように見えることに気付きました。少し検索した後、cocos2d フォーラムで、スプライトをレンダリングするときにテクスチャをサンプリングする「正しい方法」は次のとおりであると説明している投稿を見つけました。

ここに画像の説明を入力

// Texture coordinates

GLfloat sMin = (xIndex0                   + 0.5) / imageWidth;
GLfloat sMax = (xIndex0 + subregionWidth  - 0.5) / imageWidth;
GLfloat tMin = (yIndex0                   + 0.5) / imageHeight;
GLfloat tMax = (yIndex0 + subregionHeight - 0.5) / imageHeight;

...そしてコードを修正した後、しばらくは幸せでした。しかし、途中のどこかで、おそらく iOS 5 が導入された頃だと思いますが、自分のスプライトが見栄えがよくないと感じ始めました。いくつかのテストの後、「青」の方法 (2 番目の画像) に戻しまし

私は夢中になっているのでしょうか、それとも GL ES テクスチャ マッピングに関連して iOS 5 で何かが変わったのでしょうか? おそらく私は何か他のことを間違っていますか?(例えば、頂点の位置座標が微妙にずれている?テクスチャの設定パラメータが間違っている?)でも、コードベースは変わらないので、最初から何か間違っているのでしょうか...?

つまり、少なくとも私のコードでは、以前は「赤」の方法が正しかったように感じますが、現在は「青」の方法の方が良い結果が得られます。

今のところ、私のゲームは問題ないように見えますが、遅かれ早かれ修正しなければならない何かが半分間違っていると感じています...

アイデア/経験/意見はありますか?

補遺

上記のスプライトをレンダリングするには、次のように、正投影で 4x3 の四角形を描画します。各頂点には、前述のコードで暗示されたテクスチャ座標が割り当てられます。

// Top-Left Vertex
{ sMin, tMin };

// Bottom-Left Vertex
{ sMin, tMax };

// Top-Right Vertex
{ sMax, tMin };

// Bottom-right Vertex
{ sMax, tMax };

元のクワッドは (-0.5, -0.5) から (+0.5, +0.5) まで作成されます。つまり、画面の中心にある単位正方形であり、サブ領域のサイズ (この場合は 4x3) にスケーリングされ、その中心は整数 (x,y) 座標に配置されます。特に幅、高さ、またはその両方が偶数でない場合、これにも何か関係があるにおいがしますか?

補遺2

この記事も見つけましたが、まだまとめようとしています (ここは午前 4 時です) http://www.mindcontrol.org/~hplus/graphics/opengl-pixel-perfect.html

4

1 に答える 1

10

この図には見た目以上のものがあります。テクスチャ座標は、テクスチャがサンプリングされる唯一の要因ではありません。あなたの場合、おそらく青が欲しいものだと思います。

最終的に必要なのは、各テクセルを中央でサンプリングすることです。2 つのテクセル間の境界でサンプルを取得することは望ましくありません。これは、浮動小数点計算の丸め方に応じて、それらを線形サンプリングと組み合わせるか、 nearestで一方または他方を任意に選択するためです。

そうは言っても、テクスチャ座標を (0,0)、(1,1) およびその他のコーナーに配置したくないと思うかもしれません。それらはテクセル境界上にあるからです。ただし、opengl はフラグメントの中央でテクスチャをサンプリングすることに注意してください。

非常に単純な例として、2 x 2 ピクセルのテクスチャを持つ 2 x 2 ピクセルのモニターを考えてみましょう。

(0,0) から (2,2) までのクワッドを描画すると、4 ピクセルがカバーされます。このクワッドをテクスチャ マップする場合、テクスチャから 4 つのサンプルを取得する必要があります。

テクスチャ座標が 0 から 1 になる場合、opengl はこれを補間し、各ピクセルの中心からサンプリングします。左下の texcoord は、左下のピクセルの左下隅から始まります。これにより、最終的に (0.25, 0.25)、(0.75,0.75)、(0.25, 0.75)、および (0.75, 0.25) の texcoord ペアが生成されます。これにより、サンプルが各テクセルの真ん中に配置されます。これが必要です。

赤の例のように texcoords を 0.5 ピクセル オフセットすると、正しく補間されず、テクセルの中心から離れたテクスチャをサンプリングすることになります。

簡単に言うと、ピクセルがテクセルと正しく整列するようにし (整数以外のピクセル位置にスプライトを描画しないでください)、スプライトを任意の量だけスケーリングしないようにする必要があります。

青い四角が悪い結果をもたらしている場合、画像の例を挙げたり、どのように描いているかを説明したりできますか?

写真は1000語を言います:

画像

于 2012-07-12T18:14:44.383 に答える