☆超初心者向け フリーウェアのみを使用したステレオVR-MMD動画の作り方

TIPS

記事作成日 2018/12/11

※注意

各ソフトウェアは、解説に使用されているものと完全に同一のバージョンをダウンロードして使用してください。少しでもバージョンが違うと、相性問題が発生することが多いためです。

1.モーフの操作

MMDモデル用のモーフには、

1.頂点モーフ
口の開閉、目のまばたき、笑った口等、頂点が動いて機能するモーフ。
2.材質モーフ
パーツの色を変える、一部のパーツを消す等のモーフ。
3.UVモーフ
茶色の目を青くしたり、猫目にしたり、ハートマークにしたり等、テクスチャが変化して機能するモーフ。
4.ボーンモーフ
キャラクターやモーションに合わせて初期姿勢を変更する、メカやステージを変形させる等のモーフ。
5.グループモーフ
「目のまばたき」と「口を開けて舌を出す」を連動して同時に行うモーフ等、を2つ以上の上のモーフを組み合わせたもの。

の5種類があります。
MMDでは表情操作パネルのスライダーを動かすことでモーフを操作できますが、MMD4Mecanimでもモーフを操作することが可能です。

モーフを操作するには、pmxファイル+vmdファイルを変換してPrefabファイルを作成し、Prefabファイルを画面左上側のHierarchyにドラッグ・アンド・ドロップした後、Animator Controllerを設定する前に、以下の1~5を行ってください。

1.画面左上側のキャラクターを選択し、画面右側のInspectorに表示されたMMD4 Mecanim Model (Script)の6つのタブ(Model、Bone、IK、Morph、Anim、Physics)のうちのMorphタブをクリック。
2.下側にあるモーフ一覧のスライダーを適当に動かしながら画面中央上側のSceneの表示を確認し、操作するモーフの種類と変化量を決定して、モーフの名前と数値をメモしておく。
3.Morphタブの3つ左にあるModelタブをクリックし、一番下のAdd Componentボタンをクリック。
4.Scripts>MMD4 Mecanim Morph Helperを選択。 ※MMD4 Mecanim Anim Morph Helperと間違えないように注意。
5.Inspectorの下側に追加されたMMD4 Mecanim Morph Helper (Script)の設定項目に以下を入力。
Morph Speed: 0.1
Morph Name: 上でメモしたモーフの名前
Morph Weight: 上でメモしたモーフの変化量
Override Weight: チェックを入れる


Morphタブのスライダーを動かした場合とは異なり、MMD4 Mecanim Morph Helperを設定しても、画面中央上側のSceneの表示には変化が反映されませんが、画面中央上側の再生ボタンを押したり、Recorderで録画するときには、変化が反映されています。

※もしMorphタブのスライダーを動かしてもSceneの表示が変化しない場合は、いったんHierarchyからキャラクターのオブジェクトインスタンスを削除し、再びPrefabファイルをHierarchyにドラッグ・アンド・ドロップし直してください。(一度でも再生ボタンを押したりRecorderで録画を行うと、スライダーが効かなくなることがあります)

2.ライトの設定

ライト(光源)には3種類あります。

1.Directional Light
空間内の全ての座標に同じ方向の光を照射するライトです。主に太陽光を模した光として使用します。
ライトの位置の設定は無視され、ライトの向きの設定のみが有効となります。(ライトのInspectorに表示されるTransformでは、Positionはどのような値を入力しても無視され、Rotationの値のみが有効となります)

2.Point Light
空間内のある地点から縦横360度の全方向に光を照射するライトです。距離に応じて強さが減衰します。
ライトの位置の設定のみが有効となり、ライトの向きの設定は無視されます。(ライトのInspectorに表示されるTransformでは、Positionの値のみが有効となり、Rotationの値はどのような値を入力しても無視されます)

3.Spotlight
空間内のある地点を頂点とする円錐状の範囲に光を照射するライトです。車のヘッドライトと同様です。


また、ライトは複数個設置できます。(例:Directional Lightをバックグラウンド用の基本ライトとして使用し、それに加えて、キャラクターのそばでPoint Lightを使用)
しかし、AutoLuminousの発光等も加わりますので、特殊な演出を行う場合以外は、Directional Light1個で十分です。



