2013/04/29

さいたま勉強会 vol7 エフェクトの作り方

 4/28にさいたま勉強会に参加してきました。今回は「エフェクトの作り方」として手描きアニメーションによるエフェクト作成の基礎みたいなものを発表させてもらいました。参加者はプログラマばかりなのであまり目に触れる機会のないものだったかと思いますが、単純に見て楽しい内容に映ったようなので良かったかなと思います。

 さいたま勉強会はどんな内容でも発表して良いよというものなので、何が発表されるか毎回ドキドキなのですが、今回もかなりバリエーションに富んだ内容でした。
 今回のおしながきは以下のとおり。

@dsgarageさん Arduino×Unity
 ArduinoをUnityからコントロールしようというお話。シリアル通信で制御可能なはずとのことですが、一からコードを作るのがなかなか困難とのことで、uniduinoというアセット($30)の紹介とともに制御の方法について解説しておりました。Arduino Esploraというゲームパッド型のArduinoがあるそうで、それも気になります。

@k_katsumiさん SECoreTextView
 SECoreTextViewという岸川さんの自作ライブラリの紹介。URLやTwitterのユーザー名、ハッシュタグ、画像などが含まれたリッチテキストの表示を簡易に行うためのライブラリです。かなり応用範囲が広そうな便利なものと感じました。また発表ではどうやって実装しているかの細かい話まで聞けてものすごく濃かったです。

@ajinotataki(私です) エフェクトの作り方
 ゲームにおけるエフェクトはどういうものがあって、どうやって作られているかを軽くおさらいした後に手描きエフェクトの基礎の紹介。その後はリクエストに従って手描きをライブでやりました。細かくは後述します。

@akisutesamaさん Parseでガチャ回すお
 Parseという簡易サーバーサービスを使っていわゆるガチャをどうやるかについてを例に使用方法を紹介。データベースとしては設計を先にしなくてもデータ優先で作っても自動的にサーバーができていく点は良い。しかしサーバー側で実行するコードがJSでデバッグがしづらいなど、そちらの面は難ありとのこと。小規模開発やプロトタイプで使用する分にはいいのではとのことでした。

@yoichinejiさん Logic Proの活用と耳コピについて
 Logic Proを買ったもののどう使って良いかという状況に光を当てる発表。耳コピについてはWaveToneというアプリが非常に便利そうでした。

 さて、エフェクトの発表についてですが、当日のスライドはこちら。PDFはこちら

 で、手描きの基礎に入るわけなのですが、以下の2つがわかればなんとかなるかなと思って紹介しました。
 1つは、「移動の錯覚」で、以下のような点の後に線が表示されることで点が移動して見えるというもの。

 それをディテールを整えると以下のようになります。


 もう1つは「送り」で自然現象は繰り返し出てくるパターンが移動していくように見えることが多いのですが、それを意識して絵を描くということ。

 こんなのも「送り」に含まれると思います。

 で、ディテールを整えると、以下のようになります。

 という感じに紹介しました。
 その後は会場のみなさんにリクエストを貰ってその場で描きました。

 以下のは電撃での攻撃。パズドラみたいに手前から奥に攻撃するイメージ。
 これ描いてる時の録画を岸川さんがやってくれたのですが。それはこちら

 以下のは水属性の攻撃。これも同様に手前から奥に攻撃するイメージ。

 以下のは召喚的なイメージ。何かが現れた感じですね。
これ描いてるのを、これまた岸川さんに録画していただいたのですが、それはこちら

 以上でした。
 ここで紹介したアニメ素材については自由にしてもらって構いません。
 ではではー。

 あ、当日のツイートまとめはこちら

2013/01/15

ライトマップのシェーダーをMac, iOSで両立するには

 先日の記事でライトマップを別シーンで使うために、自前のライトマップシェーダーを用意して行うようにしてましたが、いざそれをiOSへ持っていくとそのままだと問題がでることがわかりました。
 ま、絵が出ないってことなんですけどね。
 Unity標準のライトマップシェーダーもそうなっているそうですが、LightModeの設定にライトマップ方式がいくつかあるのには理由があるらしく、環境によって有効な設定が違うようです。LightMode=VertexLMRGBMはMacならばOKですが、iOSでは何も出ません。逆にLightMode=VertexLMの場合はiOSはOKですが、Macでは何も出ません。という感じです。

 てなわけで、どうするか。
 UnityのShaderLabにはSubShaderというタグがありまして、それを使うと有効なシェーダーが実行時に選ばれるというものがあります。これを使えばいいんじゃない?とすると、以下のようになります。

