お布団宇宙ねこ

にゃーん

バ美肉ライブをしたよ

先日、会社のイベントで3Dモデルを利用したライブ配信バ美肉ライブを行いました。

youtu.be

バ美肉とは

バ美肉とは、「バーチャル美少女受肉」あるいは「バーチャル美少女セルフ受肉」の略である。バーチャル美少女として受肉することを指す。

バ美肉とは (バビニクとは) [単語記事] - ニコニコ大百科

私のバ美肉についてはこちらの記事に書きました。

ku00.hatenablog.com

事の発端

これに乗ってくれた方がいたので、やること何も決めてないけれどやるぞ!ということになりました。勢いしかない。

ちなみにこれをやると決めた当初は会社のイベントに合わせてやる予定はなかったのですが、できたら絶対に面白いだろうなあと思ったので間に合わせました。イベントの10日前の出来事でした。

VR開発合宿は難しい..?

このツイートをした当初はどこかのVRプラットフォームに入ってその空間に集まってプログラミングやモデリングなどの作業をやる開発合宿のようなものを想定していたのですが、以下のような問題から難しいねという話になりました。

  • 各々の環境によって入れるVRプラットフォームが制限される
  • HMDを着けながらの作業は難しい

VRChatやclusterなどVRプラットフォームはいくつかありますが、対応するHMDやOSがまちまちなため、各自が持っている機器によってはVRでの参加ができないことがあります。 今回の場合は自分はVIVE Proを持っていて、先方はOculus Goでしたので、そもそもPC対応のみのプラットフォームは使えないねという話になりました。

また、そもそもHMD着けながら作業は無理があるというのも、VR空間上でのキーボード操作のしにくさや物理ディスプレイが見えないなどの問題からも明らかですね。 絵を描いたり、スライドを見せながらプレゼンをするなどの作業ならできるプラットフォームならいくつかありますが..。

肉体はそのままで作業する

リアルの肉体をバーチャルに置きながら開発作業をするのは難しいことがわかったので、肉体はそのままでできる方法がないか考えました。

結論、2D・3Dモデルをカメラでトラッキングさせて通話しながら作業するという方針になりました。 これならプラットフォームやHMDに依存せず、かつHMDによって作業が阻害される心配もありません。

参考までに私の好きなVTuber月ノ美兎さんの動画を載せておきますね。

youtu.be

バ美肉ライブを支える技術

できたもの

YouTubeから配信を見ている人からはこんな感じで見えています。

f:id:ku00:20180909191428p:plain

会社のイベント会場にいた人にはスクリーンを通して配信を見てもらう感じでした。

f:id:ku00:20180906195556j:plain

システム構成

以下の図のような感じのシステム構成で配信しました。

f:id:ku00:20180909191521p:plain

ポイントは以下の3つです。

  • 3Dモデルの制御は全て3teneを通して行っていること
  • リアル体の声を恋声を利用して変換していること
  • 配信映像の作成はOBSで行っていること

3tene(ミテネ)というアプリが画面上で3Dモデルを動かせてVRMにも対応しており、今回の条件にマッチしたので利用させていただきました。 ウェブカメラやマイクがあればそれぞれのデバイス入力をもとにトラッキングできるのが最高ですね。

次に恋声による女声への変換ですが、これは私のバーチャル体の世界観として取り入れたものではなく、あくまで実験的な試みでした。 恋声は用意されているプリセットの変換だけだとどうしてもボイスチェンジャー感が出てしまうので、事前にある程度のチューニングと調声をしました。しかし、当日のマイクの音量や声のコンディションによってだいぶ左右されてしまい個人的には満足のいく声にはならなかったと思っています。

最後に今回初めて動画配信をしたのですが、映像を作るのも配信するのもOBSがいい感じにやってくれるので助かりました。

映像の合成は基本的にシーン(画面レイヤーみたいなもの)の順序を決めてキャプチャして配置することと、3Dモデルのキャプチャはクロマキー合成を使ったことくらいです。配信を一緒にやる予定だった方がご多忙のため今回不参加になってしまったので、Discordなどによる画面共有はやりませんでした。

あとは、映像にのせる音声が恋声で変換した音になるように仮想オーディオ(VB-CABLEなど)を入れたり、変換後の音声にはノイズが混じってしまうのでOBSのノイズ抑制を入れたりマイクの最大音量を下げる代わりにゲインを上げたりして調整していました(結局ノイズがのってしまいましたが..)

