Stage3D とテクスチャマッピング

テクスチャマッピングは、テクスチャ (ビットマップ) を 3D オブジェクトの表面、すなわち 3 角形のメッシュに貼り付ける作業です。Photoshop 等で加工した画像を使って、オブジェクト表面に質感を与えることができます。

今回は、Stage3D でテクスチャマッピングを行う方法をご紹介します。

UV 座標

テクスチャマッピングの処理は、大雑把に表現すると、3 角形の上にビットマップを重ねて、3 角形内部の各ピクセルの色を、その上に位置するピクセルの色とする、というイメージです。

その際、ビットマップのどのあたりが 3 角形の上に重なるのか、という情報が必要になります。そこで、ビットマップ内の位置を指定するのに用いられる 2 次元座標が UV 座標です。

UV 座標では、ビットマップの左下が基準点として使われ、U は横方向、V は縦方向の座標です。UV 座標が (0, 0) なら左下の角、(1, 1) なら右上の角の指定になります。

UV 座標の指定は 3 角形の頂点ごとに行います。つまり、この頂点の上に来るのはビットマップのこの位置、という指定をするわけです。なので、当然、UV 座標は頂点バッファ内に指定されることになります。 (この辺りの詳細は Stage3D と 2 つのシェーダと頂点情報

例えば、x, y, z, の座標値と UV 座標の価を持つ頂点バッファを作成するための情報は、以下のような形になります。各行の最後の 2 つが UV 座標の値です。

var vertices:Vector.<Number> = Vector.<Number>
([
  // x, y, z, u, vを指定
  -0.3, -0.3, 0, 1, 0,
  -0.3, 0.3, 0, 0, 1,
  0.3, 0.3, 0, 1, 1
]);

頂点バッファ内の UV 座標は、頂点シェーダに頂点属性として渡されます。頂点シェーダは、 UV 座標を受け取ると、色情報の場合と同様に、後の処理に引き渡します。

テクスチャ関連の Stage3D API

Stage3D でテクスチャを扱う際は Texture クラスを利用します。Texture のインスタンスは context3D.createTexture() メソッドで取得できます。

テクスチャは、シェーダや頂点バッファと同様、事前に GPU にアップロードします。そのため Texture クラスには BitmapData や ByteArray をアップロードするメソッドが提供されています。

下は、Texture クラスの機能を使って BitmapData を GPU にアップロードするサンプルです。

[Embed(source = "MyTexture.jpg" )]
var MyTextureBitmap:Class;
 
var bitmap:Bitmap = new MyTextureBitmap();
// Texture のインスタンス生成
var texture:Texture = context3D.createTexture(bitmap.bitmapData.width,
    bitmap.bitmapData.height, Context3DTextureFormat.BGRA, false);
 
// 埋め込まれたビットマップをGPUにアップロード
texture.uploadFromBitmapData(bitmap.bitmapData);

context3D.createTexture() の第 1 引数はテクスチャの幅、第 2 引数は高さです。第 3 引数はデータのフォーマットで、指定できる値は Context3DTextureFormat クラスに定義されています。ビットマップデータの場合は、上のサンプルの様に BGRA を使います。最後の引数は、アップロードしたテクスチャに描画する場合は true にしますが、通常は false で問題ないと思います。

Texture のインスタンスが生成されたら、データを GPU にアップロードします。上のサンプルでは、埋め込まれたビットマップデータを uploadFromBitmapData() メソッドを使ってアップロードしています。

シェーダ内では、アップロードしたテクスチャ用に、サンプラーレジスタという専用のレジスタが使われます。そこで、シェーダを実行する前に、アップロードしたテクスチャに対応するサンプラーレジスタの番号を指定しておきます。 (レジスタについては Stage3D のシェーダのアップロードと AGAL の基本情報

使用するメソッドは context3D.setTextureAt() です。ここで指定する番号は、シェーダが参照するレジスタの番号と同じものにします。

// サンプラーレジスタの0番にアップロードしたテクスチャを設定
context3D.setTextureAt(0, texture);

context3D.setTextureAt() の第 1 引数は、利用するサンプラーレジスタの番号です。指定できる値は 0 から 7 の何れかです。第 2 引数は、サンプラーレジスタに設定するテクスチャです。

テクスチャを使用する場合のシェーダ

テクスチャを使用する際は、UV 座標が色情報の代わりに頂点シェーダに渡されます。頂点シェーダから見て、色情報を渡された時との違いは、属性レジスタに設定された値の種類だけです。

なので、頂点シェーダに関しては、テクスチャマッピングを行う場合も、以前の記事で紹介したサンプルがそのまま使えます。

m44 op, va0, vc0
mov v0, va1 

2 行目で、頂点シェーダは、属性レジスタ va1 に設定された UV 座標をそのまま出力レジスタである v0 に代入して、次の処理に渡しています。

UV 座標はラスタライズの際に補間され、各断片に割り振られます。断片シェーダは、割り当てられた UV 座標に対応するテクスチャのピクセル (テクセルと言うとか) を参照して、サンプリングを行います。

サンプリングに使われるオプコードは tex です。tex は、ソース 2 の位置 (オプコードから 3 番目) にサンプラーレジスタを指定する点と、その後にオプションを指定するフラグを列挙する点が特徴です。

下は、テクスチャーマッピングを行う断片シェーダの例です。

tex ft1, v0, fs0 <2d,linear>
mov oc, ft1

1 行目で、テクスチャのサンプリングを行っています。v0 が補間された UV 座標、fs0 がアップロードされたテクスチャのレジスタです。サンプラーレジスタの番号 (上の例では 0) は、context3D.setTextureAt() の第 1 引数で指定した数値と同じでないと期待通りに動作しません。

1 行目の最後、サンプラーレジスタの右に記述されているのがフラグです。フラグは複数記述することができます。指定できるフラグには以下のものがあるようです。

  • テクスチャの次元: 2d, cube
  • ミップマップのオプション: nomip , mipnearest, miplinear
  • テクスチャフィルタのオプション: nearest, linear
  • テクスチャの繰り返しのオプション: repeat, wrap, clamp

テクスチャからサンプリングされたデータは、一時レジスタ ft1 に格納され、2 行目で出力レジスタに書き込まれています。

以上で、Stage3D でテクスチャを利用できる様になります。

とはいえ、AGAL でシェーダを書きたい人は少ないと思うので、次回は Pixelbender 3D をご紹介する予定です。

 

トラックバック(0)

トラックバックURL: http://cuaoar.jp/mt4/mt-tb.cgi/237

コメントする

2014年1月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
レンタルサーバー

月別 アーカイブ

Powered by Movable Type 4.261