テクスチャパラメータ
今回のサンプルの実行結果
テクスチャが持つ特性
前回はマルチテクスチャと題して、一つのポリゴンモデルに、複数のテクスチャを適用してレンダリングする方法について解説しました。マルチテクスチャレンダリングを習得すれば、テクスチャを合成することによって得られる様々な演出効果を実現でき、さらなる表現力の向上につながります。
今回は、テクスチャを使ったレンダリングのさらなる品質向上を目指して、テクスチャパラメータについて解説します。テクスチャパラメータを駆使することで、レンダリングされるモデルはさらに高品質なものになります。若干わかりにくい部分もあるかもしれませんが落ち着いて考えましょう。
そもそも、WebGL におけるテクスチャパラメータとはいったいなんなのか、まずはそこから説明します。
テクスチャパラメータとは、テクスチャが持つレンダリングされる際の品質や性質に関わる特性だと考えることができます。仮に、まったく同じ解像度、まったく同じサイズの画像を適用したテクスチャであっても、テクスチャパラメータが異なっている場合にはレンダリング結果が大きく変化します。
テクスチャパラメータには、大別して二つの種類があります。
一つ目はテクスチャの品質に関わるパラメータで、これらを変化させることでレンダリングされた際にテクスチャに適用されるフィルタが変化します。結果、美しく補間されたテクスチャを使った高品質なレンダリングを行なうことが可能になります。
もう一つのテクスチャパラメータは、テクスチャの性質を変化させます。具体的には、通常の範囲外のテクスチャ座標を指定された際のテクスチャの挙動が変化します。通常、テクスチャ座標は 0 ~ 1 の範囲に収まるようにしなければなりませんでしたよね。実際には、範囲外の値をテクスチャ座標に指定してもレンダリング自体は行なわれます。しかしテクスチャパラメータを指定すると、この範囲外の値をどのように扱うのかを任意に指定することができるようになります。
それでは次項から、実際にテクスチャパラメータの設定方法、及びその結果どのようなレンダリング結果が得られるのかを見ていきましょう。
テクスチャパラメータの設定方法
まずは、テクスチャパラメータを設定する方法から見ていきます。
テクスチャパラメータを設定するには texParameteri
というメソッドを使います。このメソッドは引数を三つ受け取り実行され、テクスチャにパラメータを設定してくれます。
ここで非常に重要なのは、テクスチャパラメータが設定されるのはその時点でバインドされているテクスチャに対してのみであり、WebGL 全体のテクスチャに関する設定が変わるわけではないということです。
texParameteri メソッドの実行例
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
この texParameteri
メソッドは、第一引数に対象となるテクスチャの種類を示す定数を与えます。通常の二次元テクスチャを使っている場合には、ここは前回・前々回でも頻繁に登場した gl.TEXTURE_2D
を指定します。第二引数は、指定するテクスチャパラメータの種類を表す定数、第三引数に、その設定値を表す定数を与えます。
現段階では、第一引数は固定で構わないでしょう。第二引数と第三引数には、それぞれ指定できる定数が決まっていますので、さっそくそれらを詳しく見ていきます。
テクスチャの品質を指定する
テクスチャの品質を指定することとは、具体的にはテクスチャが伸縮(拡大縮小)されるときにどのように扱われるのかを指定することです。WebGL では、テクスチャが拡大表示されるときと縮小表示されるときのそれぞれについて、個別に設定ができるようになっています。
テクスチャが拡大される際の補間方法を指定するには、 texParameteri
メソッドの第二引数に gl.TEXTURE_MAG_FILTER
を、テクスチャが縮小される際の補間方法を指定するには gl.TEXTURE_MIN_FILTER
を指定します。
また、これらの品質指定には以下のような組み込み定数を利用できます。ここで注意してほしいのは、MAG_FILTER と MIN_FILTER では、それぞれ指定できる定数が若干異なっている点です。
テクスチャの品質指定
定数名 | 意味 | MIN | MAG |
---|---|---|---|
gl.NEAREST | 対象ピクセルの中心に最も近い点の値をそのまま採用 | ○ | ○ |
gl.LINEAR | 対象ピクセルに最も近い4点の値を加重平均化して採用 | ○ | ○ |
gl.NEAREST_MIPMAP_NEAREST | 最適なミップマップを選択 さらに gl.NEAREST 準拠で値を採用 |
○ | × |
gl.NEAREST_MIPMAP_LINEAR | 最適なミップマップを選択 さらに gl.LINEAR 準拠で値を採用 |
○ | × |
gl.LINEAR_MIPMAP_NEAREST | 最適なミップマップを二つ選択 さらに gl.NEAREST 準拠でそれぞれ値を取り それらの値の加重平均を最終的に採用 |
○ | × |
gl.LINEAR_MIPMAP_LINEAR | 最適なミップマップを二つ選択 さらに gl.NEAREST 準拠でそれぞれ値を取り それらの値の加重平均を最終的に採用 |
○ | × |
ミップマップが使われるのは、イメージを縮小表示しなければならないときだけなので、定数の指定もそれにならった形になっているのがわかりますね。拡大処理される場合には、加重平均による補間処理が行なわれるかどうかのみ、指定できることになります。
ここで挙げた六つの品質設定は、下に行けば行くほど高負荷になります。意味をよく見ればそれは歴然ですね。基本的には NEAREST 系よりも LINEAR 系の処理のほうが負荷が大きい分、高品質な結果を得ることができます。
拡大・縮小の両設定を最も低負荷で指定するとすれば、以下のようにすればいいですね。
テクスチャの品質設定記述例
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
テクスチャの性質を指定する
さて、続いてはテクスチャに範囲外のテクスチャ座標が指定された場合の設定です。こちらも先ほどまでと同様に texPrameteri
メソッドで指定できます。第二引数に指定できる組み込み定数は二種類あり、テクスチャ座標の横軸と縦軸、それぞれに個別に設定します。
テクスチャの横座標に対する指定を行なう際には gl.TEXTURE_WRAP_S
を、縦座標に対する指定を行なう際には gl.TEXTURE_WRAP_T
を指定します。
そしてこれらに対して設定できる値は以下の三種類。
定数名 | 意味 | 例 |
---|---|---|
gl.REPEAT | 範囲外の値に対し繰り返し処理 | 1.25 = 0.25 : -0.25 = 0.75 |
gl.MIRRORED_REPEAT | 範囲外の値を対照的に繰り返し処理 | 1.25 = 0.75 : -0.25 = 0.25 |
gl.CLAMP_TO_EDGE | 値を 0 ~ 1 の範囲内に収まるようクランプ | 1.25 = 1.00 : -0.25 = 0.00 |
言葉ではイメージし難いかもしれませんが gl.REPEAT
の場合は範囲外の値に対し、テクスチャがそのまま敷き詰められたような形で対象となる座標が適用されます。 gl.MIRRORED_REPEAT
では鏡に映したように反転したテクスチャ座標が適用されます。
最後の gl.CLAMP_TO_EDGE
では、全てのテクスチャ座標は 0 ~ 1 の範囲に丸められます。10 だろうが 100 だろうが、どうあがいても 1 になってしまうわけですね。
テクスチャ座標の性質設定記述例
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
まとめ
テクスチャパラメータについて理解できたでしょうか。
テクスチャパラメータを指定する際には、これらの設定がテクスチャごとに個別に行なわれるということに十分に注意しましょう。今回のサンプルでは、テクスチャパラメータを変更しながら、座標を変えてポリゴンをレンダリングしています。これが冒頭に貼ってあるサンプルの実行結果です。
今回のサンプルで使用しているテクスチャ用画像データは二種類あります。
一つ目のテクスチャ用画像
二つ目のテクスチャ用画像
一枚目の画像は前回使ったものとまったく同じものです。二枚目の画像は、前回のものに手を加えて、左側から右側にかけてグラデーションが掛かっています。これにより、範囲外のテクスチャ座標を指定した場合の挙動がわかりやすくなるはずです。
サンプルではこれら二つの画像をテクスチャに設定し、合成してレンダリングしています。そして、ポリゴンの描画先座標と、テクスチャパラメータを変更しながら、合計 9 枚の板ポリゴンをレンダリングしています。
それぞれのポリゴンは、以下の画像のようにテクスチャパラメータを設定しています。まずは上半分に描画されている六つのポリゴン。
これは静止画なので非常にわかりにくいと思いますが、実際のサンプルではポリゴンモデルが Y 軸を中心とした回転をしていますので、動作しているものを見るとパラメータの違いによる品質の変化が非常によくわかると思います。
続いては下半分にレンダリングされている三つのポリゴン。こちらはテクスチャ座標に関する設定の部分を変化させています。ちなみに、今回のサンプルでは、以下のようにテクスチャ座標を各頂点に割り当てています。
全ての頂点で、0 ~ 1 の範囲外の値が指定されているのがわかりますね。
それを踏まえて、以下のレンダリング結果を見比べてみてください。
まるで違う結果になっているのがわかりますね。範囲外の値を意図的に指定する場面はそんなに多くはないかもしれませんが、これらの指定を行なわなければ実現できないテクニックがあるのも事実です。それぞれの設定の違いはしっかり理解しておきましょう。
また、先にも述べたように、これらのテクスチャパラメータはその時点でバインドされているテクスチャに対してのみ有効になります。サンプルでは、二枚目の画像を読み込んだテクスチャが常にバインドされている状態になっているため、一枚目の画像を読み込んだテクスチャには、品質的にも、またテクスチャ座標に関する性質的にも、一切変化が起こっていません。これも大きなポイントの一つです。
今回のサンプルは以下のリンクから実際に動作するものを見ることができます。静止画像ではなかなか変化がわかりにくいので、是非サンプルを実際に動作させて、変化を実感してみてください。
次回はブレンディングについて解説します。ブレンディングに関する理解が深まれば、半透明処理や様々な合成エフェクトを使えるようになります。