感想・反省

勢いだけで決まった初配信で一人で喋ることができるのかわからなくて始める前は緊張で死にそうでしたがトラブルなくなんとか終えることができました。

受け手がどれだけいるのか、どんな反応をしているのかを見ることができず、技術カンファレンスのような登壇とはまた違った怖さがありましたが、会社のSlackチャンネルのコメントやYouTubeのチャット欄が大変励みになりました、皆さんありがとうございました! インターネットあたたかい..

一方でライブ配信することに集中しすぎて、会社のイベント会場のことをほとんど考慮できず申し訳なかったです。配信用のPCを会場にも用意して、Slackチャンネルやスレッドを立てて質問を募ったり、Discordで会場と中継したりなどコミュニケーションの取り方はいくらでもあったなと思いました。次回以降改善します。

書き切れないくらい感想・反省がありますが、会社の人に「かわいかった!」「自分も参加して女子会やりたい!」という反応をもらえただけで今回のライブ配信やってよかったなあと思ったのでした。

改めまして、スクリーンなどの会場の設営をしてくれた会社の方々、配信を見てくださった皆さま、本当にありがとうございました!!!

(見てない方はアーカイブ見てね)

VRoidの3Dモデルにリップシンクを覚えさせる

前回の目の瞬きに引き続き、今回はリップシンクを覚えさせます。

リップシンクとは

舞台、生放送などであらかじめ収録された音声入りの楽曲に対して歌っているように見せること。 『Wikipedia』より

要は口パクです。

これを覚えるとHMDやマイクから入力された音声と同期して3Dモデルが口パクをしてくれるようになります。

シェイプキーはこだわりがないなら作る必要はない

前回の目の瞬きを覚えさせたときに、VRoidはある程度シェイプキーを用意してくれることがわかったので今回もそれを使おうと思います。

ただ、用意されているものだけだと後述する必要なシェイプキーに一部合わない(足りない)ものがあり、完全なリップシンクとはちょっと違う感じになってしまったのでその点だけご注意ください。

VRChatにアップロードできるところまで準備する

具体的にはFBX形式にエクスポートしてVRC_Avatar Descriptorを追加するところまでです。詳細は以前ブログに書いたので参考までにどうぞ。

ku00.hatenablog.com

このコンポーネントを使います。

f:id:ku00:20180817022533p:plain

シェイプキーを割り当てる

VRC_Avatar Descriptorでリップシンクの設定ができます。

まずはLip Syncを[Viseme Blend Shape]に変更します。
次にFace Meshは[UMARenderer]を選択します。

あとは口の形に合わせてシェイプキーを割り当てるだけです。Viseme: 〇〇の項目がそれです。
各項目の説明についてはVRChat 日本語wikiを参照してください。 vrchatjp.playing.wiki

全ての項目を埋めるにはシェイプキーが足りないので、ある程度同じシェイプキーで埋めることになります。

自分の設定はこちらです

f:id:ku00:20180828233039p:plain

これで終わりです。こいつ..しゃべるぞ..!!

それでは~

バーチャルマーケットに行ってきたよ

http://v-market.work/

3Dアバター・3Dモデルの展示会『バーチャルマーケット』に参加してきました。

これの何がすごいかというとVRChatで開催されるため、出展物も展示会に行く私たち自身も全部バーチャル空間上で完結するということなんですよね。当然バーチャル空間なので、展示されている3Dアバターは自分で着て実際にどんな姿になるのか確認できますし、3Dモデルも触ることができます。今までBoothなどでよさそうなアバターを見つけても画像でしか確認することができず購入しづらいと思っていた人も解消されそうです。

自分もアバターの試着したり、スクショ撮ってたら一時間くらい余裕で経っていた..!

バーチャルの買い物楽しい! 未来が来てた!
西側を完全に失念していたのは内緒です。

以下スクショです(カメラの設定をミスったせいで自撮りはないです)

f:id:ku00:20180827230837j:plain f:id:ku00:20180827230937j:plain f:id:ku00:20180827230946j:plain f:id:ku00:20180827231036j:plain

会場の様子が気になる人は動く城のフィオさんのアーカイブ動画があるのでこちらをご覧ください。

youtu.be youtu.be

運営、出展者のみなさん、本当にお疲れさまでした!

VRoidの3Dモデルに目の瞬きを覚えさせる

VRoid製の3Dモデルは瞬きのやり方を知らないので今回はこれを覚えさせます。