例えば、夕日を描いたスカイドームを遠景として使用する場合、以下の1~7の手順でライトの設定を行ってください。

1.Scene内でマウスを右ドラッグしながらキーボードのAキーかDキーを押してライトの周りをぐるぐる回ってライトの向きを把握し、ライトの向きがスカイドームの夕日の光の向きと同じになるように、ライトのInspectorに表示されるTransformの下のRotationの数値を書き変えて調整。
2.その下のLightのTypeDirectionalに設定。
3.さらに下のColor色選択欄をクリック。
4.Colorダイアログが表示されたら、一番下のSwatchesに並んだパレットのうち一番右の二重囲みをクリック。(念のため、現在の色=デフォルトカラーを保存しておきます)
5.Colorダイアログの外周の色帯上にある○マークをドラッグして赤色の位置へ移動。
6.Scene内のオブジェクトの色を見ながら、Colorダイアログの内側の正方形上にある○マークを、上の辺に沿って左右に、または、右の辺に沿って上下に移動して、最終的なライトの色を決定する。(ちなみに、真っ白、真っ黒、グレー等の、RとGとBの値が全て同じ色にしたい場合は、○マークを左の辺に沿って上下に移動すればOKです)
7.さらに下のIntensityの数値でライトの明るさ(光の強さ)を決める。

ちなみに、スカイドームを遠景としてVR動画に使用する場合、スカイドームのInspectorに表示されるTransformScaleを3~10程度の大きな値に変え、ドーム壁の位置を無限遠方に近づけた方が、表示の違和感が少なくなります。

3.半透明化

レースのカーテンや服の一部等を透けさせたい(半透明化したい)場合、以下のように半透明シェーダーを作成し、半透明化する部分にセットされたMaterialのシェーダーをそのシェーダーに変更します。

1.Windows標準メモ帳で下のコードを貼り付けて適当な場所に保存し、ファイル名をMyTranslucentShader.shaderにリネームする。

Shader "Custom/MyTranslucentShader" {
  SubShader {
    Tags { "Queue" = "Transparent" }
    LOD 200

    CGPROGRAM
    #pragma surface surf Standard alpha:fade
    #pragma target 3.0

    struct Input {
      float2 uv_MainTex;
    };

    void surf (Input IN, inout SurfaceOutputStandard o) {
      o.Albedo = fixed4(1.0f, 1.0f, 1.0f, 1);
      o.Alpha = 0.6;
    }
    ENDCG
  }
  FallBack "Diffuse"
}

2.Windows標準エクスプローラから、MyTranslucentShader.shaderを、画面左下側のProjectパネルのAssetsフォルダの中にドラッグ・アンド・ドロップ。

3.画面左下側のProjectパネルで半透明するモデルのMaterialフォルダを開き、半透明化する部分にセットされたMaterialを選択して、画面右側のInspectorの一番上の方にあるShaderのドロップダウンリストでCustomMyTranslucentShaderを選択。

※コード中のo.Albedo前3つの数値でRGB色を指定します。(例えば、1.0f, 1.0f, 1.0f, 1なら白、1.0f, 0.0f, 0.0f, 1なら赤、0.0f, 1.0f, 0.0f, 1なら緑、0.0f, 0.0f, 1.0f, 1なら青、1.0f, 1.0f, 0.0f, 1なら黄等、フルカラーで自由に指定できます)
※コード中のo.Alphaで透過率を指定します。(最大1.0、最小0.0で、値が小さいほど透過率が高くなります)
※コード中の数値を書き換えたときは、いったんProjectパネルから削除した後、Windows標準エクスプローラから再びドラッグ・アンド・ドロップし直してください。



ちなみに、Standard ShaderのRendering ModeのTransparentやFadeは、テクスチャのうちアルファブレンディングで透明化処理した部分のみを透過させるもので、ガラス等の元々透明なオブジェクトとして設計されたものしか透明化できません。一方、上のシェーダーは、どんなものでも透明化できます。

4.リアルな水面

海や湖等の水面を専用のシェーダーで作ると、リアルな水面の揺れ、水面の反射、水中の屈折等を表現できます。

