Onoty3D

Unityに関するメモとか

指定範囲のモデルをボクセルで生成し直す

2017/06/11 19:40
スクリプトに一部不備がありましたので修正しました…(てへぺろ)

指定範囲にあるモデルを、別の場所にボクセルで生成し直すスクリプトを作りました。

もともととあるイベントで利用された?(※)、#オノッチ解体ショー というハッシュタグの便乗ネタで、twitterのアイコンにもしている鹿モデルの解体をするために作ったスクリプトです。

福岡VR・ARコンテンツの開発とWindows 10最新情報セミナー - Togetterまとめ

解体~!

f:id:onoty3d:20170611182652g:plain

ボクセル生成原理

原理としては簡単で、指定範囲に細かい点をプロットし、各点が指定範囲内にあるモデルのメッシュの内側であるならばそこにボクセルを生成する、という処理をしているだけです。
ネタがわかれば「なんだそれだけ」って感じの力技…。

メッシュの内側にあるかどうかの判定は、判定したい点に対して、上下左右前後の6方向からRayを飛ばし、そのすべてのRayが何かにHitすれば内側だとみなしています。f:id:onoty3d:20170611182819p:plain
よって6方向以外で隙間が空いている場合なんかは、外側でも「内側」だと誤認してしまいます。より厳密に判定したい場合は、Rayを飛ばす方向を増やしてみたりするといいかもしれません。
Rayを飛ばして判定しているので、指定範囲内に含むモデルは一部分でも、複数モデルでも問題ありません。
ただし後述しますが、MeshColliderをセットする必要があります。

色の決定原理

ボクセルの色は、6方向から飛ばしたRayで、一番判定点の近くで衝突したRayのHit情報から取得しています。
HitInfoのTriangleIndexを利用するため、指定範囲内に含むモデルにはMeshColliderをセットしておいてください。

f:id:onoty3d:20170611183708p:plain
中まででぎっちり色がついている

マテリアルのテクスチャから色を取りますが、テクスチャがない場合はマテリアルのカラー情報から色を取ります。
それでも色が取得できない("_Color"パラメタを持たないシェーダを使っている)場合は、黒色になります。
色が決定したら、あらかじめ指定したマテリアルを複製してボクセルにセットしています。よって好きなシェーダーを利用することができます。
ボクセルの数だけマテリアルが生成されるのは避けたいので、同じ色の場合はマテリアルを共通して使います。
(頂点カラーと、頂点カラーを表示するシェーダーを使えばマテリアルはひとつですみますが、好きなシェーダーを使える形にしたかった。)

スクリプトの使い方

まず指定範囲用の空のGameObjectを用意し、VoxelTargetAreaスクリプトをAddします。

f:id:onoty3d:20170611184212p:plain

TransformのPositionScaleで範囲の位置や大きさを変更できます。
VoxelCountパラメータで、X,Y,Z方向の細分化数が指定できます。
この設定値に従って、最大でX*Y*Z個のボクセルが生成されます。
細分化の個数によっては、生成されるボクセルがきれいな立方体ではなく直方体になったりします。
指定範囲と細分化の具合はSceneビューで青いGizmoで表示されます。

f:id:onoty3d:20170611184334p:plain

次に生成場所用の空のGameObjectを用意し、VoxelGeneratorスクリプトをAddします。

f:id:onoty3d:20170611190435p:plain

TextAreaパラメータには先程用意した指定範囲用のGameObjectを指定します。
(この時点でSceneビューに指定範囲と同サイズの赤いGizmoが表示されます。)f:id:onoty3d:20170611184404p:plain

Inside Checkerパラメータで、メッシュの内側判定に使うパラメータをセットします。
Target Layer:対象とするモデルのLayerが指定できます。指定範囲内でもTargetにしていないLayerのモデルは無視されます。
Ray Distance:点に対してどのくらいの距離からRayを飛ばすかを指定できます。モデルが大きい場合は大きな値をセットしてください。
Ray Radius:内側判定の精度をあげるため、RayCastではなくSphereCastを利用しています。上手くボクセルが生成されない場合は値を大きくしてみるといいです。

残りのパラメータで、ボクセルに関する情報を設定します。
Voxel Layer:生成するVoxelのLayerを指定できます。
Parent:生成するVoxelのParentを指定できます。
Base Material:生成するVoxelにBase Materialで指定されたMaterialのcloneをセットします。
Material Color Name:ボクセルの色を反映させるシェーダーのパラメーター名を指定できます。
Visualization:チェックすると、うちの内側判定とボクセルの生成をひとつずつ可視化して行います。