瞬きの方法については検索すればいくらか情報が出てきますが、VRoidの場合は少し方法が異なります。

「シェイプキー」を作る必要はない

「シェイプキー」とはオブジェクトの形を記憶させておく機能のことです。「モーフ」とも呼ばれます。

人の3Dモデルを例に挙げると、真顔や笑顔などの表情やサムズアップのような手のジェスチャーをシェイプキーとしてよく作ります。このシェイプキーを使ってキーフレームで真顔から笑顔に、平手からサムズアップに変化させるようにアニメーションを作ることができます。

自作アバターを一から作る場合はBlender等で適宜シェイプキーを作る必要がありますが、VRoidの場合はデフォルトでいくつかシェイプキーが登録されているのでそれらを使ってある程度の表情などが出せるようになっています。

mtprince9 さんがVRoidで出力される表情のリストを貼ってくれているのでこちらを参考にしましょう。

この結論に辿り着くまでだいぶ時間がかかりました..。

FBX形式でエクスポートする

VRoidの3Dモデルのシェイプキーを利用するために、FBX形式でエクスポートするところまでやりましょう。一つ注意点としては、FBXでエクスポートする際のオプションで「Animated Skinned Mesh」にチェックを入れてエクスポートする必要があります。

FBX形式でのエクスポート方法については以下の記事で書いたので参考までにどうぞ。

ku00.hatenablog.com

FBXのエクスポートが完了してFBXファイルをHierarchyに追加したら、UMARendererを選択し[Inspector]->[Skinned Mesh Renderer]->[BlendShapes]が追加されていることを確認してください。

f:id:ku00:20180827000054p:plain

登録されているシェイプキーは0~100の値で調整できます。 試しに1つ値を変えてみるとこんな感じになります。

f:id:ku00:20180827000100p:plain f:id:ku00:20180827000104p:plain

瞬きのアニメーションを作る

瞬きに合うシェイプキーを探しましょう。 目を閉じる Face.M_F00_000_Fcl_EYE_Close が最適そうですね。

アニメーションの作り方については文章で説明するのが大変なので以下の動画を参考にしてください(本当に動画の方が分かりやすいので..!)

youtu.be

瞬きができるようになったらVRChatにアップロードしてみましょう。

目の瞬きがあるだけでも人間らしくなりますね。それでは。

VRoidの3DモデルでVRChatの世界に入ったよ

先日ようやくVRChatのアップロード制限が解除されたので、今回は前回の記事で作ったVRoidの3Dモデルを使ってVRChatの世界に入ろうと思います。

こちらの記事を参考にさせていただきました。ありがとうございました。
VRoidで作成したモデルをVRChatの世界に送り出す方法 - あたまのたいそう

下準備

事前に用意するものがいくつかあるので、まずは下準備からです。
順番に説明していきます。

  • 3Dモデルのポリゴン数を2万以内に収める
  • VRoidから作成した3DモデルをVRM形式でエクスポートする
  • 必要なソフトウェアやファイルを揃える

3Dモデルのポリゴン数を2万以内に収める

VRChatに持ち込める3Dモデルはポリゴン数が2万までと制限されているため、この閾値を超えないように3Dモデルを作っておく必要があります。VRoidでは意識せずにアバターを作っていると軽く閾値を超えてしまうため注意が必要です。

ポリゴン数を削減する方法については前回の記事で紹介しているのでここでは触れません。

また、Simplygonを利用してポリゴン数を削減できるようですが、自分の場合はこの方法ではうまくいかなかったのでやめました。(テクスチャが参照できないみたいなエラーが発生してしまった)

VRoidから作成した3DモデルをVRM形式でエクスポートする

ポリゴン数が閾値以下で収まったら、VRM形式でエクスポートしましょう。

VRoidの上部タブの [撮影・エクスポート] から左メニューの [エクスポート] を選択、エクスポートに必要なアバターの情報を入力して [エクスポート] を押下するだけです。

必要なソフトウェアやパッケージを揃える

最後の下準備として、今後の作業に必要なソフトウェアとパッケージを用意しましょう。必要なものは以下です。

Unityはダウンロード後にインストールまで行ってください。複数バージョンインストールするのでインストールするディレクトリをそれぞれ区別できるように変更してください。

https://docs.unity3d.com/jp/460/Manual/InstallingMultipleVersionsofUnity.html

Unity Packageはこの時点ではダウンロードのみでOKです。

