隣接するテクスチャのエッジを拾うスプライトシートテクスチャ


10

シンプルなスプライトシートを使用するカスタムスプライトルーチン(openGL 2.0)があります(テクスチャが横に並んでいます)。

したがって、たとえば、以下は2つの単純なテクスチャを持つテストスプライトシートです。

ここに画像の説明を入力してください

ここで、openGLスプライトオブジェクトを作成するときに行うことは、アトラス内のフレームの総数を指定し、描画するときに、描画するフレームを指定することです。

次に、テクスチャをどこから取得するかを決定します。

必要なフレーム数をフレームの総数で割る(左座標を取得するため)

次に、フレームの総数で1をダイビングし、その結果を上記で計算した左側の座標に追加します。

これは機能するようですが、時々問題が発生します。たとえば、以下のXを描画したいとします。

ここに画像の説明を入力してください

各テクスチャの間に1ピクセルの「パディング」を挿入することについて聞いたことがありますが、これがどのように機能するかを誰かが正確に説明できますか?つまり、これを行うと、テクスチャを取得するための計算が確実に破棄されます。

ピックアップしたテクスチャにパディングを単純に含めると(スプライトは空白の境界線で描画されます)、衝突の検出で問題が発生しますか?(つまり、透明部分が衝突するときに境界ボックスを使用すると、スプライトが衝突するように見えることがあります)。

誰かが説明していただければ幸いです。


あなたは、使用しているGL_NEARESTか、GL_LINEARテクスチャをレンダリングしますか?
MichaelHouse

私はGL_Linear @ Byte56を使用しています
BungleBonce

回答:


15

テクスチャアトラスと隣接するテクセルのリークの使用に関する問題は、線形テクスチャフィルタリングの動作に関係しています。

テクセルの中心で正確にサンプリングされていないテクスチャ内のポイントの場合、線形サンプリングは隣接する4つのテクセルをサンプリングし、指定された場所の値を(サンプルポイントからの距離に基づく)4つすべての加重平均として計算しますサンプル。

これは問題の素晴らしい視覚化です:

  

GL_CLAMP_TO_EDGEテクスチャアトラスのようなものは使用できないため、各テクスチャのエッジの周りに境界テクセルを作成する必要があります。これらの境界テクセルは、アトラス内の完全に異なるテクスチャからの隣接するサンプルが、上で説明した加重補間によって画像を変更するのを防ぎます。

異方性フィルタリングを使用する場合は、境界線の幅を大きくする必要があることに注意してください。これは、異方性フィルタリングにより、極端な角度でサンプル近傍のサイズが大きくなるためです。


各テクスチャのエッジの周りの境界線を使用して私が何を意味するかを説明するために、OpenGLで利用可能なさまざまなラップモードを検討してください。に特に注意してくださいCLAMP TO EDGE

  http://lucera-project.com/blog/wp-content/uploads/2010/06/wrap.png

「Clamp to Border」と呼ばれるモードがありますが、実際には興味がありません。このモードでは、正規化された[0.0の外側にあるすべてのテクスチャ座標のテクスチャの周囲の境界線として使用する単一の色を定義できます。 -1.0]範囲。

CLAMP_TO_EDGE(サブ)テクスチャの適切な範囲外のテクスチャ座標が境界外の方向にある最後のテクセル中心の値を受け取るの動作を複製する必要があります。ほぼ完全に制御できるので、アトラスシステムのテクスチャ座標。(有効な)テクスチャ座標がテクスチャの外側の場所を参照する唯一のシナリオは、テクスチャフィルタリングの加重平均ステップ中です。

GL_LINEAR上の図のように、4つの最近傍をサンプリングすることがわかっているため、1テクセルの境界線のみが必要です。異方性フィルタリングを使用する場合、特定の条件下でサンプルの近傍サイズが大きくなるため、より広いテクセル境界が必要になる場合があります。

以下は、境界線をより明確に示すテクスチャの例ですが、目的に合わせて境界線を1テクセルまたは2テクセルにすることもできます。

  

