パーティクルによって崩壊させる MEL スクリプト

MEL スクリプトの例

パーティクルによる崩壊の制作手順を、 MEL スクリプトで自動化してみましょう。

  1. 以下の MEL スクリプトを makeDisintegrate1.mel という名前で作ります。
    proc string makeLambert(string $obj)
    {
    	string $shname = `shadingNode -asShader lambert`;
    	string $sgname = `sets -renderable true -noSurfaceShader true -empty`;
    	connectAttr -f ($shname + ".outColor") ($sgname + ".surfaceShader");
    	select $obj;
    	sets -e -forceElement $sgname;
    	return $shname;
    }
    
    proc string makeRamp()
    {
    	string $ramp = `shadingNode -asTexture ramp`;
    	string $ptex = `shadingNode -asUtility place2dTexture`;
    	connectAttr ($ptex + ".outUV") ($ramp + ".uv");
    	connectAttr ($ptex + ".outUvFilterSize") ($ramp + ".uvFilterSize");
    	return $ramp;
    }
    
    proc makeKeyframe(int $keys[], float $vals[], string $obj, string $attr)
    {
    	int $i = 0;
    	for($k in $keys)
    	{
    		currentTime $k;
    		setAttr ($obj + "." + $attr) $vals[$i];
    		setKeyframe -at $attr $obj;
    		$i++;
    	}
    }
    
    global proc makeDisintegrate1()
    {
    	string $cname1[] = `cylinder`;
    	rotate 0 0 90;
    	string $dname[] = `duplicate`;
    	setAttr ($dname[0] + ".v") 0;
    
    	string $ename[] = `emitter -type surface -r 100 $dname[0]`;
    	setAttr ($ename[1] + ".enableTextureRate") 1;
    
    	string $pname[] = `particle`;
    	setAttr ($pname[1] + ".particleRenderType") 7;
    	addAttr -ln "radius" -at "float" -min 0 -max 10 $pname[1];
    	setAttr ($pname[1] + ".radius") 0.05;
    
    	connectDynamic -em $ename[1] $pname[0]; 
    
    	string $ramp1 = makeRamp();
    	connectAttr -force ($ramp1 + ".outColor") ($ename[1] + ".textureRate");
    
    	setAttr ($ramp1 + ".type") 1;
    	setAttr ($ramp1 + ".interpolation") 6;
    	setAttr ($ramp1 + ".colorEntryList[0].color") -type double3 0 0 0;
    	setAttr ($ramp1 + ".colorEntryList[1].color") -type double3 1 1 1;
    	setAttr ($ramp1 + ".colorEntryList[2].color") -type double3 1 1 1;
    	setAttr ($ramp1 + ".colorEntryList[3].color") -type double3 0 0 0;
    
    	int $keys1[] = {1, 90};
    	float $vals1[] = {1.0, 0.0};
    	makeKeyframe($keys1, $vals1, $ramp1, "colorEntryList[0].position");
    
    	int $keys2[] = {1, 10, 90};
    	float $vals2[] = {1.0, 1.0, 0.005};
    	makeKeyframe($keys2, $vals2, $ramp1, "colorEntryList[1].position");
    
    	int $keys3[] = {1, 20, 90};
    	float $vals3[] = {1.0, 1.0, 0.15};
    	makeKeyframe($keys3, $vals3, $ramp1, "colorEntryList[2].position");
    
    	int $keys4[] = {1, 30, 90};
    	float $vals4[] = {1.0, 1.0, 0.2};
    	makeKeyframe($keys4, $vals4, $ramp1, "colorEntryList[3].position");
    
    	string $shname = makeLambert($dname[0]);
    	connectAttr -f ($ramp1 + ".outColor") ($shname + ".color");
    
    	string $uname[] = `uniform -m 10 -dx 1 -dy 0 -dz 0 $dname[0]`;
    	connectDynamic -f $uname[0] $pname;
    
    	string $ramp2 = makeRamp();
    
    	setAttr ($ramp2 + ".type") 1;
    	setAttr ($ramp2 + ".interpolation") 6;
    	removeMultiInstance -break true ($ramp2 + ".colorEntryList[2]");
    	setAttr ($ramp2 + ".colorEntryList[0].color") -type double3 0 0 0;
    	setAttr ($ramp2 + ".colorEntryList[1].color") -type double3 1 1 1;
    
    	makeKeyframe($keys1, $vals1, $ramp2, "colorEntryList[0].position");
    	makeKeyframe($keys2, $vals2, $ramp2, "colorEntryList[1].position");
    
    	string $shname = makeLambert($cname1[0]);
    	connectAttr -f ($ramp2 + ".outColor") ($shname + ".transparency");
    }
    
  2. Script EditorFile → Source Script によって makeDisintegrate1.mel を読み込みます。
  3. Script Editor のインプットウインドウで、makeDisintegrate1() を実行します。
    (makeDisintegrate1() 実行後の図)
    [makeDisintegrate1() 実行後の図]
  4. アニメーションを実行します。
    [アニメーション実行後の図]
    [レンダリング結果]