Unityで2バージョン必要なのは、前者の 2.3f1 をVRM形式をFBX形式にコンバートするために利用し、後者の 5.6.3p1 をVRChatへアップロードするために利用するからです。

VRCSDKはVRChatにログインして、CONTENT CREATIONの [DOWNLOAD SDK] からダウンロードできます。

CubedsShadersはシェーダーなので必要のない人はスキップしてください。

以上で下準備は完了です。


やること

ここからようやく作業に入ります。やることは以下です。

  • VRM形式の3DモデルをFBX形式にコンバートする
  • VRChat用に3Dモデルを整える
  • VRChatにアップロードする

VRM形式の3DモデルをFBX形式にコンバートする

Unity 2.3f1を起動してプロジェクトを新規作成します。

作成できたらVRM形式のファイルを読み込めるようにするためにUniVRMをインポートします。

[Assets] -> [Import Package] -> [Custom Package] から、UniVRM-0.40.unitypackageを選択してください。

パッケージのインポートが終わったらVRMファイルを下の画像の枠線内にドラック&ドロップで渡すと読み込んでくれます。

f:id:ku00:20180816235634p:plain

読み込みが完了するとprefabファイルとそれに付属するテクスチャなどのディレクトリがプロジェクトのAssetsディレクトリ以下に作成されます。


次に読み込んだVRMファイルをFBX形式にコンバートします。

コンバートにはFBX ExporterというAsset Packageを利用します。
FBX ExporterはAsset Store経由でインポートすることができます。

真ん中の画面の上部タブから [Asset Store] を押下し、そこからストアにアクセスできます。

f:id:ku00:20180816235638p:plain

パッケージのインポートが完了したら、先ほど読み込んだVRMファイル、正確には.prefabという拡張子が付いているファイルを左側のHierarchyにドラック&ドロップします。

f:id:ku00:20180816235641p:plain

それができたら右クリックメニューから [Export To FBX] を選択します。

Export Optionsはデフォルトのままで [Export] を押下します。

エクスポートが完了するとAssetsディレクトリ以下に.fbxのファイルが作成されているはずです。

Unity 2.3f1の役目はここで終わりなので終了してください。

VRChat用に3Dモデルを整える

ここからはUnity 5.6.3p1を使います。

別バージョンのUnityなので、プロジェクトは先ほどのを使いまわすのではなく新規作成してください。

作成できたらコンバートのときと同じ要領で以下のパッケージをインポートします。

  • UniVRM
  • VRCSDK
  • CubedsShaders

インポートが完了したらVRMファイルとFBXファイルの順番でAssetsにドラック&ドロップします。なぜコンバートしたのにVRMファイルも一緒に読み込むのかというと、FBXファイルにはテクスチャの情報が付属しないためVRMのものを参照する必要があるからです。

その後、FBXファイルを左側の Hierarchy にドラック&ドロップすることで3Dモデルを整える準備が完了します。


まずHierarchyに追加したFBXの階層からUMARendererを選択します。

f:id:ku00:20180817012352p:plain

選択すると右側の [Inspector] にマテリアルの情報が出るので、ここから各マテリアルのシェーダーを CubedsShaders のに変更します。CubedsShaders にも種類があり自分は Flat Lit Toon にしました。

f:id:ku00:20180817012402p:plain

FBXファイルをインポートした時点ではマテリアルの一部が意図せず黒くなって表示されることがありますが、これは Rendering Mode を [Transparent] などに変更すると直ります。

f:id:ku00:20180817012417p:plain

なんかパンダみたいになる..

f:id:ku00:20180817012409p:plain

直った!

f:id:ku00:20180817012652p:plain


次はボーンの設定です。

Assets内のFBXファイルを選択し、右側の [Inspector] -> [Rig] の Animation Type を [Humanoid] に変更し、 [Apply] を押下します。

f:id:ku00:20180817022453p:plain

先ほどと同じく右側の [Inspector] -> [Rig] の Avatar Definition の [Configure] を押下します。

ボーン設定に遷移するので、Bodyを以下のように変更します。

  • Chest: [J_Bip_C_UpperChest]
  • UpperChest: [None]

f:id:ku00:20180817022506p:plain

変更したら [Apply] 、[Done] の順で押下したら完了です。 これでモデルデータが人型(Humanoid)として認識されます。


左側のHierarchyのモデルの [Inspector] から [Add Component] を押下して [Scripts] -> [VRCSDK2] -> [VRC Avatar Descriptor] を選択します。

