MAXScript によって、Max SDK を使用して MSVC++ でコーディングされたプラグインと機能の点で類似するスクリプト プラグインを作成することができます。スクリプト可能なプラグイン クラスの 1 つは、RenderEffect クラスです。ここでは、レンダリングからカラーを削除するだけの非常に単純なプラグインを作成します。
関連トピック:
全体の流れ:
スクリプト RenderEffect を作成して、レンダリング後にレンダリングされたイメージを変更します。
イメージ内のすべてのラインおよび各ライン内のすべてのピクセルを巡回します。
各ピクセル内のカラー情報をモノクロ値に置き換え、アルファを維持します。
現在のラインとライン総数に基づいて、レンダラーの進行状況バーを更新します。
MAXScript
plugin RenderEffect MonoChrome name:"MonoChrome" classID:#(0x9e6e9e77, 0xbe815df4) ( rollout about_rollout "About..." ( label about_label "MonoChrome Filter" ) on apply r_image progressCB: do ( progressCB.setTitle "MonoChrome Effect" local oldEscapeEnable = escapeEnable escapeEnable = false bmp_w = r_image.width bmp_h = r_image.height for y = 0 to bmp_h-1 do ( if progressCB.progress y (bmp_h-1) then exit pixel_line = getPixels r_image [0,y] bmp_w for x = 1 to bmp_w do ( p_v = pixel_line[x].value pixel_line[x] = color p_v p_v p_v pixel_line[x].alpha )--end x loop setPixels r_image [0,y] pixel_line )--end y loop escapeEnable = oldEscapeEnable )--end on apply )--end plugin
plugin RenderEffect MonoChrome
name:"MonoChrome"
classID:#(0x9e6e9e77, 0xbe815df4)
(
スクリプト プラグインは、コンストラクタの plugin
で始まり、その後にスクリプト プラグインのスーパークラス(renderEffect
)、プラグインのクラス名(MonoChrome
)が続きます。 さらに、効果リスト内で表示される name
と固有の classID
を指定する必要があります。
シーンをロードするときにプラグインを識別するために、classID
が 3ds Max によって使用されます。新しい固有の ID を生成するには、リスナー内で GenclassID()
メソッドを使用し、結果をスクリプト内にコピーすることができます。
ただし、このプラグインのすべてのバージョンが常に互換性を保つようにするには、この classID をコピーすることをお勧めします。
rollout about_rollout "About..."
(
label about_label "MonoChrome Filter"
)
このプラグインにはコントロールがありません。ユーザに何をロード中かを示す、1 行のテキストだけを含んだ非常に単純なロールアウトを作成します。
on apply r_image progressCB: do
(
renderEffect プラグインには、効果がイメージに適用されるたびに実行されるメイン ハンドラがあります。レンダラーのイメージ バッファが、唯一のパラメータとしてハンドラに渡されます。r_image
という名前のユーザ変数を使いますが、これに作業対象のイメージが含まれます。また、イメージの処理中にメイン レンダラーの進行状況バーを更新するために、進行状況のコールバック オブジェクトを定義します。
progressCB.setTitle "MonoChrome Effect"
setTitle
メソッドを progressCB
オブジェクトで使用することで、[レンダリング効果](Rendering Effect)進行状況ウィンドウに表示される名前をそれぞれ定義します。[レンダリング プログレス](Renderer Progress)ウィンドウにそれぞれ表示される名前を定義します。前者の例では、「Currently Updating:MonoChrome Effect」という行が表示されます。後者の例では、「Current Task:MonoChrome Effect」という行が表示されます。
local oldEscapeEnable = escapeEnable
escapeEnable = false
効果のメイン ループ中に[Esc]キーを押す操作を実際にスクリプトを中断しないで捕捉して処理できるようにするために、MAXScript のエスケープ キー処理を無効にする必要があります。この目的のために一時的なユーザ変数内にエスケープ処理の現在の状態(true
または false
)を格納し、次に false
をエスケープ処理を制御している MAXScript システムのグローバル変数に代入します。後で、メイン ループの終了後に、oldEscapeEnable
ユーザ変数内に元の状態を設定します。
bmp_w = r_image.width
レンダリングされたイメージの width
が必要です。イメージの .width
プロパティをユーザ変数の bmp_w
に格納します。
bmp_h = r_image.height
レンダリングされたイメージの height
も必要です。イメージの .height
プロパティをユーザ変数の bmp_h
に格納します。
for y = 0 to bmp_h-1 do
(
イメージ内のすべてのラインをループで巡回します。イメージ ピクセルへのアクセスでは、0 を基点としたインデックス処理が必要です。 つまり、640x480 のイメージの左上の座標は[0,0]であり、右下の座標は[639,479]です。変数 y
には、ループが繰り返されるごとに、0 からイメージの高さから 1 を引いた値が代入されます。
if progressCB.progress y (bmp_h-1) then exit
この行では 2 つの動作が行われます。
.progress
メソッドは true
を返し、それ以外の場合は false
を返しますが、戻り値をチェックして、true
が返された場合はループを終了させます。 これで、y
ループの後の行に進みます。
同じメソッドが、進行状況の割合を計算するために必要な 2 つの引数、つまり現在の値と最大の値を受け入れます。この例では、現在の行と行の総数を指定します。たとえば、現在の行が 300 で、ビットマップには 600 行ある場合は、進行状況バーに 50% 終了と表示されます。
pixel_line = getPixels r_image [0,y] bmp_w
getpixels
関数は、指定されたファイルの Point2 の値で示された位置からピクセルを読み始め、最後の値で指定されたピクセル数を読み取ります。結果は、配列としてユーザ変数の pixel_line
に代入されます。最初のピクセルから開始して左へ読み取り、すべての bmp_w
ピクセルを読みます。 スキャンライン全体にイメージの幅に入るだけの数のピクセルが含まれています。
for x = 1 to bmp_w do
(
これで、ピクセル値の配列内ですべての値を巡回して調べることができます。MAXScript 内の配列は 1 を基点としているため、1 からイメージの幅まで数えます。
p_v = pixel_line[x].value
pixel_line[x] = color p_v p_v p_v pixel_line[x].alpha
これが実際の中核となるコードです。 カラーの .Value プロパティ (グレースケール強度) を取得して、元のピクセルの .Value と等しい赤、緑、および青の値で新しいカラー値を生成します。アルファ チャネルに触れないように、元のアルファ値を RGBA カラーに追加するだけです。結果は配列内の同じ位置に格納するので、カラー情報がグレースケール バージョンで上書きされます。
)--end x loop
setPixels r_image [0,y] pixel_line
スキャンラインのすべてのピクセルを処理した後に、setpixels
関数で、新しいグレースケール値を含んだ配列の pixel_line
を同じ位置から始まるイメージに書き戻します。これで、現在の行 y
内のカラーが上書きされます。
)--end y loop
ループによる準備が完了し、ビットマップ全体が変更されました。on apply
ハンドラによって結果のビットマップがシステムに返され、仮想フレーム バッファ内に表示されます。
escapeEnable = oldEscapeEnable
前に説明したように、レンダリング効果のループ前に MAXScript のエスケープ キーの処理を元の状態に設定する必要があります。
)--end on apply
)--end plugin
スクリプトを評価した後に、新しいプラグイン効果の 「MonoChrome」が、[レンダラー > 効果... > 追加...] (Renderer > Effects... > Add...)に表示されます。それを効果のキューに追加して、シーンをレンダリングします。その結果、モノクロ バージョンでレンダリングされます。スクリプト renderEffects は、SDK を使用して作成された本物のプラグインと比較して低速ですが、非常に柔軟性があり、すばやくプロトタイプ化できます。
仮想フレーム バッファ内で、イメージのアルファ バージョンとモノクロ バージョンを調べることができます。アルファ バージョンは変更されておらず、モノクロ バージョンは renderEffect によって生成された RGB イメージと同じです。
この基本スクリプトの比較的簡単な変更は、ビットマップの N 番目の行だけを常に変更することです。for y ループに by 2
オプションを追加すると、常に 2 番目の行のみに影響を与えることになります。
for y = 0 to bmp_h-1 by 2 do
x ループに by 2
を追加すると、ピクセルのグリッドのみに影響を与えることになります。2 よりも大きい値を使用することもできますし、ユーザ定義の行やピクセル ステップ用の UI コントロールを追加することもできます。
このスクリプトに対するもっと複雑な変更は、R、G、および B チャネル内のモノクロ値の異なるプロパティを使用した、モノクロ イメージへの着色です。そのためには、ロールアウトと 3 つの浮動小数点値を定義する paramBlock を追加し、ユーザが使用する各チャネル量を指定できるようにします。次に、p_v 値に 3 つの値を乗算し、それらの値をイメージの R、G および B の値に代入します。
戻る