1.まず、Standard Assetsをインポートします。
Standard Assets(非公式アーカイブ) を解凍し、Unity起動中にWindows標準エクスプローラからダブルクリックして起動します。
次に、~.cs等が上下に並んだリストが表示されたら、リスト右下のImportボタンをクリックすれば、インポート完了です。

2.画面左下側のProjectパネルのAssetsフォルダの下のStandard AssetsEnvironmentWaterWaterPrefabsを開き、WaterProDaytime.prefabWaterProNighttime.prefabを選択してキーボードのCtrl+Dを押して、prefabファイルを複製してください。

3.複製されたprefabファイル(WaterPro~ 1.prefabという名前のファイル)を、画面左上側のHierarchyのSampleSceneフォルダの中にドラッグ・アンド・ドロップします。

4.水面を囲む地面等に水面オブジェクトの端が隠れるように、水面オブジェクトの位置と半径を調整します。
画面左上側のHierarchyのWaterPro~ 1を選択して、画面右側のInspectorに表示されたTransformの下のPositionのX、Y、Zで水面オブジェクトの位置を設定してください。(Xが左右、Yが上下、Zが前後)
また、Positionの下のScaleのXとZの数値で水面オブジェクトの半径を設定してください。

※水面オブジェクトが円形になっているせいで端がどうしてもはみ出てしまう場合は、WaterPro~ 1のInspectorのWater Plane Meshに適切な形状のメッシュを指定すればOKです。

5.リアルな川

上ではリアルな水面を作成しましたが、今度は、水面が波打ちながら一方向に流れるシェーダーを使って、川をフォトリアル化します。(上とは全く別の新しいシェーダーをゼロから作成して使用します)

1.Unityシェーダーチュートリアル  水流を作ってみる - Tsumiki Tech Times|積木製作のページ中の上から1/3辺りに掲載されている4枚の正方形の画像(「◇屈折」に青紫2枚、「◇ディスプレイス」に白黒2枚)を名前を付けて保存。

2.Windows標準エクスプローラから、保存した4枚の画像(shader-tutorial-water-normal12.jpgshader-tutorial-water-height12.jpg)を、画面左下側のProjectパネルのAssetsフォルダの中にドラッグ・アンド・ドロップ。

3.Windows標準メモ帳で下のコードを貼り付けて適当な場所に保存し、ファイル名をMyRiverShader.shaderにリネームする。