[Inspector] に VRC_Avatar Descriptor が追加されるので、まずは Default Animation Set を [Famale] に変更します。

次に View Position を変更します。これはアバターを使用したときの利用者の目線を表しています。[Scene] の画面にグレー色の球体がデフォルトだとモデルの真上くらいに表示されるので、これを目と目の間にめり込むくらいの位置に調整します。

f:id:ku00:20180817022519p:plain

参考までに自分の設定はこちらになります。

f:id:ku00:20180817022533p:plain

VRC_Avatar Descriptorの詳細な設定についてはVRChat 日本wikiにも書かれているのでそちらも参考までに。

ここまでくればあとはVRChatにアップロードするだけです。

VRChatにアップロードする

まず先に上部メニューの [VRChatSDK] -> [Settings] からVRChatにログインします。

次に [VRChatSDK] -> [Show Build Control Panel] から [Build & Publish] を押下します。

処理が完了すると真ん中の画面にVRChatのアップロード画面が表示されるので、各項目を入力してから[Upload]ボタンを押下すれば完了です。

f:id:ku00:20180817024324p:plain

あとはVRChatを起動して設定画面の [AVATAR] にアップロードしたアバターが表示されていればOKです。

お疲れさまでした。

(目のハイライトが消えてしまったのであとで直す..)

VRoidで美少女アバターを作ったよ

vroid.pixiv.net

pixivからVRoid Studioという人型アバターの3Dモデルが簡単に作れるアプリケーションがリリースされましたね。

今回はVカツで作ったアバターをVRoidでも再現できるのかどうか試してみました。

結論から言うと作ることはできましたがVカツのようにパラメータのみをいじって完成!とはいかず、絵(イラスト)を描くのと同じような作業がいくつか必要になり慣れるまではちょっと大変かなという印象でした。

チュートリアルや操作説明などのドキュメントについてはベータ版ということもあってか整っていません(というよりもほぼ無いに等しい)。 また、VRoidハッシュタグで検索したりVRoidの公式TwitterのRTを覗いてみれば他の方のアバターがたくさん見られますが、ざっと探した感じだとドキュメントを補完するような情報は少なかったです。

なので自分が作るときに参考にしたものや使ったものなどをメモ程度に紹介します。

作ったアバターをVカツのと比較してみる

どんな感じのアバターができるのかをまず先に載せます。

Vカツのりたろうちゃんがこちら

今回作ったVRoidのりたろうちゃんはこちら

髪の色味・光具合とか目の大きさとか色々違うけどこれはこれでいいよね

作り方の雰囲気を掴むために動画を観る

公式でチュートリアル動画などがあればよかったのですが、無いので適当にYouTubeで検索しました。自分が参考にしたのはこの動画です。

VRoid Studioでレム(remu)作製 裏技公開の制作流れ VRoidStudio髪編集と顔編集のまとめ先行制作 - YouTube

VRoidを最初に開いたときにパッと見て操作方法がわからないという理由から触るのをちょっとためらってしまいました。

参考動画では目や髪の毛の描き方を中心とした作業の様子を映したものなので、この操作をするとこう変わるみたい直感的に理解できてよかったです。

ペンタブがあると描きやすい

マウスでも描けないことはないと思いますが、特に髪は手のブレが結構反映されてしまうのでペンタブがあると線が真っ直ぐ描けると思います。

筆圧についてはまだ対応してなかったと思います。

参考までに自分はWacomの『One by Wacom』を使っています。

store.wacom.jp

ポリゴン数を減らしたいときは髪の毛を調整するといい

こちらの方のツイートで言及されている通り、VRChatではアバターのポリゴン数が2万ポリと制限されているためそういったサービスで利用する場合は調整が必要になります。

自分は最終的にVRoidで作ったアバターをVRChatに持っていきたい気持ちがあったので同じような方法で調整しました。

調整前は約26000ポリでしたが、「滑らかさ」を前髪以外 40.0 から 15.0 に、「断面形状」をひし形から底なし三角形に変更することで約17000ポリまで下げることができました。

前髪の滑らかさを変更しなかったのは、滑らかさを削ると思いのほか粗さが目立ってしまったからです。

衣装はどう描けばいいんだ..

アイラインや衣装などをどうやって描くのかについてはよくわからないままでした。前者はモデルのプレビューを見ながら雰囲気で描けましたが、後者は雰囲気では描けそうになかったので諦めました(衣装の展開画像を見てもこれでどう描けと..)

