2009年03月18日

テクスチャプラグインを作ってみる

今回はこちらのページを参考にして、テクスチャプラグインを作ってみたいと思います。

一応、Blenderの公式ユーザーマニュアルの中のページなのですが、一番上の部分を見ると「Blender Version 2.31」となっていて、内容がBlenderの最新バージョンに対応していないようです。このページ以外にBlenderプラグインリポジトリなどにもBlenderのテクスチャプラグインのサンプルコードが掲載されていますが、いずれも現在のBlenderに付属するプラグイン作成用のヘッダファイルとバージョンが違っていて、そのままではコンパイルしてもきちんと動作しないようです。

そのため、今回はBlender2.48aの「plugins」フォルダに入っているサンプルファイル「clouds2.c」のソースファイルを元にして、オリジナルのプラグインを作るにはどこを修正すればいいのか、という形で話を進めたいと思います。ただし、上記の参考ページの解説内容については、ほとんどの部分が現在も有効です。今回は最低限の内容に話を絞っていますので、もしこの内容に興味を持たれた場合は、そちらのページの方をご参照ください。
pic090318_01.jpg

まず、「clouds2.c」を複製して「test.c」と名前を変更してください。そして、以下の手順でこのファイルの内容を作り替えていきます。
一応、サンプルデータsample_data090318.zipにソースファイルとWindows(32bit)、Linux(32/64bit)のバイナリファイルを用意してあります。私は現在のところ、Windows64bit、Mac OSなどのバイナリファイルを作ることができません(将来的にもできなさそうです)。ご了承ください。