後は実行中にVoxelGeneratorのGenerateボタンを押せば、ボクセルが生成できます。
Visualization無し

f:id:onoty3d:20170611184628g:plain

Visualization有り

f:id:onoty3d:20170611184705g:plain

UnityPackage

鹿のサンプルシーンも含めたUnityPackageです。

VoxelGenerator

UnityPackageはUnity5.6で作成しています。5.5でも取り込めますが、鹿のテクスチャ情報が消えてしまう場合があるようなので、その時はテクスチャを再セットしてください。
またLayer8を"Voxel"として登録して置いてください。(登録しなくてもいいがVoxelLayerの設定が空欄になる。)

もっと作り込みできそうな所

マテリアルを動的に複製しているため、実行中に出来上がったボクセルをコピーして、終了後に貼り付けてもマテリアルがMissing状態になります。
実行後も再利用したい場合はマテリアルを保存する仕組みにすべきかと思います。

f:id:onoty3d:20170611185947p:plain

また、マテリアルは同色では共通して使うようにしていますが、テクスチャの色数が多いモデルの場合、同じような色でも微妙に違ったりして、どうしてもマテリアルの数が増えます。減色や均一化の処理をかました方がいいかと思います。
もしくはやっぱり頂点カラーの利用…。

ソース

Ink Painterを使って、パーティクルの衝突でインクが塗れるようにする

Esさんが無料で公開しているすばらしいアセット、Ink Painter

www.youtube.com

オブジェクトが衝突したところやマウスでクリックしたところなんかにインクを塗布できる楽しいアセットです。
今のところパーティクルが衝突したときにインクが塗布する機能はないようなので、スクリプトを作成しました。

こんな感じになります。

f:id:onoty3d:20170518000503g:plain

作り方
Ink Paiter付属のサンプルシーン、Sample01-Paint-に新規にパーティクルを追加します。
パーティクルの向きや重力設定を調整し、さらにCollisionモジュールでパーティクルがCubeやPlaneに当たるようにします。

f:id:onoty3d:20170517235527p:plain
この時重要なのは、Send Collision Messageにチェックを入れることです。
これにより、パーティクルの衝突が検知できるようになります。

パーティクルにParticle Paiterスクリプトをセットします。
以下のような感じで設定します。

f:id:onoty3d:20170517235620p:plain

設定はこれだけ。
これを実行すると、前述の動画のようになります。
また、パーティクルを

のような液体状のものに変えれば、いよいよイカゲームのような感じになります。
以前twitterに投稿した動画。

※インクが垂れていく表現はHightFluidスクリプトの効果です。
Ink PainterのサンプルシーンのSample10-HightMapFluid-を参考にしてみてください。

インクの塗布以外にもInk Painterは色々機能があるので、みなさんもぜひぜひ触ってみてくださいネ!


以下ソース

プロ生ちゃん付属のToon Shaderにデカール機能を足して血糊表現とかしてみる。

2月に作ってtwitterにだけ投げて終わっていたプロ生ちゃんのデカールでの血糊表現。

その表現のために作ったデカールシェーダーとスクリプトを公開します。
作ったというか、もともとプロ生ちゃんにつけていたToon Shaderを改造しました。

→なぜスクリプトまであるのか。
単なるデカール処理だけならシェーダーだけでよかったのですが、プロ生ちゃんの衣服のようにテクスチャを左右対称に展開して利用しているようなUV設定の場合、デカールも左右対称になって格好悪いということが当時製作中に判明しました。

f:id:onoty3d:20170516235816p:plain

これを解決するために、スクリプトで新たにデカール用にUV2を作成し、それを参照してデカールを上乗せするようにした、という理屈です。
参考。
Unity - スクリプトリファレンス: Mesh.uv2

デカールを左右非対称で出したい場合は、UV2Setterというスクリプトをプロ生ちゃんのモデルにセットしてください。
セットした状態で実行すると、実行時に動的にUV2が作成され、デカールが左右非対称になります。

f:id:onoty3d:20170516235841p:plain

マテリアルの設定はこんな感じ。
デカールのテクスチャに加え、Decal Colorというパラメータも作ったので、デカールのテクスチャにさらにDecal Colorを乗算できます。

