Texture クラスは Texture オブジェクトと同じではないことに注意してください。例えば Art of Illusion は、標準イメージがベースのテクスチャを実装する ImagedMappedTexture というクラスを含みます。このクラスの個別のオブジェクトは、たくさんの異なるパラメータ(テクスチャの定義に使う画像・色・値)の値を指定します。同じようにユーザ自身の Texture クラスは、テクスチャの見映えに影響する自由なパラメータを含むことができます。これでユーザは、あなた自身のクラスの異なるインスタンスをたくさん作成できます。それぞれのクラスが、これらのパラメータで自らの値を持ちます。
Texture クラスのジョブは、1つのオブジェクトの表面プロパティを記述することです。これは getTextureSpec() というメソッドを提供して行います。getTextureSpec() は、表面上の点の座標を取得し、その点での表面プロパティを計算します(Texture クラスが提供するメソッドはほかにいくつかあり、それらは第6章で詳述します)。レンダラーが画像を作成しているとき、これは繰り返し getTextureSpec() を呼び出し、表面上のさまざまな点のプロパティを決定します。そしてそのプロバティで表面の色づけの方法を決定します。
getTextureSpec() に渡された座標は、テクスチャ空間 内の点を参照します。これはテクスチャが定義される 2D または 3D 空間です(サブクラスするのが Texture2D か Texture3D かによる)。ユーザがオブジェクトにテクスチャを割り当てるとき、テクスチャ空間内の点とオブジェクト表面の点との間で対応を定義する、さまざまなマッピングから選べます。
表面プロパティは TextureSpec オブジェクトに返されます。以下は TextureSpec クラスの定義です。
public class TextureSpec { public final RGBColor diffuse, specular, transparent, emissive; public double roughness, cloudiness; public final Vec3 bumpGrad; public TextureSpec(); }diffuse(拡散反射)色、specular(鏡面反射)色、transparent(透明)色は、表面に当たる光のフィルタとして機能します。例えば表面を透過する光は、(透明色)×(入射光)と等しくなります。diffuse 色と transparent 色は同じように、表面による拡散反射、鏡面反射の光量の計算に使われます。
emissive(発光)色は、表面から発する光量を与えます。Renderer が拡散反射光を計算した後、発光色を追加します。このため発光色は、光が当たっていないときの表面の色となります(シーン内の周辺光が拡散反射光に影響することと、明らかな光源がそこに当たっていないときでも、そのためそれが表面の色に影響することを思い出してください。実際に表面を発光させるのなら、ゼロではない発光色のみを使うといいでしょう)。
roughness(粗さ)パラメータの値は0〜1の間で、表面の光沢をどれだけにするかを決めます。これは以下の2つの目的に使われます。鏡面反射ハイライトのサイズの決定と、(Renderer が光沢の反射をサポートしている場合)表面の反射の鋭さ・鈍さの度合いの決定です。同じように、cloudiness(曇り)では、この表面を通して見たときの、オブジェクトの鋭さ・鈍さの見映えの度合い決定します。
bumpGrad パラメータは、凹凸の高さの関数の勾配です。これは 2D テクスチャの場合より分かりやすいです。凹凸の高さは、2D テクスチャ空間内で関数として定義されます。bumpGrad の x, y 要素はこの 2D 関数の勾配を指定します。Z 要素は無視されます。
一方 3D テクスチャでは、凹凸の高さはオブジェクトの表面上でのみ意味があるので、最初は少し混乱します。それにもかかわらず、3次元での連続関数として定義されます。表面上にある点でこの関数の値は、その点での凹凸の高さを決定します。必要な戻り値は、この関数の(フル 3D)勾配です。
(テクスチャに凹凸マッピングを使っているなら、「真」(true) を返すために bumpMapped() メソッドをオーバーライドする必要もあることにご注意ください。そうしないと、bumpGrad の値は単に無視されてしまいます)
もしあなたが Art of Illusion の標準 Texture クラスに慣れているなら(一様テクスチャ、イメージマップテクスチャなど)、このプロパティリストになじみがあるでしょう。注意: 見映えに惑わされることがあります。例えば、透明度と反射率がありません。さらに拡散反射色、鏡面反射色、透明色の解釈は、今までのものとはわずかに異なります。
標準 Texture クラスは、以下の方程式で拡散反射、鏡面反射、透明のパラメータを計算します。
diffuse = diffuseColor * (1-transparency) * (1-specularity)
specular = specularColor * (1-transparency) * specularity
transparent = transparentColor * transparency
ユーザはこれで、1つのスライダーを動かしてテクスチャの透明度または反射率を全体的に変化させられます。これはのユーザインターフェイスの観点でとても便利です。しかし基礎となる API はより一般的です。例えば、標準 Texture クラスでは、テクスチャに入射する赤い光を 100% 反射させ、かつ緑色の光を 100% 透過させるテクスチャを作る方法がありません。
あなた自身の Texture クラスでは簡単にできます。単に拡散反射を (1, 0, 0) に、透明度を (0, 1, 0) にするだけです。表面に入射した光量よりも反射光と透過光の合計のほうが大きい、「物理的でない」テクスチャも作れます。これをするには、拡散反射・鏡面反射・透明に対応する色要素を1以上になるよう足し合わせます。もちろんこれは写実的ではありませんが、アーティステックな効果を作るのに便利です。
既にお気づきかもしれませんが、置換の高さを指定するパラメータはありません。これにはその目的用の別な関数 getDisplacement() があります。置換マッピングはよく、ほかのテクスチャパラメータが使われる陰影計算とは別に前処理段階で行われるからです。
以下は、Texture2D クラスの getTextureSpec() メソッドの完全なシグネチャです。
public void getTextureSpec(TextureSpec spec, double x, double y, double xsize, double ysize, double t, float param[])Texture3D では、以下の2つのパラメータが追加されます。
public void getTextureSpec(TextureSpec spec, double x, double y, double z, double xsize, double ysize, double zsize, double t, float param[])表面プロパティは spec に返されます。x, y, z は、プロパティの計算が必要なテクスチャ空間に座標を与えます。 xsize, ysize, zsize は、第5章で解説するアンチエイリアスに使います。値を返すべき実際のプロパティはこれらの 点(x, y, z)ではなく、幅(xsize, ysize, zsize)の領域の 平均 プロパティです。この平均プロパティは点(x, y, z)に中央を合わせます。t は、プロパティが評価される場合時間(秒)です。これでアニメーションテクスチャを作れます(今のところ Art of Illusion はアニメーションをサポートしていないので、t は常に 0 となります。言うまでもなく将来の変更点です)。(訳注: アニメーション非対応は、この記事が最後に更新された2004年時点のことです。2013年現在、AoI はアニメーションに対応しています)
最後に、すべてのテクスチャは、頂点ごとのテクスチャパラメータ をどんなに多くても定義できます。ユーザが頂点ベースのオブジェクト(三角メッシュやスプラインメッシュ)にテクスチャを割り当てるとき、テクスチャパラメータで頂点ごとの各パラメータに値を指定できます。getTextureSpec() が呼び出されると、表面上で与えられた点でのパラメータ値は param 配列に従います。これは表面プロパティの計算でどのようにでも使えます。ユーザが定義した方法でオブジェクトの表面にわたってテクスチャを変えられる、とても強力な仕組みです。