f:id:ku00:20180815140630p:plain
衣装のテクスチャ画面

VRoidへのフィードバック

  • [既知] vroidファイルを読み直したときに発生する髪の毛が意図しない位置に吹っ飛ぶ不具合を早めに直してほしいです
    • 高さ調整とかでは修正が効かなくて結局描き直しました😢
  • 髪の毛の流れを調整するプレビュー側のガイド(?)のみのundoができるようになってほしい
    • ガイドが変になったと思って直そうにも直せないので(そしてやり直すために読み込み直しをして上の不具合にぶち当たるコンボがつらい)
  • 体型編集の身長調整で実身長の目安が出ると嬉しい

まとめ

冒頭にも書いた通りドキュメント不足による障壁は大きいですが、慣れてしまえばのは難しくないと思います。描き始めてからはそこまでつっかかることはなく完成させることができました。これは自分がVRoidを立ち上げたときのデフォルトのモデルから主に目と髪の毛のみを描き直すという方法を取れたことも大きな要因だと思っています。

ひとまず絵がほとんど描けない自分でもそれなりのクオリティの3Dモデルが作れるのでVRoidさん本当にありがとうございますという気持ちです。

皆さんもぜひ試してみてください。それではよいバーチャルライフを。

optparse-applicativeを使ってCUIツールを作る

Haskellで簡単でもいいから何かツール作りたいなあと思ってシュッと作れそうなCUIツールを作ったので、作るにあたって利用したライブラリoptparse-applicativeの紹介をします。

はじめに

今回CUIツールを作る上で基本となるオプションパーサの部分にライブラリを使いました(というよりそこにしか使いませんでした)。オプションパーサのライブラリはこちらを見つつ、その後optparse-applicativeoptparse-simpleoptparse-genericに絞って、最終的に一番ドキュメントの量が多くコードの読みやすかったoptparse-applicativeを使っています。optparse-genericもよかったのですがサブコマンドの書き方がよくわからなくて断念してしまいました。

オプションパーサのライブラリを使ってますが、実はオプションは一つも実装していないのでどちらかと言うとサブコマンドを実装したい人向けの記事になります。

実装例

コマンド部分は以下のように簡単に作れます。

module Main where

import Options.Applicative
import Data.Semigroup ((<>))

data Command
  = Hello name
  | Bye name msg
  deriving (Show)

parseHello :: Parser Command
parseHello = Hello <$> argument str (metavar "[NAME]")

parseBye :: Parser Command
parseBye = Bye
  <$> argument str (metavar "[NAME]")
  <*> argument str (metavar "[MESSAGE]")

withInfo :: Parser a -> String -> ParserInfo a
withInfo opts desc = info (helper <*> opts) $ progDesc desc

parseCommand :: Parser Command
parseCommand = subparser $
  command "hello" (parseHello `withInfo` "Say Hello") <>
  command "bye" (parseBye `withInfo` "Say Bye")

parseInfo :: ParserInfo Command
parseInfo = parseCommand `withInfo` "Greeting"

execCommand :: IO ()
execCommand = execParser parseInfo >>= run
  where run cmd = case cmd of
                    Hello n -> sayHello n
                    Bye n m -> sayBye n m

main :: IO ()
main = execCommand

まず、実装したいサブコマンドやオプションの型を定義してそれをParser型で包んだパーサ関数を定義します。ここではComannd型を定義してparseHelloparseByeを実装しています。このパーサ関数にはコマンドが受け取る引数やヘルプで表示したい情報などを設定できます。

次にそれらのパーサ関数をまとめるパーサを用意します。ここではparseCommandがそれにあたります。

あとはそれをexecParser関数に食わせることで入力された文字をいい感じにパースしてコマンドと引数に分解してくれます。

実行

デフォルトでヘルプオプションが付いてくるので、上のような実装だけでもいい感じのコマンドが作れてしまいます。

> stack runghc Main.hs -- --help
Usage: Main.hs COMMAND
  Greeting

Available options:
  -h,--help                Show this help text

Available commands:
  hello                    Say Hello
  bye                      Say Bye

> stack runghc Main.hs -- hello --help
Usage: Main.hs hello [NAME]
  Say Hello

Available options:
  -h,--help                Show this help text

まとめ

以上、optparse-applicativeを使うとお手軽にCUIツールを作れるのでした。
自分が実際に作ったものはこちらに置いてあります。

github.com

参考文献