○コメント
サンプルファイルには冒頭にライセンスについての記述があります。
本来は、きちんとライセンスの内容を確認した上でコードの管理者などを明記する必要があると思いますが、今回はとりあえず冒頭のファイル名の部分を変更してあります。
/**
 * $Id: test.c $
 *

○インクルードファイル
#include "plugin.h"

テクスチャプラグインを作成するには、必ずこの「plugin.h」をインクルードする必要があります。サンプルファイルではこの他に「math.h」をインクルードしていますが、今回は使用しませんので削除してあります。

○プラグイン名の設定
char name[24]= "Test";

とりあえずダブルクォートで囲まれた部分(" ")を変更しています。
参考のページでは、「Texture Buttons Windowでtexture's titleとして表示される」と書かれていますが、現在のバージョンではプラグインファイルのパスが表示されていて、ここで設定した名前は表示されていないようです。

○サブタイプの設定
#define NR_TYPES    1
char stnames[NR_TYPES][16]= {"Default"};

サブタイプというのは、プラグインの使われ方を切り替えるスイッチのようなものです。今回は簡単にするために一つだけに修正しています。「cluds2.c」では、「強度」「カラー」「バンプ」の3種類の使い方ができるようになっていて、「NR_TYPES」が「3」に、「stnames」が「{"Intens","Col","Bump"}」となっています。
pic090318_02.jpg pic090318_03.jpg

○VarStruct構造体 ボタンの設定
VarStruct varstr[]= {
{    NUM|FLO,    "value",    0.0,    -1.0,    1.0,    "test value"},
};

「plugin」パネルに表示するボタン類をここで定義します。ここでは「value」という数値を変更できる数値ボタンを、デフォルト値「0.0」、最小値「-1.0」、最大値「1.0」として設定しています。
VarStructという構造体には「type」「name」「def」「min」「max」「tip」を指定します。
  1. type ここで数値設定用のボタン(数値ボタン、数値スライダ、トグルボタン)、テキストラベルなどのタイプを指定します。数値ボタンの場合数値のフォーマット(INT,FLO)とボタンタイプ(NUM,NUMSLI,TOG)を「|(OR)」で組み合わせて指定します。
  2. name ボタンに表示される名前です。15文字までです。
  3. 数値の範囲 デフォルト、最小、最大の値を指定します。トグルボタンでは「min」が押された状態、「max」が押されていない状態に対応します。
  4. tip ボタン上にマウスポインタを置いたときに表示されるテキストです。80文字までです。

pic090318_04.jpg pic090318_05.jpg

○Cast構造体 ボタンで設定する変数の本体
typedef struct Cast {
    float val;
} Cast;

VarStructでは、ボタンの表示に関する設定だけを行っていて、実際に描画のための処理を行う関数(plugin_tex_doit)で使用するための変数については何も書かれていません。Cast構造体には、VarStructで指定した順番通りに、それぞれのボタンに対応する変数を記述します。今回はボタンが一つだけなので、それに合わせてfloat型の「val」という名前の変数を一つだけ記述してあります。

○変更の必要ない部分
以下、実際のソースコードではplugin_tex_doit()関数まで、基本的には内容を変更する必要のないコードが書かれています。変更していないのでブログの記事上では内容を省略しますが、コンパイルするために必要なコードが書かれていますので、実際のソースコードでは省略しないでください。

○プラグインの描画処理
int plugin_tex_doit(int stype, Cast *cast, float *texvec, float *dxt, float *dyt, float *result)
{
    if (texvec[0] <= cast->val) {
        result[0] = 0;
    } else {
        result[0] = 1;
    }
   
    return 0;
}

この部分がレンダリングの際に、各ピクセルに対して毎回Blenderから呼ばれるプラグインの本体となる部分です。参考のページのもの、pluginsフォルダのサンプル、どちらもそれなりに複雑な計算をする処理が書かれているので、ちょっと見ただけでは内容がわかりにくいように思いました。そこで、このサンプルでは思いっきり簡単にしてみました。

plugin_tex_doit()関数に渡される引数

  1. stype どのサブタイプが有効になっているかが渡されます。今回はサブタイプが一つなので関係ありませんが、 2つ以上設定している場合はこの値に応じて(強度、カラー、バンプなど)処理を分けることになります。
  2. *cast ボタンに応じた変数を格納したCast構造体のポインタです。
  3. *texvec レンダリングされているピクセルで使用されているテクスチャ座標を「float」型の3つの数値で渡しています。texvec[0]がX座標、texvec[1]がY座標、texvec[2]がZ座標となります。
  4.  *dxt,*dyt OSAがオンで、アンチエイリアスが正しく計算されているとき(それ以外はNULLとなりますので確認が必要です)3つのfloat値の配列のポインタが渡されます。アンチエイリアスの計算で使用されるようなのですが、正直なところ私にはまだよく理解できていません。
  5. *result この配列を使って計算結果をBlenderに返します。つまり、このresult[]をなんらかの値に設定することが、この plugin_tex_doit()関数の目的になります。result配列は、float型のresult[0]からresult[7]までの8つの値が渡されます。その中に入れる内容はあらかじめ決まっていて、result[0]は強度、result[1]からresult[4]まではRGBA値、 result[5]からresult[7]までがnormalのXYZ値となります。result[0]の強度は必ず返す必要があります。それ以外はオプションとなります。RGBA、normalの値を返す場合は、plugin_tex_doit()関数の戻り値でそれぞれ「1(RGB)」「2(Normal)」「3(全て)」を返すように設定する必要があります。強度のみの場合は「0」です。
プラグインの描画処理の内容についてです。
このプラグインでは「plugin」パネルで数値ボタン「value」の値を変えることができ、テクスチャ座標のX座標がそれより小さければテクスチャ強度「0」、大きければテクスチャ強度「1」になります。

テクスチャプラグインの描画処理は、基本的に「texvec」からテクスチャ座標(X,Y,Z)を取り出して、その場所でのテクスチャの強度を計算し、結果を「result[0]」に格納する、という感じになります。このサンプルでは「texvec[0]」でテクスチャ座標のX座標についてだけ調べています。

プラグインのパネルに設定したボタンからは、Cast構造体の変数を通して値を受け取ることができます。このサンプルでは「cast->val」の部分で、プラグインパネルの数値ボタンの現在の設定値を調べています。

if文の条件式の部分は、(texvec[0] <= cast->val)となっています。「val」変数にはデフォルト値で「0.0」を指定してあり、テクスチャ座標は、「-1.0」から「1.0」の範囲の値が渡されるようです。
例として、あるピクセルが描画される際、plugin_tex_doit()関数に渡されるテクスチャ座標Xの値が「-0.5」であったとします。このとき「val」の値がデフォルトのままであればif文の条件判定は「-0.5 <= 0.0」でTRUEとなりますから、result[0] = 0がレンダラに渡されます。結果として、そのピクセルはテクスチャ強度「0」となり、テクスチャプレビュー表示では黒になります。
実際にこのプラグインをロードした状態(「Val」が0.0になっている)でテクスチャの「Preview」パネルを見ると、左半分が黒で右半分が白になっています。
pic090318_06.jpg

プラグインパネルの「Value」の値を変更すると、それに応じてプレビューの表示の白い部分と黒い部分の境目が左右に動くのが確認できると思います。
pic090318_08.jpg pic090318_09.jpg

最後の部分で、plugin_tex_doit()関数の戻り値は、result[0]以外を使用していないので「return 0;」としています。
はっきりいって、実用性ゼロのプラグインができてしまいましたが、他のサンプルと比べてかなり内容が分かりやすくなったと思いますが...どうでしょうか。

このブログ、ソースコードのインデントが表示できないことに、今頃気づきました。プログラミングの記事を書くのには向いてなかったようです...。
※追記
スタイルシートとかを変えれば表示できそうなので、少し調べてみたいと思います。 ->スタイルシートは変更できなかったのですが、記事の本文を書く際に「リッチテキストエディタを使用する」というのを選択したら、とりあえずインデントが反映されるようになりました。
posted by mato at 22:50| Comment(0) | Blender | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。