魔法陣

ファンタジー系ゲームやマンガ、アニメでよくあるヤツで、召喚魔法に使用する魔法円のことです。
円形や五芒星、六芒星ベースの模様の中からモンスターなどを異界から呼び出す…といったものです。
『悪魔くん』や『CCさくら』を思い出してもらえればピンと来るかもしれませんね。

これまで魔法陣による召喚魔法といえば、地面に時間をかけて魔法円を描き、前後には儀式を執り行い、呪文詠唱のあとにようやく召喚が始まる…というのが定番でした。
しかも失敗することもしばしばというのがお約束。
しかし最近は一瞬で魔法陣を地面、空中かまわず作成し、いとも簡単に召喚魔法を実行するというパターンが出てくるようになりました。

今回はこの魔法陣を使った召喚術の演出方法について考えてみました。
ちょっと長いので覚悟してください。

地面の魔法陣から召喚する

地面からの召喚 まず、魔法陣のテクスチャを貼った板モデルを地面すれすれに設置します。
あとは召喚するキャラクターを地面の下に隠れる座標からゆっくり地表座標まで移動させれば、地面に書いた魔法陣から キャラクターを召喚したように見せることが出来ます。

この方法は割と簡単なのですぐに実現できると思います。
注意する点は、魔法陣を地表に設置する際に、地表が平らになっていないと魔法陣が地面の下にもぐりこんで隠れてしまう点です。
また、斜めになっている地面上では、地面の法線方向を調べて魔法陣を傾ける必要があります。

これ以外の方法として、キャラクターモデルの拡大縮小や透過機能なんかを使ってうまく表現するのも面白いかもしれませんね。

演出を含めて魔法陣から召喚する

演出を含めた地面からの召喚 演出効果も含めたテクニックです。

  • まず、地面や建物など余計なオブジェクトを非表示にします。
  • 背景を均一な色にします。(黒一色や白一色が雰囲気に合いそうですね。)
  • 魔法陣のすぐ下に背景色と同じ色の立方体オブジェクトを配置します。
  • 召喚するキャラクターをその立方体オブジェクトの中に入れておきます。
  • 召喚が始まったら、キャラクターをゆっくりと上に移動してやれば魔法陣から出てきたかのように見えます。

こうすることで背景と隠れる場所の色が同じなので隠れていると分かりません。
地形も無視して魔法陣を配置できますし、回りの景色が一転すると異空間を連想させ演出効果も得られそうです。

しかし魔法陣を下から見上げる位置からだと、魔法陣が見えなくなってしまったり、 立体オブジェクトの向こう側に召喚するキャラクターとは別のキャラクターがいた場合それも隠れてしまいます。
また逆に地面や背景などが表示できないという問題もあります。

空中の魔法陣から召喚する

空中魔法陣は、水平に限らず、垂直方向で使われることもあったり無かったり。
魔法陣で空間に穴をあけ(空中です)、そこから何かを召喚するというパターンもあります。

このように地形に影響されず使用できるので、結構便利そうな代物です。


しかし困ったことに、地面が無いので召喚するキャラクターが隠れる場所がありません。
拡大縮小や透過機能をうまく使ってそれらしく演出することも出来ますが、 今回はあくまで魔法陣の表面からキャラクターが出現する方法を考えてみました。

要するに召喚するキャラクターの一部を透明に出来ればいいわけです。

半透明の仕組み

透明も半透明の延長ですので、まず半透明の仕組みを考えてみます。いろいろやってみた結果次のような仕組みになっているようです。

半透明描画は、既に配置されている不透明オブジェクトの状態から描画されます。
逆にいえば半透明描画を行う際に配置されていない不透明オブジェクトは表示されません。

また半透明表示は、不透明オブジェクトの表面にその後ろ側のオブジェクトを考慮した映像が描かれるイメージのようです。


モデルの配置
オブジェクトがこのような配置にあったとします。

スクリプトはこんな感じです。

	;バックバッファにレンダリング
	E3DRender scid, 地面, 0, 0, 0
	E3DRender scid, 緑タコ, 0, 0, 0
	E3DRender scid, 赤タコ, 0, 0, 0

なお不透明描画の場合、E3DRender命令でのバックバッファへのレンダリングには順番は関係ありません。

不透明
これを青の矢印の方向から見るとこうなります。
このように不透明の場合は赤いモデルは緑のモデルの影になって表示されません。

次に緑のモデルを半透明にしてみます。

半透明
このように緑のオブジェクトの向こう側にあるオブジェクトの状態が、緑のオブジェクトの表面に描画されます。

スクリプトはこんな感じです。

	;バックバッファにレンダリング
	E3DRender scid, 地面, 0, 0, 0
	E3DRender scid, 緑タコ, 0, 0, 0
	E3DRender scid, 赤タコ, 0, 0, 0
	E3DRender scid, 緑タコ, 1, frameno0, 0, 0, 0, 1

不透明オブジェクトを全て描画したあとに半透明オブジェクトを描画するのがポイントです。



これらを踏まえて考えると、任意のオブジェクトの一部を隠すのはこうすれば実現できそうです。
「隠したいオブジェクト1を、隠すためのオブジェクト2で隠す場合。」

  • オブジェクト1を、オブジェクト2の中に入れます。
  • この段階で不透明オブジェクトであれば、オブジェクト1オブジェクト2の陰に隠れて見えなくなります。
  • オブジェクト2の表面にオブジェクト1を除く背景映像を表示させます。(オブジェクト2オブジェクト1以外を透過表示させる。)