スクリプトの解説

proc string makeLambert(string $obj)
Lambert マテリアルを作成し、 $obj で表されるオブジェクトにアサインするプロシージャです。
このプロシージャは lambert ノードの名前を返すので string がついています。
global がついていないので、この MEL スクリプト内でしか使用できません。
string $shname = `shadingNode -asShader lambert`;
lambert ノードを作成し、作成されたノード名を変数 $shname に代入します。
string $sgname = `sets -renderable true -noSurfaceShader true -empty`;
lambert マテリアルをコネクトするためのセットを作ります。
-renderable true
作られたセットはシェーディンググループになって、 renderPartition ノードにコネクトされます。
-noSurfaceShader true
デフォールトのシェーダーにコネクトしません。
上で作ったマテリアル $shname にコネクトするためです。
-empty
空のセットを作ります。
セレクトされているオブジェクトがあっても、 このセットに加えません。
connectAttr -f ($shname + ".outColor") ($sgname + ".surfaceShader");
マテリアル $shname が出力する色情報を表す outColor アトリビュートを、 セット $sgname の surfaceShader アトリビュートにコネクトします。
これで、マテリアル $shname がレンダリング可能になります。
select $obj;
$obj を選択します。
sets -e -forceElement $sgname;
選択された $obj をシェーディングループであるセット $sgname に追加します。
-e
編集モードにします。
-forceElement
選択されているオブジェクトを強制的にセットに追加します。
選択されているオブジェクト別のセットのメンバーである場合は、 別のセットから削除されます。
return $shname;
プロシージャの終わりに lambert ノードの名前を返します。
proc string makeRamp()
ramp ノードを作成するプロシージャです。
このプロシージャは ramp ノードの名前を返すので string がついています。
string $ramp = `shadingNode -asTexture ramp`;
ramp ノードをテクスチャーとして作成します。
string $ptex = `shadingNode -asUtility place2dTexture`;
ramp ノードをテクスチャーとしてオブジェクトに張るための、 place2dTexture ノードを作成します。
connectAttr ($ptex + ".outUV") ($ramp + ".uv");
place2dTexture ノードの outUV アトリビュートを ramp ノードの uv アトリビュートにコネクトします。
connectAttr ($ptex + ".outUvFilterSize") ($ramp + ".uvFilterSize");
place2dTexture ノードの outUvFilterSize アトリビュートを ramp ノードの uvFilterSize アトリビュートにコネクトします。
return $ramp;
プロシージャの最後にramp ノードの名前を返します。
proc makeKeyframe(int $keys[], float $vals[], string $obj, string $attr)
オブジェクト $obj にキーフレームを設定するプロシージャです。
各引数の意味は以下のとおりです。
$keys
キーフレームを設定するフレームを並べた int の配列です。
$vals
各キーフレームに対するアトリビュートの値を並べた float の配列です。
$obj
キーフレームを設定するオブジェクト名です。
$attr
キーフレームを設定するアトリビュート名です。
int $i = 0;
変数 $i を 0 に初期化しておきます。
この変数はキーフレームをカウントするために使用します。
for($k in $keys)
各キーフレームをひとつづつ取り出して $k に代入し、 以下のコマンドでキーフレームを設定してゆきます。
currentTime $k;
現在のキーフレームを $k に設定します。
setAttr ($obj + "." + $attr) $vals[$i];
オブジェクト $obj のアトリビュート $attr に $vals[$i] を設定します。
setKeyframe -at $attr $obj;
オブジェクト $obj のアトリビュート $attr にキーフレームを設定します。
$i++;
$i を 1 増加します。
global proc makeDisintegrate1()
オブジェクト(cylinder)が、 パーティクルとともに消えてゆくエフェクトを作成する プロシージャ(makeDisintegrate1)を宣言しています。
string $cname1[] = `cylinder`;
ここではオブジェクトとして NURBS のシリンダーを作成します。
rotate 0 0 90;
作成したシリンダーを Z 方向に 90 度回転します。
string $dname[] = `duplicate`;
シリンダーを複製します。
setAttr ($dname[0] + ".v") 0;
複製されたシリンダーの visibility を 0 にして、 見えない状態にします。
string $ename[] = `emitter -type surface -r 100 $dname[0]`;
エミッターを作成します。
-type surface
エミッターの種類を surface にします。
これによりオブジェクトの表面からパーティクルが放出されます。
-r 100
1 秒間に発生するパーティクルの個数を 100 にします。
setAttr ($ename[1] + ".enableTextureRate") 1;
エミッターのアトリビュート enableTextureRate を 1 にします。
これにより、パーティクルの放出個数が、 テクスチャーの色によってコントロールされるようになります。
string $pname[] = `particle`;
エミッターから放出するパーティクルを作成します。
setAttr ($pname[1] + ".particleRenderType") 7;
パーティクルシェイプのアトリビュート particleRenderType を 7 に設定します。
これにより、パーティクルの種類が blobby になります。
addAttr -ln "radius" -at "float" -min 0 -max 10 $pname[1];
パーティクルシェイプに radius という名前で float のアトリビュートを追加します。
この radius アトリビュートによって、 blobby の半径を設定できるようになります。
この radius アトリビュートの最大値(-max)は 10、 最小値(-min)は 0 です。
setAttr ($pname[1] + ".radius") 0.05;
blobby の半径を 0.05 に設定します。
connectDynamic -em $ename[1] $pname[0];
エミッターからパーティクルが放出されるように、 エミッター($ename[1])とパーティクル($pname[0])をコネクトします。
string $ramp1 = makeRamp();
ramp テクスチャーを作成します。
makeRamp() は上で定義したプロシージャです。
$ramp1 には作成された ramp テクスチャーの名前が代入されます。
connectAttr -force ($ramp1 + ".outColor") ($ename[1] + ".textureRate");
テクスチャーの色によって、 パーティクルの放出量がコントロールされるように、 ramp テクスチャーのアトリビュート outColor と、 エミッターのアトリビュート textureRate をコネクトします。
setAttr ($ramp1 + ".type") 1;
ramp テクスチャーの種類を、V ramp にします。
setAttr ($ramp1 + ".interpolation") 6;
ramp テクスチャーの保管方法を Spike にします。
これによって、色が急速に変化するようになります。
setAttr ($ramp1 + ".colorEntryList[0].color") -type double3 0 0 0;
ramp テクスチャーの 1 番目の色を 0 0 0 (黒) に設定します。
setAttr ($ramp1 + ".colorEntryList[1].color") -type double3 1 1 1;
ramp テクスチャーの 2 番目の色を 1 1 1 (白) に設定します。
setAttr ($ramp1 + ".colorEntryList[2].color") -type double3 1 1 1;
ramp テクスチャーの 3 番目の色を 1 1 1 (白) に設定します。
setAttr ($ramp1 + ".colorEntryList[3].color") -type double3 0 0 0;
ramp テクスチャーの 4 番目の色を 0 0 0 (白) に設定します。
int $keys1[] = {1, 90};
キーフレームを設定するために、 キーになるフレーム番号 1 と 90 を int の配列 $keys1 に代入します。
float $vals1[] = {1.0, 0.0};
キーフレームを設定するために、 各キーの値 1.0 と 0.0 を float の配列 $vals1 に代入します。
makeKeyframe($keys1, $vals1, $ramp1, "colorEntryList[0].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp1)の 1 番目の色の位置(colorEntryList[0].position)に、 キーフレームを設定します。
int $keys2[] = {1, 10, 90};
キーフレームを設定するために、 キーになるフレーム番号 1, 10 と 90 を int の配列 $keys2 に代入します。
float $vals2[] = {1.0, 1.0, 0.005};
キーフレームを設定するために、 各キーの値 1.0, 1.0 と 0.005 を float の配列 $vals2 に代入します。
makeKeyframe($keys2, $vals2, $ramp1, "colorEntryList[1].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp1)の 2 番目の色の位置(colorEntryList[1].position)に、 キーフレームを設定します。
int $keys3[] = {1, 20, 90};
キーフレームを設定するために、 キーになるフレーム番号 1, 20 と 90 を int の配列 $keys3 に代入します。
float $vals3[] = {1.0, 1.0, 0.15};
キーフレームを設定するために、 各キーの値 1.0, 1.0 と 0.15 を float の配列 $vals3 に代入します。
makeKeyframe($keys3, $vals3, $ramp1, "colorEntryList[2].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp1)の 3 番目の色の位置(colorEntryList[2].position)に、 キーフレームを設定します。
int $keys4[] = {1, 30, 90};
キーフレームを設定するために、 キーになるフレーム番号 1, 30 と 90 を int の配列 $keys4 に代入します。
float $vals4[] = {1.0, 1.0, 0.2};
キーフレームを設定するために、 各キーの値 1.0, 1.0 と 0.2 を float の配列 $vals4 に代入します。
makeKeyframe($keys4, $vals4, $ramp1, "colorEntryList[3].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp1)の 4 番目の色の位置(colorEntryList[3].position)に、 キーフレームを設定します。
string $shname = makeLambert($dname[0]);
上で定義したプロシージャ makeLambert() によって、 lambert マテリアルを作成し、 その名前を $shname に代入します。
connectAttr -f ($ramp1 + ".outColor") ($shname + ".color");
ramp テクスチャーのアトリビュート outColor を、 lambert マテリアルのアトリビュート color にコネクトします。
これによって、lambert マテリアルに ramp テクスチャーがアサインされます。
string $uname[] = `uniform -m 10 -dx 1 -dy 0 -dz 0 $dname[0]`;
uniform フィールドを作成します。
-m 10
フィールドの強さを 10 に設定します。
-dx 1 -dy 0 -dz 0
フィールドの方向を 1 0 0 に設定します。
これによって、X 軸方向にフィールドの力がパーティクルに加わります。
connectDynamic -f $uname[0] $pname;
uniform フィールドとパーティクルをコネクトして、 パーティクルに uniform フィールドの力が作用するようにします。
string $ramp2 = makeRamp();
上で定義したプロシージャ makeRamp() を使用して、 ramp テクスチャーを作成します。
$ramp2 には作成された ramp テクスチャーの名前が代入されます。
setAttr ($ramp2 + ".type") 1;
ramp テクスチャーの種類を、V ramp にします。
setAttr ($ramp2 + ".interpolation") 6;
ramp テクスチャーの保管方法を Spike にします。
これによって、色が急速に変化するようになります。
removeMultiInstance -break true ($ramp2 + ".colorEntryList[2]");
ramp テクスチャー($ramp2)の 3 番目の色(colorEntryList[2])を削除します。
setAttr ($ramp2 + ".colorEntryList[0].color") -type double3 0 0 0;
ramp テクスチャーの 1 番目の色を 0 0 0 (黒) に設定します。
setAttr ($ramp2 + ".colorEntryList[1].color") -type double3 1 1 1;
ramp テクスチャーの 2 番目の色を 1 1 1 (白) に設定します。
makeKeyframe($keys1, $vals1, $ramp2, "colorEntryList[0].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp2)の 1 番目の色の位置(colorEntryList[0].position)に、 キーフレームを設定します。
ここで、キーフレームのフレーム番号と各フレームの値は、 一つ目の ramp テクスチャーの 1 番目の色の位置と同じ値 ($keys1 と $vals1)を使用していることに注意してください。
makeKeyframe($keys2, $vals2, $ramp2, "colorEntryList[1].position");
上で定義したプロシージャ makeKeyframe() によって、 ramp テクスチャー($ramp2)の 2 番目の色の位置(colorEntryList[1].position)に、 キーフレームを設定します。
ここで、キーフレームのフレーム番号と各フレームの値は、 一つ目の ramp テクスチャーの 2 番目の色の位置と同じ値 ($keys2 と $vals2)を使用していることに注意してください。
string $shname = makeLambert($cname1[0]);
オリジナルのオブジェクト($cname1[0])に、 新しい lambert マテリアルをアサインします。
connectAttr -f ($ramp2 + ".outColor") ($shname + ".transparency");
二つ目の ramp テクスチャー($ramp2)のアトリビュート outColorを、 lambert マテリアル($shname)のアトリビュート transparency にコネクトします。
これによって、 ramp テクスチャーの色でシリンダーの透明部分がコントロールされるようになります。

練習

練習課題

参考


Prev
Home | Contents
Mail