Shader "Custom/MyRiverShader" {
  Properties {
    _WaveTex1 ("Wave Tex 1" , 2D ) = "bump" {}
    _WaveTex2 ("Wave Tex 2" , 2D ) = "bump" {}
    _WaveTex1H ("Wave Tex 1H" , 2D ) = "white" {}
    _WaveTex2H ("Wave Tex 2H" , 2D ) = "white" {}
    _WaveTiling ("Wave Tiling" , Vector ) = (0, 0, 0, 0)
    _Color ("Color" , Color ) = (1, 1, 1, 1)
    _Glossiness ("Smoothness" , Range(0, 1)) = 0.5
    _FlowSpeed ("Flow Speed" , Vector ) = (0, 0, 0, 0)
    _Refraction ("Refraction" , Vector ) = (0, 0, 0, 0)
    _Displace ("Displace" , Vector ) = (0, 0, 0, 0)
    _EdgeLength ("Edge length" , Range(3,50)) = 10
  }

  SubShader {
    Tags {
      "Queue" = "Transparent"
      "RenderType" = "Transparent"
    }

    GrabPass {}

    CGPROGRAM
      #pragma target 5.0
      #pragma surface surf Standard vertex:disp tessellate:tessEdge
      #include "Tessellation.cginc"

      sampler2D _GrabTexture;
      sampler2D _WaveTex1;
      sampler2D _WaveTex2;
      sampler2D _WaveTex1H;
      sampler2D _WaveTex2H;
      half4 _WaveTiling;
      fixed3 _Color;
      half _Glossiness;
      half4 _FlowSpeed;
      half4 _Refraction;
      half4 _Displace;
      half _EdgeLength;

      struct appdata {
        float4 vertex : POSITION;
        float4 tangent : TANGENT;
        float3 normal : NORMAL;
        float4 color : COLOR;
        float2 texcoord : TEXCOORD0;
        float2 texcoord1 : TEXCOORD1;
        float2 texcoord2 : TEXCOORD2;
      };

      float4 tessEdge (appdata v0, appdata v1, appdata v2) {
        return UnityEdgeLengthBasedTessCull (v0.vertex, v1.vertex, v2.vertex, _EdgeLength, 1.5f);
      }

      void disp (inout appdata v) {
        fixed waveTex1 = tex2Dlod(_WaveTex1H, float4(v.texcoord.xy * _WaveTiling.x + float2(0, _Time.x * _FlowSpeed.x), 0, 0)).a * _Displace.x;
        fixed waveTex2 = tex2Dlod(_WaveTex2H, float4(v.texcoord.xy * _WaveTiling.y + float2(0, _Time.x * _FlowSpeed.y), 0, 0)).a * _Displace.y;
        fixed displace = waveTex1 + waveTex2;

        v.vertex.xyz += v.normal * displace;
      }

      struct Input {
        float2 uv_WaveTex1;
        float4 screenPos;
      };

      void surf (Input IN, inout SurfaceOutputStandard o) {
        fixed4 waveTex1 = tex2D(_WaveTex1, IN.uv_WaveTex1 * _WaveTiling.x + float2(0, _Time.x * _FlowSpeed.x));
        fixed4 waveTex2 = tex2D(_WaveTex2, IN.uv_WaveTex1 * _WaveTiling.y + float2(0, _Time.x * _FlowSpeed.x));

        fixed3 normal1 = UnpackNormal(waveTex1);
        fixed3 normal2 = UnpackNormal(waveTex2);
        fixed3 normal = BlendNormals(normal1, normal2);

        fixed3 distortion1 = UnpackScaleNormal(waveTex1, _Refraction.x);
        fixed3 distortion2 = UnpackScaleNormal(waveTex2, _Refraction.y);
        fixed2 distortion = BlendNormals(distortion1, distortion2).rg;


        half2 grabUV = (IN.screenPos.xy / IN.screenPos.w) * float2(1, -1) + float2(0, 1);
        half3 grab = tex2D(_GrabTexture, grabUV + distortion).rgb * _Color;


        o.Albedo = fixed3(0, 0, 0);
        o.Emission = grab;
        o.Metallic = 0;
        o.Smoothness = _Glossiness;
        o.Normal = normal;
        o.Alpha = 1;
      }
    ENDCG
  }

  FallBack "Transparent/Diffuse"
}

4.Windows標準エクスプローラから、MyRiverShader.shaderを、画面左下側のProjectパネルのAssetsフォルダの中にドラッグ・アンド・ドロップ。

5.画面左下側のProjectパネルで川を含むモデルのMaterialフォルダを開き、川の部分にセットされたMaterialを選択して、画面右側のInspectorの一番上の方にあるShaderのドロップダウンリストでCustomMyRiverShaderを選択。
※既製の川のモデルを使用せず新しく自分で作成する場合は、Hierarchyで右クリックして3D ObjectPlane等を選択し、さらに、ProjectパネルのAssetsで右クリックしてCreateMaterialを選択して、作成したMaterialをPlaneにドラッグ・アンドドロップして代わりに使用すればOKです。

6.川の部分にセットされたMaterialのInspectorに表示された設定画面に、以下のように入力。
Wave Tex 1
 Tiling: X1 Y1
 Offset: X0 Y0

Wave Tex 2
 Tiling: X1 Y1
 Offset: X0 Y0

Wave Tex 1H
 Tiling: X1 Y1
 Offset: X0 Y0

Wave Tex 2H
 Tiling: X1 Y1
 Offset: X0 Y0

Wave Tiling: X6 Y12 Z0 W0
Color: 白
Smoothness: 1
Flow Speed: X4 Y12 Z0 W0
Refraction: X0.1 Y0.015 Z0 W0
Displace: X0.05 Y0.15 Z0 W0
Edge length: 3