(注:私が参照している境界線は、画像の4つのエッジすべての周りの黒ではなく、チェッカーボードパターンが定期的に繰り返されなくなる領域です)

疑問に思っている方のために、異方性フィルタリングを繰り返し取り上げているのはこのためです。これは、角度に基づいてサンプル近傍の形状を変更し、4つ以上のテクセルをフィルタリングに使用する可能性があります。

  http://www.arcsynthesis.org/gltut/Texturing/ParallelogramDiag.svg

使用する異方性の度合いが大きいほど、4つ以上のテクセルを含むサンプルの近傍を処理する必要性が高まります。2テクセル境界は、ほとんどの異方性フィルタリングの状況に適しています。


最後に重要なことですが、ここではGL_CLAMP_TO_EDGEGL_LINEARテクスチャフィルターの存在下で動作を複製するパックテクスチャアトラスを作成する方法を示します。

黒い座標のXとYから1を減算します。投稿する前に画像の校正をしていません。   

境界ストレージのため、このアトラスに4つの256x256テクスチャを格納するには、サイズ516x516のテクスチャが必要です。境界線は、アトラスの作成中にテクセルデータで塗りつぶす方法に基づいて色分けされています。

  • 赤=すぐ下のテクセルで置き換える
  • 黄色=真上のテクセルで置き換える
  • 緑=すぐ左のテクセルで置き換える
  • 青=すぐ右のテクセルで置き換える

このパックされた例では効果的に、アトラスの各テクスチャはアトラスの258x258の領域を使用しますが、表示される256x256の領域にマップするテクスチャ座標を生成します。境界テクセルは、アトラスのテクスチャのエッジでテクスチャフィルタリングが行われる場合にのみ使用され、それらの設計方法はGL_CLAMP_TO_EDGE動作を模倣します。

不思議に思っている場合は、同様のアプローチを使用して他のタイプのラップモードをGL_REPEAT実装できます。テクスチャアトラスの左/右および上/下の境界テクセルを交換することで実装できます。シェーダー。これはもう少し複雑なので、今のところ心配する必要はありません。あなただけのスプライトシートを扱っているので、に自分自身を制限するGL_CLAMP_TO_EDGE:)


@AndonMColemanに感謝します。これがどのように機能するのかまだわからないので、図にボーダーを表示してもらえますか?これも、テクスチャがオブジェクトに適用されるときにボーダーが含まれることを意味しますか?私はこれを正しく理解していないよ場合は申し訳ありません- -私は、実際のテクスチャは、右私のクワッドのエッジに行きたいいくつかの詳細をいただければ幸いです-ありがとう
BungleBonce

@ user22241確かに、このボーダーは、テクスチャの端にあるテクセルを複製することで機能します。
Andon M. Coleman

@ user22241:いいえ、この境界線は通常の状況では表示されません。パックされたテクスチャは、テクスチャ座標計算と同じ次元を持つものとして扱います。オフセットを適用するだけで、境界を越えてスキップします。境界線の要点は、スプライトシート内の個別の画像に属するテクセルを線形テクスチャサンプリングが過度に到達してサンプリングするのを防ぐことです。ニアレストネイバーサンプリングを使用する場合、これは必要ありませんが、厄介なエイリアススプライトを取得します。
Andon M. Coleman

非常に詳細な回答-ありがとうございます!できれば最後に一つだけ。テクスチャ座標に追加する「オフセット」をどのように計算しますか?それは単に1 / widthOfTextureになるだろうと私は言っていますか?
BungleBonce 2013

@ user22241:はい、テクスチャ画像の開始は、X方向に+ 1 / widthOfTexture、Y方向に+ 1 / heightOfTextureになります。各テクスチャの周りを一周する境界線ができます。3番目の水平テクスチャのテクスチャ座標を計算するときには、このテクスチャのパック位置は実際には+5テクセルです(最初のテクスチャの境界は+2テクセル、2番目のテクスチャの境界は+2テクセル、最初は+1です)他の2つのテクスチャの幅に加えて、このテクスチャの)。それを書くだけでは複雑に見えます。必要に応じて、図を描くことができます:)
Andon M. Coleman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.