2 / 4 補間されたUVの可視化
頂点の間の値をGPUが求める仕組みを確認します。テクスチャを読む前に、フラグメント関数へ届いたUVを表示します。
三角形の内部にもUVが必要です
三角形には三つの頂点がありますが、その内部には多数の画素があります。GPUは、各頂点から渡された値を使い、描画位置に対応する値を求めます。この処理を補間(Interpolation)と呼びます。
例えば、三つの頂点が(0, 0)、(1, 0)、(0, 1)というUVを持つとします。三頂点がカメラから同じ深度にある例では、三角形の重心に対応するUVは(1/3, 1/3)になります。重心を表すための頂点がなくても、画素処理はその場所のUVを利用できます。
頂点から離れると値が連続的に変わります
ある頂点の近くでは、その頂点の値が結果へ強く反映されます。三角形の内部を移動すると、各頂点の寄与が変わり、補間結果も連続的に変わります。
前期で使用したLerpは、二つの値を割合に応じて混ぜる関数でした。GPUが三角形内で行う補間も、複数の値から中間の値を求める考え方に基づいています。ただし、全画素に対して自分で補間の式を書く必要はありません。
透視投影では遠近関係も考慮されます
奥行きの異なる三角形を透視投影で描く場合、画面上で単純に値を混ぜるだけでは、画像の貼られ方が不自然になります。通常の浮動小数点の頂点出力に対して、GPUは透視投影を考慮した補間を行います。
この処理には、頂点位置の投影に使った情報が関わります。前回、頂点関数がwを含むクリップ座標を出力したことは、色やUVの受け渡しともつながっています。詳しい処理はMicrosoftのラスタライザー段階の説明で確認できます。
UVを赤と緑の成分へ対応付けます
TextureTint.shaderのFrag関数全体を、次の関数へ置き換えます。関数の引数にVaryings inputを追加し、受け取ったUを赤、Vを緑として出力します。青は0、Alphaは1です。
float4 Frag(Varyings input) : SV_Target
{
return float4(input.uv.x, input.uv.y, 0.0, 1.0);
}input.uv.xとinput.uv.yは、二成分の値から一成分を取り出す記法です。このように個別に取り出す代わりに、float4(input.uv, 0.0, 1.0)と書いて二成分をまとめて色の出力へ使うこともできます。
この表示では、Uが大きい場所ほど赤の成分が増え、Vが大きい場所ほど緑の成分が増えます。UVが0から1の範囲にある面では、色の連続的な変化からUVの向きを読み取れます。
保存してConsoleとGameビューを確認します。原点UV=(0,0)なら黒、(1,0)なら赤、(0,1)なら緑、(1,1)なら黄です。Textureを割り当てていなくても、この表示はできます。次のステップへ進むまでUVの色表示を残してください。
Shader Graph側でも同じ値を表示します
Shader Graph側では、URP Unlit GraphのUVノードからUとVを取り出します。SplitとCombineを使い、UをR、VをG、Bを0にしてBase Colorへ接続してください。
テクスチャが未設定でも、UVの可視化ができることを確認してください。UVの取得とテクスチャの取得は、別の処理です。
3つの場所を確認します
| 確認する場所 | 観察する内容 |
|---|---|
| 面の端 | UまたはVが端へ向かって変化しているか |
| 三角形の内部 | 頂点間で値が連続的に変化しているか |
| UVの切れ目 | 同じ立体上でも値が不連続になっているか |
UVの切れ目は、必ずしも不具合ではありません。メッシュの作成者は、画像を展開するためにUVを分けることがあります。色が不連続な場所とメッシュのUV設定を対応付けて確認してください。
- フラグメント関数が補間されたUVを受け取ることを説明できます。
- テクスチャを読み取らずにUVを可視化できます。
- 赤と緑の変化をUとVの変化に対応付けられます。
- UVの切れ目とシェーダーの計算ミスを区別して確認できます。