また、右上側に4つ縦に並んだ大きめの正方形欄に、画面左下側のProjectパネルのAssetsフォルダから、上から順にshader-tutorial-water-normal1.jpgshader-tutorial-water-normal2.jpgshader-tutorial-water-height1.jpgshader-tutorial-water-height2.jpgをドラッグ・アンド・ドロップ。
※右上の南京錠のアイコンをクリックして画面をロックした方が、操作が楽です。(終わったら、必ず、再び南京錠のアイコンをクリックして、ロックを解除しておいてください)

もし川の流れの向きが逆だったら、川を含むモデルのInspectorに表示された設定画面のWave Tilingを、
Wave Tiling: X-6 Y-12 Z0 W0
に書き換えてください。
また、もし川の流れの向きが90度傾いていたら、4枚のテクスチャをそれぞれペイントソフト等で開いて90度回転して書き換えて保存し、川を含むモデルのInspectorに表示された設定画面のFlow Speedを、
Flow Speed: X12 Y4 Z0 W0
に書き換えてください。

6.pmdファイルやxファイルのMMDモデルを使用する

インターネットで配布されているキャラクターやステージのMMDモデルの中に、pmxファイルではなく、pmdファイル(.pmd)やxファイル(.x)になっているものがありますが、PMXエディタを使用してpmxファイルに変換すれば、Unity+MMD4Mecanimで読み込むことができます。

1.モーションの破綻の修正5.PMXエディタのインストールとボーン構成の把握でインストールしたPMXエディタを起動。
2.Pmx編集ウィンドウのメインメニューのファイル開くから、pmdファイルやxファイルを読み込む。
3.Pmx編集ウィンドウのメインメニューのファイル名前を付けて保存から、pmx形式で保存。
4.通常通りに、Unity+MMD4Mecanimに読み込む。

※xファイルでは頂点、面、材質の3つしか扱わないため、キャラクターのxファイルをpmxファイルに変換する場合は、PMXEでxアクセサリーをpmx化 - Togetter等を参考に、ボーンやウェイトを追加する必要があります。

7.MMD4Mecanimで読み込めないモーションファイルのキーフレーム削減

物理演算を焼き込んだり、MMDMotionFilter_MMM_plugin等のツールを使用した場合、キーフレームが全打ちされ、モーションデータのサイズが非常に大きくなります。(100MB以上)
モーションデータのサイズが大き過ぎると、MMD4Mecanimで読み込めません。記録されているキーフレームの数が上限(約139万個までは動作確認済みなので、それより上)を超えると、fbxファイルへの変換中にコマンドプロンプトにエラーが一瞬出て、fbxファイルが生成されずに終了してしまいます。

この場合、ベジェ補間を利用してモーションのピークを壊さずにキーフレーム数を削減する機能を持つMMM用プラグイン「さくさくMMM」を使用してキーフレーム数を削減すれば、MMD4Mecanimで読み込めるようになります。


A.さくさくMMMのインストール
みなみむきのMMD用ツール紹介/サポート:みなみむきの部屋 - ブロマガのページ上方の

>(2016/04/01) Kinect用ではなく、
>ねじれ緩和機能やノイズ削減機能、補間曲線推定を省いたMMM用の
>プラグインも作成しました。
>さくさくMMM
>ダウンロード:

のリンクから、さくさくMMM.zipをダウンロードしてください。

次に、ダウンロードしたzipファイルを解凍する前に、Windows標準エクスプローラでzipファイルのプロパティを開き、一番下にあるブロックの解除をクリックします。
これを行わなければ、起動時にエラーが出てさくさくMMMを起動できませんので、注意してください。

ブロックを解除したらzipファイルを解凍して、さくさくMMM090.dllを、MMMをインストールしたフォルダの下にあるPluginsフォルダにコピーしておきます。(例:MikuMikuMoving64_v1292\Plugins\さくさくMMM090.dllとなるようにコピー)
次に、MMMを起動してください。

エラー表示なしで起動することが確認できたら、いったんMMMを終了させておいてください。


B.モーションファイルの分割
解消法Dの詳細な解説1235と同じ手順で、モーションファイルを、さくさくMMMが処理可能な上限である30万キーフレームごとに分割してください。


C.さくさくMMMの適用
以下の手順で、それぞれの分割ファイルに対してさくさくMMMを使用して、「キーフレームが全打ちされたボーン」のキーフレームを間引きます。