f:id:onoty3d:20170517000141p:plain

ちなみに血糊テクスチャにはニコニ・コモンズの素材をお借りしました。
https://commons.nicovideo.jp/material/nc44564
https://commons.nicovideo.jp/material/nc44570


ソースは以下。
なお内部でプロ生ちゃんのモデルデータに付属のToon Basicシェーダーの処理を呼んでいるため、Toon Basicシェーダーが含まれるプロジェクトにインポートして使うのがいいかと思います。

高崎柚乃ちゃんのBlendShaperをGUIで操作する

高崎柚乃ちゃんには、表情の変更用にBlendShapeが設定してあるのですが、SkinnedMeshRendererが細かく分割してあるため、インスペクタ上でそれぞれの値を変更するのがけっこう大変です。

というわけでGUIで変更できるようにするスクリプトを作りました。

f:id:onoty3d:20170227010123g:plain

プロ生ちゃんで使っているやつをいじった感じです。
高崎柚乃ちゃんのモデルにセットすれば、各パラメータは空のままでも実行時に自動でSkinnedMeshRendererを探しに行きますが、うまくいかない場合は手動で各パラメータに該当するSkinnedMeshRendererをセットしてみてください。

f:id:onoty3d:20170227005803p:plain

BlendShapeValueChangerYuno

© Gugenka from CS-REPOERTERS.INC/YUNO

クリエイティブ・コモンズ・ライセンス
この作品は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。

 

高崎柚乃ちゃんを触ってみる

先日Gugenkaさんから高崎柚乃(Takasaki Yuno)ちゃんというフリー(商用利用無料)のかわいい3Dモデルが公開されました。

https://gugenka.jp/original/yuno-3d.php

f:id:onoty3d:20170226115056j:plain

日本で企業から公開される3DモデルというとMMDが先行するイメージが強いんですが、このモデルのフォーマットはMA形式とFBX形式で、しかもおすすめシェーダがユニティちゃんシェーダと、Unityでの使用をまずメインにしたような感じで公開されています。

目もMMDで定番の「コッチミンナ」モーフを前提とした凹んだ白目ではなく球体!いいね!

というわけでさっそくUnityに取り込んでみることにしました。

取り込み

MA形式とFBX形式はどちらもそのままUnityに取り込み可能ですが、前者はMayaがインストールされている必要があるようです。
自分は持ってないのでFBXのみをインポート。

インポートすると1モデルに付きエラーと警告が1つずつでます。

f:id:onoty3d:20170226115324p:plain

エラーはアニメーションのタイムレンジが上限超えてるよ、的な。
警告はScale Compensationが云々。とりあえず無視。
これらが出ても、モデル自体は取り込めているようでした。

見た目

とりあえずぐるりと見てみたんですが、ごっそりはみ出てる!!!

f:id:onoty3d:20170226115841p:plain

f:id:onoty3d:20170226115856p:plain
下着がショートパンツやブラウスを突き破ってます。

これは
・上着状態にしたいときは下着を非表示
・下着状態にしたいときは上着を非表示
にすればとりあえず気にならなくなります。

しかし、公式サイトには「ショートパンツからはみ出る下着や脇のラインを堪能しろ」とありますし、公式立ち絵ではブラウスからブラの紐をチラチラさせているので、やはり本来同時表示させるべきものらしく、バージョンアップで改善されるとのことです。
ちなみに上着も下着も非表示…も可能。

<2017/02/28追記>
上記突き抜け問題は、特に改善の必要はないようです。
上着状態にしたい場合は、下着すべてを非表示にするのではなく、bra_hiでグルーピングされている側のみを非表示にすれば良いとのこと。
これで上着を突き抜ける部分のみが非表示になり、裾からチラリと見える部分はのこされるので、公式サイトに書かれているこだわりポイントは維持できます。

 

f:id:onoty3d:20170228001946p:plain

f:id:onoty3d:20170228002112p:plain

Rigの変更

取り込んだ状態のまま、RigをGenericからHumanoidに変更しようとすると、Unityが落ちます(5.5.1f1)。
いきなりフッと落ちるのでどうしたものかと思いましたが、取り込み時にアニメーションがエラーを出していたのを思い出し、AnimationsのパネルからImport Animationのチェックを外した後、改めてRigをHumanoidに変更するとうまく出来ました。

f:id:onoty3d:20170226115816p:plain

 

とりあえずまずはここまで。