SubShader {
  Tag { "LightMode" = "VertexLMRGBM" }
}
SubShader {
  Tag { "LightMode" = "VertexLM" }
}

 ところがこれではダメで、LightModeでどうなっててもどうやらSubShaderレベルでは有効なシェーダーとして判別されてしまうようです。なので、やるなら以下のように1つのSubShaderの中に2つをいれてしまいます。

SubShader {
  Pass {
    Tag { "LightMode" = "VertexLMRGBM" }
  }
  Pass {
    Tag { "LightMode" = "VertexLM" }
  }
}

 こうすると片方は何も描画しないのでうまくいくようです。たしかに実際にうまく表示できました。使わない方のPassのオーバーヘッドが無いのかどうかについては調べきれてないです。GLSL化された後のコードを見れば分かるとは思うんですけどね。

参考1:Alpha-VertexLit.shader
http://dorumon.googlecode.com/svn/trunk/pwars/Assets/Standard%20Assets/DefaultResources/Alpha-VertexLit.shader
参考2:Multiple target platform lightmap shader
http://forum.unity3d.com/threads/75487-Multiple-target-platform-lightmap-shader

2013/01/12

Unityのライトマップを別のシーンで使う

 Unityではライトマップはシーンデータに固定されて、他のシーンで使用することが出来ないというのが仕様ですが、他で使用するための方法を考案しました。最初は適当にライトマップを貼れるシェーダー書けばいいんでしょって思ってましたが、どのあたりに制約があるのかわかりました。

 てなわけで、まずはモデルへの焼付けを行います。通常通りモデルやライトをstaticにしてLightmapウィンドウにて焼き付けます。今回はキャラにトップライトを設定して、主にオクルージョンの焼付けをメインにしたような調整で行いました。こうするとある程度キャラに動きが入ってもそこそこ見た目が破綻しないので。


 こんなかんじになります。わかりにくいですが、エプロンの下に影が落ちています。トップライトの影とオクルージョンが入っている感じです。エプロンを腰の後ろで縛っている部分にもオクルージョンが入っていますね。
 試しにこれで動かしてみたら、以下のようになります。(なんか色が違ってますけど、細かいことは気にしないでください。テストレンダリングなので微妙に設定違いだったりするからです)


 で、これを別のシーンにもっていくわけですが、普通だとunity_LightmapSTという値がシーンで管理されているために、正しい描画結果になりません。ライトマップがずれて表示されたりします。このunity_LightmapSTっていう値はどこにどう設定されているのかということですが、LightmapウィンドウのObjectタブを見ると焼き付け後には値が入っていることが分かります。


 下の方にある、Tiling X, Tiling Y, Offset X, Offset Yがそれです。このそれぞれの値がunity_LightmapST.xyzwに入るようにUnityのシステムからシェーダー側へuniform変数として受け渡されます。これを元にシェーダー側ではUV2のスケーリングとオフセットを行なってズレを修正するので、ライトマップが正しく貼れることになります。
 さて、では自前のシェーダーでライトマップ用UV2のズレを修正するには上記の値を何らかの状態で保持しておいてシェーダーに伝達すればいいので、マテリアルのプロパティとして値を追加して持って行く事にしました。以下の用に設定します。(注、自前シェーダーのプロパティなので、普通のシェーダーにはありません)


 ちょっと図が細かいですけど、先ほどの値をマテリアルのLightmapSTのVectorへセットしてあります。ちなみにシェーダーコードは以下の様な感じです。HalfLambert + Lightmap + Ambientにしてあります。


 描画結果はどうなるかというと、以下の様な感じです。ライトマップ焼付けが白のトップライトだったのですが、下の図では横からの赤いライティングでベースに緑が入っているのがわかります。横からの赤いライトがDirectionalLightでHalfLambertになってます。ベースの緑はAmbientですね。ライトマップの影響はほんのりと分かる感じになってます。


 シェーダーコードのことで注意ですが、LightModeはVertexLMRGBMを選択しないと正しくライティングできません。LMRGBMじゃないとライトマップのデコードが出来ないみたいです。とはいってもシェーダーコードの中では特にライトマップとして扱ってるわけでもないんですけどね。謎です。なお、今回はライトマップを1枚で焼き付けましたけど、Dualの場合にはVertexLMを選択することになるみたいです。細かいことは以下を参考に。
 http://docs.unity3d.com/Documentation/Components/SL-PassTags.html

 とはいえ、unity_LightmapSTに縛られたくない場合には、他の方法も考えられます。
 1,ライトマップの焼付けを3dsmaxやSoftimageなどのDCCツール側で行う。UV2も自前で展開してね。
 2,Unityでライトマップ焼付けた後にunity_LightmapSTの補正をスクリプトで計算して、UV2へ書き戻してしまう。これならunity_LightmapSTの値がシーン違いで失われても問題ありません。マテリアルもモデル毎に増えないしいいかもしれない。
 以上です。