完成予想図 これが完成予想図です。 あとは透明度を上げて、緑のオブジェクトが見えないようにしてやれば、赤のオブジェクトの一部が切り取られたように隠すことが出来ます。

スクリプトはこんな感じです。

	;バックバッファにレンダリング
	E3DRender scid, 地面, 0, 0, 0
	E3DRender scid, 緑タコ, 0, 0, 0
	E3DRender scid, 緑タコ, 1, frameno0, 0, 0, 0, 1
	E3DRender scid, 赤タコ, 0, 0, 0

半透明の部分に表示したくないオブジェクトは、半透明を描画したあとに描画するのがポイントです。

モデルを準備する

これから作っていきますので、まず魔法陣と召喚するキャラクターが隠れる場所のモデルを作成します。
まずはメタセコイアで作業します。

メタセコイア
魔法陣と透明にするボックスは別々にモデル作成したほうが魔法陣を綺麗に表示させることが出来るのですが、 今回は面倒なので1つのモデルの中に入れてしまうことにします。

魔法陣セット - 魔法陣のみ 魔法陣
魔法陣のテクスチャを貼った1枚板です。
面を両面化しておくと、下から覗き込んだときでも魔法陣が表示されるようになります。
不透明度を0.99以下にするのを忘れないようにしましょう。

魔法陣セット - 透明ボックスのみ 透明ボックス
材質設定の諸設定(不透明度など)は全て0.0にしておきます。
色は何色でもかまいません。(あとで補足説明します。)

※画像は見やすいように不透明度を1.0にしてあります。また、不透明度に限って言えばあとで変更できるので0.0にする必要はありません。

魔法陣セット 完成したモデルはこのようになります。

魔法陣の端と透明ボックスの端の位置はそろえるようにしておかないと後々違和感がある結果になりますので注意が必要です。
その辺は各自お試しください。




RokDeBone2
作成したメタセコのファイルをRDB2でさらに加工します。

階層構造エディタから魔法陣を右クリックしてSig Paramsダイアログを表示します。
表示面を「3:両面」にします。 面の色透明度が1.0より小さくなっていることを確認します。(0.99など)
OKをクリックして設定を反映させます。
設定が反映されたことをメイン画面で確認します。

※透明度が1.0のままだと、透過情報をもったPNG画像を使用しても透過されません。


階層構造エディタから透明ボックスを右クリックしてSig Paramsダイアログを表示します。
面の色透明度0.03に設定します。
OKをクリックして設定を反映させます。
設定が反映されたことをメイン画面で確認します。

よく見るとうっすらと見えるのが確認できますが、これ以上透明度に小さい値を設定すると HSPで実行時にまったく表示されなくなってしまい、期待した効果が得られません。
その辺は各自ご確認ください。

完成したモデルをSIG形式で出力します。



これでモデルの準備は完了です。
次はこのモデルを使用したサンプルを見てみてください。

サンプル

サンプル実行結果 魔法陣でタコを召喚するサンプルです。
魔法陣の方が上下に動いて、タコを出したり消したりします。
キーボードの上下キーでカメラ位置を変更できますので好きな位置から見てください。

タコモデルのファイルtako.sigとタコ用テクスチャファイルtako01.bmpを用意しておいてください。
下のファイルを解答するとMediaフォルダが出てきますのでその中にコピーしてください。
実行に必要なファイル:e3d3038.zipmd_mapdata.zip
スクリプトは前後省略してあります。

	…

;/////////////////
;
;	メインループ
;
*main
	E3DGetKeyboardState keybuf	;キー状態取得


	E3DBeginScene	;-----シーンスタート

		;モデルが、視野内にあるか判定
		repeat 3
			E3DChkInView scid, hsid(cnt)
		loop

		if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了
		gosub *MoveChara		;キャラクター移動
		gosub *MoveCamera		;カメラ移動

		;オブジェクトの描画をする
		E3DRender scid1, hsid(0), 0, frameno0, 0	;地面
		E3DRender scid1, hsid(2), 0, frameno0, 0	;魔法陣と透明ボックス
		E3DRender scid1, hsid(2), 1, frameno0, 0, 0, 0, 1	;魔法陣と透明ボックス
		E3DRender scid1, hsid(1), 0, frameno1, 0	;タコ描画

	E3DEndScene			;-----シーン終了
	E3DPresent scid1	;バックバッファの内容を、プライマリバッファに転送。描画する。

	E3DWaitByFPS 60, chkfps1 : await 0
	title ""+chkfps1 + " FPS"

goto *main

	…

問題点

サンプルでは魔法陣と透明ボックスを同じモデル内で作成しましたが、この方法では魔法陣の周りが綺麗に処理できないので、 本来なら魔法陣と透明ボックスは分けて作成したほうが綺麗な仕上がりになります。
今回のは単なる手抜きです。(^ ^;

さて、この方法にも問題点はあります。
透明にするためのボックスが、完全な透明に出来ないため、よく目を凝らすとうっすらと境界線を見ることが出来ます。
また、透明度が0.03は経験値から割り出した値なのでどの環境でも非表示オブジェクトにならないという保証はありません。

うっすらと見える問題は、透明ボックスの元の色がうっすらと見えるためなので、白や黒、青など背景などの状況に合わせて 色を設定すると若干目立たなくすることが出来ます。
透明度0.03は調査が必要な部分です。