これからアニメーション適用させてみたり、表情モーフなんかを見ていきたいと思います。

f:id:onoty3d:20170226115732g:plain

© Gugenka from CS-REPOERTERS.INC/YUNO

クリエイティブ・コモンズ・ライセンス
この作品は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。

 

パラパラ漫画風プロ生ちゃん

プロ生ちゃん Advent Calendar 2016と関係なく書く気でしたが、7日目が空いていたので7日目の記事とします

qiita.com

さて、さっそく本題に入ります。
UnityにCamera Filter Packというイメージエフェクトが300超も詰まったアセットがあります。

色味の調整等基本的なものから、ドット絵化、古いビデオのような表現、雨だれの表現、血しぶき表現、複数カメラの融合等々、思いつく限りのエフェクトが詰まったようなアセットです。

紹介動画

www.youtube.com

ドキュメントはWEBで公開されているので、実際にどんなエフェクトがあるか見てみてください。
Introduction - Camera Filter Pack 3.x for Unity 5.x - Documentation (c) Vetasoft 2016

その中に紙に描いたようにモデルを描画するPaperというエフェクトがあるのですが、特にPaper2というエフェクトが、ノートに書いた絵のように見せるエフェクトで面白いです。

f:id:onoty3d:20161207141306p:plain


また、様々なエフェクトをGitHubで公開されている高橋 啓治郎さんの作品のひとつに、パラパラ漫画風に見せるFlipBookというエフェクトがあります。

github.com

デスノートの映像に使われたのだとか。

 このふたつを組み合わせれば、ノートに書いたパラパラ漫画風に見えるかな、ということで、やってみました。

下準備

GitHub - keijiro/FlipBook: Flip book effect example for Unity
から、FlipBookのエフェクトをZipでダウンロードし、展開します。

展開できたらUnityを起動し、Openボタンで展開したFlipBook-masterフォルダを選択し開きます。
Unity5.5で開く場合、警告ダイアログが出るかと思いますが、そのままContinueで問題ありません。

f:id:onoty3d:20161207142142p:plain

エディタが起動したら、プロ生ちゃんの3DデータCamera Filter Packもインポートします。
以上で準備完了です。

準備が終わったら、まずはSceneを選択します。
SceneはAssets>Test配下にTestという名前であります。
そのまま実行してみると、GitHubで公開されているような画を見ることができます。

キャラクタの置き換え

もともとのキャラクタはMazeLowManという名前で、Sceneオブジェクトの下に居ます。
なので同じ位置にプロ生ちゃんのPrefabを配置します。

f:id:onoty3d:20161207142227p:plain

プロ生ちゃんはお好みのPrefabで構いませんが、シェーダーはToonのやつを使うと、アウトラインが出やすいです。
適当に位置をずらして、ついでにMazeLowManが利用していたKarateのAnimationも拝借して適用しましょう。

f:id:onoty3d:20161207142410p:plain

MozeLowManと周りを飛び交っていたパーティクルは利用しないため、Removeするか非表示にします。

カメラの設定

シーンにはカメラが2つあります。最終的な結果を描画するカメラと、キャラクタを映すカメラ。
ここでは後者を編集します。
後者のカメラはやや深い部分にあります。

f:id:onoty3d:20161207142453p:plain

MazeLowManをコミック風に見せていたエフェクトのContour、Obscurance、Binaryは今回利用しないので、Removeするか、チェックを外します。
新たにCamera Filter PackのPaper2エフェクトを適用します。

f:id:onoty3d:20161207142549p:plain

プロ生ちゃんの線がはっきり出るように、Paper2のパラメータを調整します。
Paper2のパラメータ以外に、プロ生ちゃんの各MaterialのMain Colorの色を明るめにしたほうが線が出やすいかも。

f:id:onoty3d:20161207142600p:plain

いざ実行

こんな感じになりました。

f:id:onoty3d:20161207143131g:plain

Main CameraのMotionスクリプトのMultiple Frame Blendingの設定をいじると、よりパラパラ漫画っぽく見えるかもしれません。

コーディング不要なので、是非是非試してみてください。

 

幼生(おさなま)ちゃん -プロ生ちゃん幼女化-

プロ生ちゃん Advent Calendar 2016、4日目の記事となります。

qiita.com

やること

以前、むにむに教授の動画でユニティちゃんを幼くする、というものを見ました。

www.youtube.com