1.MMMを再起動し、画面左側のタイムラインのフレーム番号が0になっていることを確認してから、解消法Dの詳細な解説1~2と同じ手順で、キャラクターのpmxファイルと、1つ目の分割モーションファイルを読み込む。

2.解消法Aの詳細な解説3と同様の操作で、「キーフレームが全打ちされたボーン」を選択。
※1ボーン当り1~2分の処理時間がかかります。例えば、髪ボーン45個+袖ボーン15個で計60個のボーンを選択した場合、処理完了まで1~2時間必要です。

3.画面左側のタイムラインの下側(スクロールバーのすぐ下)にある横に2つ並んだ数字入力欄に、0-50000(右側の数値は、最後にキーフレームが打たれたフレーム番号よりも大きな数を適当に入力してください)と入力し、そのすぐ右のチェックマークボタンをクリック。
※入力フレーム範囲がキーフレームが打たれた範囲より広い場合、自動的にキーフレームが打たれた範囲だけが選択された状態になるので、適当に大きな数を入力した方が楽です。

4.メインメニューのプラグインをクリックし、コマンドカテゴリにあるキーフレ 削減ボタンをクリック。
さくさくMMMダイアログが表示されたら、
回転許容量:1.0
位置許容量:1.0
と入力して、実行をクリックし、処理完了まで待ちます。
※許容量が大きくなるほどキーフレームの数を減らせますが、モーションのブレが大きくなります。できる限りモーションのブレを抑えたい場合は、両方0.1に設定してください。

処理が終わってもメッセージボックス等は表示されませんが、MMMのユーザーインターフェースが再び動くようになれば(MMMのメインメニューやボタン等が反応するようになれば)、処理完了です。

5.処理が完了したら、メインメニューのファイルをクリックし、読み込み/保存カテゴリにあるモーション保存ボタンをクリックしてモーション保存ダイアログを開き、
出力ファイル:分かりやすい名前(削減済み_~.vmd等)
フォーマット種類:VMDファイルを選択+レイヤ統合のチェックを外す
出力設定:全てのキーフレームを選択
ダイアログ下側のボーン一覧画面:1つ目の分割モーションファイルに含まれる全てのボーンにチェックを入れる ※上の例で言えば、その分割ファイルに含まれる41個全てのボーンにチェックを入れてください。時間がなくて一部のボーンしか処理しない場合も同様です。
と入力して別名保存。

6.1つ目の分割モーションファイルが終わったら、2つ目以降の分割モーションファイルについても、上記と同様にさくさくMMMを適用していく。


D.モーションファイルの再統合
全ての分割モーションファイルにさくさくMMMを適用し終わったら、解消法Dの詳細な解説7と同じ手順で、MMMを使用して、さくさくMMM適用済み分割モーションファイルを再び1つのモーションファイルに統合してください。
これで、キーフレームの間引きは完了です。


E.モーションファイルに含まれる総キーフレーム数の確認
以下の手順で、モーションファイルに含まれる総キーフレーム数を確認することができます。(目安として、100万程度まで削れば、確実にMMD4Mecanimで読み込めます)

1.確実なモーション修正2.VMDファイルエディタのインストールでインストールしたVMDファイルエディタを起動。

2.VMDファイルエディタのメインメニューのファイル開くから、モーションファイル(vmdファイル)を読み込む。

3.VMDファイルエディタのメインメニューの表示ファイルのプロパティをクリックすると、プロパティというダイアログが表示されるので、その中のモーションの数値を確認する。(これが、そのモーションファイルに含まれる総キーフレーム数です)

参考:

MMDモデルの基本構成 +α「モーフ」 | 解凍って何?からのMMD挑戦日記
2-1|ディレクションライト作成
【Unityシェーダ入門】透明なシェーダを作る - おもちゃラボ
< Unity >透過処理した画像について - なんでもログ
【Unity】水面の表現を無料で簡単に作る - おもちゃラボ
Unityで湖や海を作成する | Unityを使った3Dゲームの作り方(かめくめ)
Unityシェーダーチュートリアル  水流を作ってみる - Tsumiki Tech Times|積木製作
Xファイル編集にPMXEditorを使う(仮) - KantanBay BVE Memo
PMXEでxアクセサリーをpmx化 - Togetter