この動画を見た時点では、自力での実装は無理だなと思っていたのですが、
最近になってメッシュの頂点を直接移動させる技も覚えてきたので、プロ生ちゃんを対象に挑戦してみることにしました。

題して「幼生(おさなま)ちゃん」。
では早速やっていきたいと思います。


顔の実装

動画では、変化後のメッシュの頂点位置が片対数グラフみたいになっていました。

f:id:onoty3d:20161204105122p:plain
(ユニティちゃんの顔がやばい)

変化させたい座標軸の始点の座標を0、終点の座標を1として、途中の点の座標を全体の長さの割合として見立てた場合に、以下の数式で変化させたら上手く行くかな、と思ってまずはそれで実装してみました。
b=a^n
もともとの座標(割合)をa、変更後の座標(割合)をbとする
nは可変パラメータf:id:onoty3d:20161204111106p:plain
nが大きくなるほど、座標は始点側に近づいていく。

この実装でnを変化させてみた場合、このような動きになりました。
・キューブの座標に適用してみた場合
f:id:onoty3d:20161204105640g:plain

・メッシュに適用してみた場合f:id:onoty3d:20161204105800g:plain

これが幼女化の第一歩です。

で、顔のメッシュに適用させてみた場合。f:id:onoty3d:20161204111219g:plain
なるほど幼くなりました!

体の実装

これができれば、あとは体を小さくさせていくだけ。
体型変化についてはネットでググるといろいろとデータが出てくるので、今回はここのデータを参考にさせていただきました。

子供の年齢別・平均体重と平均身長・座高データ(年度別平均表):スクスクのっぽくん | :スクスクのっぽくんスクスクのっぽくん

サイトのデータを参考に、座高を上半身、身長-座高を下半身の変化と見立てて、変化させていきます。
顔と同じようにメッシュの頂点操作をまずは考えたのですが、腕の角度やら何やらを考えるのが大変だったので、ボーンのスケール変更でやってみることにしました。

親ボーンのスケールを変更すると、子ボーンも同様にスケールが変化しますが、この時親ボーンに対して子ボーンに角度がついてると偏った変形になります(Y方向を半分のスケールにしたいのに、子は親に対して垂直についているため、X方向が半分になってしまう、みたいな)。
なので、親ボーンのスケール変更→子ボーンのスケールを一旦戻す→子ボーンのスケール変更…みたいな感じで実装しました。
これに関しては、テラシュールブログさんを参考に、lossyScaleを利用して対応しています。

tsubakit1.hateblo.jp

で、出来上がったのがこれ。

f:id:onoty3d:20161204111733g:plain

体の発育データを参考にしているため、変化は一様ではなく、15歳くらいからゆるやかになります。

f:id:onoty3d:20161204113101p:plain
(体の発育をデータ打ち込みしてるとき、なんか妙に変態な感じがしたんですが気のせいだろう。)

単純に全体のスケールを一様に小さくした場合との比較。f:id:onoty3d:20161204113206g:plain
ただ小さくなっているだけの左とは違い、ちゃんと幼くなっている感じがします。

問題点

一連の実装法の場合、ポーズの変更をしなければとりあえず破綻しません。
ただ、ポーズを変えると妙な具合になります…。

f:id:onoty3d:20161204112126p:plain(頭が歪んでいる…)

先述の、親ボーン・子ボーンの関係と三軸のバラバラスケーリングのせいです。
これに関しては、スケール(年齢)を変更する前にポーズを決定し、そのポーズでスケールを変更すればきれいになります。

f:id:onoty3d:20161204112256p:plain
なので、とりあえず今回は観賞用の幼女といった実装になりますでしょうか…。

この辺を上手くクリアして、揺れものの設定とかもサイズに即したものに変化するようにすれば、ゲームとかでも使えるかもしれません。
実際はこうやってモデル側にボーンモーフ・頂点モーフ的に組み込むのが楽そうな気がします。

以上、プロ生ちゃん幼女化でございました。
最後に年齢変化のシーンと今回作ったスクリプトを公開しておきます。
シーンはUnityPackage、スクリプトは単体で同梱しています。

UnityPackageおよびスクリプト


プロ生ちゃんの3Dモデルは含んでおりませんので、プロ生ちゃんの3Dモデルを含むプロジェクトに本UnityPackageをインポートすると、動くはずです。
最新のUnity5.5でエクスポートしたので、Unity5.4以前にうまくインポートできるかは不明です。