セガのモーションキャプチャースタジオ紹介

はじめに

はじめまして。セガゲームスのモーションキャプチャーチームに所属している北川と申します。

業務内容としてはモーションキャプチャーエンジニアとしてワークフローの構築や収録オペレーターといったことをしています。(簡単にいうとモーションキャプチャーの撮影周り全般です)

モーションキャプチャーチーム内では、以下の三つの班に分かれて業務を行っています。

・撮影班:撮影~収録したマーカーデータの処理や小道具作成など

・エディット班:収録データのキャラクターへの流し込みと修正作業

・サポート班:上記の班をサポート

私はその中でも撮影班として収録業務を行っているので、今回はなかなか話をする機会のないセガのモーションキャプチャースタジオについてお話をさせていただきます。

 

 

セガモーションキャプチャースタジオとは

セガモーションキャプチャースタジオの歴史

セガは『バーチャファイター』(1993年発売)の開発時からと業界でもかなり早くモーションキャプチャーをゲーム開発に導入しました。

導入当初はモーションキャプチャーの専門チームとしては存在せず、2000年頃よりモーションキャプチャーチームとして部をまたがってプロジェクトをサポートするようになりました。

写真は過去のスタジオ写真の一部になります。スタジオも数回引っ越しをしていますし、使用しているシステムも様々な変化があります。

f:id:sgtech:20191127214712j:plain
f:id:sgtech:20191127214716j:plain
f:id:sgtech:20191127214705j:plain
f:id:sgtech:20191127214708j:plain
f:id:sgtech:20191127214722j:plain
f:id:sgtech:20191127214728j:plain

現在の所属はセガゲームスになりますが、セガ・インタラクティブ、アトラス、サミー、マーザ・アニメーションプラネットなどセガサミーグループの様々なプロジェクトに関わっています。

直近のタイトルでは以下のモーション収録に携わりました。

『龍が如く7 光と闇の行方』『東京2020オリンピック The Official Video Game』『新サクラ大戦』
『ファンタシースターオンライン2』『WCCF FOOTISTA』『Wonderland Wars』『けものフレンズ3』
『Fate/Grand Order Arcade』『艦これアーケード』『ペルソナ5 ザ・ロイヤル』『キャサリン・フルボディ』

  

スタジオスペック
  • カメラ:Vicon社 反射光学式カメラ 約100台          

    f:id:sgtech:20191127214815j:plain

  • 収録エリア:18m x 10m x 4m(横幅 x 奥行き x 高さ)
  • 常設設備:壁面鏡・ワイヤーアクション用設備・チェック用大型モニター

過去のモーションキャプチャーを利用するタイトルがバーチャファイターシリーズをはじめとした格闘アクションだった事もあり、『シェンムー』(1999年発売)制作の頃から立体的なアクションの要求に応えるためワイヤーアクション用の設備を設置しました。
現在のスタジオではワイヤーアクションの為に天井からのH鋼を二本に増やすだけでなく、床内にワイヤー用の専用フックも設置してより複雑なアクションがとれるようになっています。 

f:id:sgtech:20191127214737j:plain
f:id:sgtech:20191127214741j:plain
f:id:sgtech:20191127214638j:plain
f:id:sgtech:20191127214732j:plain

 

収録環境の工夫

リファレンス用のビデオ収録

反射光学式のモーションキャプチャーは収録しただけだとただの点データ(座標データ)になってしまいます。そうするとマーカーを付けていない部分の動きや表情などは収録することができません。

そのため、後作業で参考にするためにキャプチャー収録と同期をしてビデオを録画することが非常に有用になってきます。

昔はSD画質でも問題なかったのですが、指の表現や表情も撮影時のものを参考にすることが増えてきたことによってHD画質での録画の要望が高まってきました。しかし、要望の増え始めた頃はVicon社のキャプチャーシステムと同期してHDで録画するシステムは存在していない状況でした。

その話をモーションキャプチャーチームをサポートしてくれているプログラマーに話したところ、プログラマー同士の雑談から動画の処理に詳しい者がシステム作成に手を挙げてくれました。

そこからモーションキャプチャーチームの要望をヒアリングしたうえで、ハードの選定や録画・エンコードソフト、キャプチャーシステムとのリンク部分などを作成してくれました。

これによって国内でも非常に早い段階でHD画質でのリファレンス映像の収録環境を構築することができました。このシステムは今でも欠かすことのできないものとして運用されています。

社内のふとした繋がりによって当初想定していたより素早く期待以上の環境構築をすることができたと同時に、セガ社内の人材の厚さを実感しました。

f:id:sgtech:20191127214651j:plain
f:id:sgtech:20191127214655j:plain
f:id:sgtech:20191127214701j:plain
 リアルタイムプレビューのクオリティアップ

ビデオ収録でも触れましたが、収録したデータは座標情報のみとなり点と線の表示となってしまいます。そのため、MotionBuilderというソフトを同時に使用して確認用にキャラクターを動かす事が一般的です。
ただアクター(演者)さんとキャラクターとの体型の差などから不自然に動いてしまう場合も多々あり、エディット班では後処理を行う際にセガ独自のリターゲット方法を利用しており、アクターさんとキャラクターの動きの誤差を少なくすることで作業の軽減を図っています。

そこでエディット班とサポート班に協力をしてもらい、リアルタイムプレビューにも同様のリターゲットが行えるように改良を行っていきました。これによって収録をしている段階で動きの誤差が少なくなり、アクターさん・プロジェクトスタッフ双方のイメージの共有の齟齬が少なくなり再収録などのリスクも非常に低くなりました。

f:id:sgtech:20191127214646j:plain



指の収録

最近では指の動きを収録する事例なども多く見かけるようになりましたが、セガでは2010年頃からボディと一緒に簡易的な指のモーションの収録も行うようになりました。

それ以前は必要に応じてグローブデバイスを使うなどしたこともありますが課題も多く、指は収録後にビデオやイメージを基にプロジェクトのモーションデザイナーが手作業で動かすことがほとんどでした。その手法だと数をこなしたり、自然な動きを再現するのに非常に時間がかかってします。そこで収録時のアクターさんの動きを体と一緒に収録できれば指の自然な表現ができるのではと実装に向けて検証を始めました。

検証当初は5本の指全てにマーカーを付けての収録など様々なテストをしました。しかし出来上がるクオリティとデータクリーンアップ作業の工数を鑑みて、親指・人差し指・小指の3か所のみにマーカーを付け、その動きを基に5本の指を動かすようにしました。これによって手の開閉タイミングや細かい動きのニュアンスも収録できるようになり、プロジェクトからも好評で今ではすべての撮影で欠かせないものとなっています。

導入当初はリアルタイムプレビューでは満足に動かすことができず、撮影後のデータ処理の段階で初めて動く状況でしたが、改良を重ね現在ではリアルタイムプレビュー上でも動かせるようになっています。

末端の動きではありますが開閉や指差しなどだけでも表情のように印象が大きく変わるので、特にダンスやイベントシーンの収録時にイメージ共有がしやすくなりました。

f:id:sgtech:20191127214750j:plain



 

 

その他

小道具やセット

モーションキャプチャーの収録はカメラやソフトなどを見るととても複雑なシステムを使用しているように見えますが、実際の収録現場はアナログな作業が非常に多く存在しています。

生の動きであるアクターさんの動きをデジタルデータに変換するのがモーションキャプチャーです。なので、可能な限り演じやすく・ロスなくデータ化することが非常に重要になってきます。もちろんそのまま使用することはほとんどありませんが、だからこそその素材になる収録データはできる限りアクターさんの動きをしっかりと撮ることが最終的なクオリティにも貢献できると思っています。

収録しやすくなるように小道具やセットも可能な限りリクエストに応えられるように様々な準備を行います。演技しやすいように発泡スチロールや塩ビパイプなどを組み合わせて大きくても軽い小道具を作成したり、イメージに近くデータ収録に問題がないセットにするなど様々な工夫をして収録をしています。この部分は実際に現場で動きながら作業をするので、テクニカルなだけでなくADや大道具的な作業も行っています。

以下の画像はごく一部ですが、すべてチーム内のスタッフが作成したものです。よく見るとわかりますが、マーカーがついており小道具の動きも収録を行っています。収録したオブジェクトの動きもリアルタイムプレビュー上でしっかりと反映し武器などを構えた状態も確認できるようにしています。

 

f:id:sgtech:20191127214755j:plain
f:id:sgtech:20191127214800j:plain
様々な収録システム

モーションキャプチャーといっても様々なメーカーのいろいろな収録システムが存在します。セガのモーションキャプチャースタジオも当初から現在のViconのシステムではありませんでした。古くは磁気式といわれるものやVicon社以外のシステムを運用していました。

それらの経験は現在の収録にも活かされており、メインで使用しているシステムだけでなく他のシステムに関しても情報を収集したり撮影によっては他のシステムを運用したりしています。

例えばスタジオの広さが室内ではとても足りない場合や、収録をしたい環境(セットなど)を再現するのが困難な場合は持ち出して収録をすることができる慣性センサー式のシステム(Xsens MVN)を使用して収録を行ったりもしています。

また、映画製作で行われているパフォーマンスキャプチャーについても要望が高まっていることからフェイシャルキャプチャーやバーチャルカメラも同時に撮れる環境づくりを順次進めています。市販のものを購入するだけでなく、使い勝手を考え顔の動き・表情を収録するためのHMC(ヘッドマウントカメラ)や3DCG上のカメラを操作することができるバーチャルカメラを独自に作成もしています。

社内のスタジオとしてできるだけ多くの要望に応え、より良いものをプロジェクトに届けるべく様々な検証やサービスの展開を行っています。

f:id:sgtech:20191127214810j:plain
f:id:sgtech:20191127214805j:plain

 

 

最後に

今回はモーションキャプチャースタジオでの収録に関連した部分にスポットを当てて書いてきました。収録現場はPCでの作業もありますが、実際に自分が動いて対応をすることが多くあります。ビデオの収録やキャラを見ながらの確認などをしっかりと整備したことによって、イメージを共有しやすくしたり現場での撮影補助に集中することができるようになりました。動き回ることの多い現場だからこそ周辺のツールなどのありがたみを感じます。

f:id:sgtech:20191127214746j:plain



写真:撮影班一同

 

モーションキャプチャーチームでは一緒にプロジェクトを支えるメンバーを募集しています。

興味のある方はぜひサイトにアクセスしてみてください。

sega-games.co.jp

©SEGA

 

Unite Tokyo 2019 「大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~」講演と壇上では語られなかった6つのこと。

皆さんこんにちは。セガゲームス、開発技術部の山田です。 以前は OpenGL の話を本ブログで紹介したのですが、今回は Unite Tokyo で講演してきたお話です。 本記事は講演の時と同じく、前半は山田、後半は竹原でお送りします。

目次

Unite Tokyo 2019

Unityユーザーのためのテクニカルな講演やブース出展が数多く行われる、国内最大のUnityカンファレンスイベント「Unite Tokyo 2019」が 2019年9月25日、26日に開催されました。そこで、私と竹原より、「大量のアセットも怖くない~HTTP/2による高速な通信の実装例」という講演を行いました。 お越しいただいた方々ありがとうございました。

講演の結論は「Unityで標準的な作り方をした場合において、 HTTP/2を使ってアセットバンドルをダウンロードすることは相性がよいです」 と話しました。

f:id:sgtech:20191028000857j:plain

資料など

資料や講演ムービーは既に公開されており、次のページでアクセスできます。

learning.unity3d.jp

質疑中の様子

予想していたよりも多くの方に質疑コーナーに来て頂けまして、色々と質問や情報交換ができました。 とても有意義な時間でした。ありがとうございました。

f:id:sgtech:20191028000853j:plain

講演中に語られなかったこと

講演では説明できなかった色々なことを本ブログで補足したいと思います。

Keep Alive の話

Keep Alive を使った HTTP/1.1 なら HTTP/2 との速度差はそれほどつかないのでは?と思う方もいるでしょう。自分もそう考えていた時期があったので、この点に悩む方は多いのではないかと考えています。

前提として、https での通信を考えます。 Keep Alive で削減できるのは TCP の再接続のコストです。実際にデータを送受信するまでの前準備の部分です。

f:id:sgtech:20191028000903p:plain

HTTP/1.1 では、複数のコネクションを張って並列にデータのダウンロードを行う実装とします。 このとき多くの場合で3~6が使われることと思います。しかし、それぞれのコネクションで輻輳制御が行われるために、帯域を有効活用することができません。 これを分かりやすく説明してくれているのが 「IIJ Technical WEEK 2015」においての「HTTP/2からQUICへ続く Webプロトコルの進化」という講演内容です。

www.iij.ad.jp

「HTTP/2からQUICへ続く Webプロトコルの進化」という講演資料の19ページから21ページにて解説をされています。 次の図は、この資料より引用させていただきました。

f:id:sgtech:20191028000900p:plain

HTTP/1.1 ではファイルごとに1つのコネクションを使います。Unity での標準的な作りをする場合においてファイルサイズは小さめであり、1コネクションにおいて輻輳ウィンドウサイズが十分に大きい状態で通信を行い続けることができません。 HTTP/2 ではストリームの機能を用いて複数ファイルのダウンロードを1つのコネクションに多重化するため、使用できる帯域を最大限使うことができます。

RTTの観点からも HTTP/2 ほうが有利です。 HTTP/1.1 の場合、Keep-Alive で再接続のコストを抑えていても、ファイルを取得するときに出すリクエストで RTT 分の時間が掛かります。 この間は、そのコネクションにおいてファイルのダウンロードは進行していません。仮に 100 ファイルあったとすると 100 *0.5RTT の時間分はファイルのデータダウンロードに使えていないことになります。HTTP/2 では多重化により他のデータやりとりの1部としてファイルのリクエストも紛れ込んでいるので、通信路としての無駄が少なくなっています。

f:id:sgtech:20191028000906p:plain

ただし、どのような条件下でも HTTP/2 のほうが速いかというとそうでもないので状況に応じて考える必要があります。

必要なファイルを結合してアーカイブファイルを作成し、それをダウンロードするというフローであれば HTTP/1.1 でも効率の良い通信が実現できます。 Unite Tokyo 2019 の KLab さんの講演「「禍つヴァールハイト」最大100人同時プレイ!モバイルオンラインゲームの実装テクニック」の中でも語られておりました。 tar 形式と Range パラメータを使ってというアイデアはとても面白いと思います。 KLab さんの方式は事前に必要なデータをガッツリダウンロードするような MO/MMO のようなものに向いているのではないかと考えております。

learning.unity3d.jp

同時ファイルオープン数について

講演中では印象優先で Windows ではファイル数 512 という表現をさせてもらいました。 しかし、その制限は実は Windows そのものによる制限ではなく、 Visual C++ が提供している C Runtime (CRT) による制限となっています。 Windows 自体はもっと多くのハンドルを同時に扱うことができます。

fopen/fclose といった C言語の世界の関数が CRT に属します。 Windows で生のファイルを操作する場合は Win32API に属する CreateFile 関数を使用します。 Windows 専用ということもあって、ファイルの共有Read/Write, 256文字を超えるファイルパスによるアクセスなど色々とできることが多いです。

(Windows API (Win32API) や、Windows カーネルの話も機会があったら本ブログで書けたらと思います。)


講演で語られなかったこと (竹原より)

それではここからは竹原が担当させて頂きます。

私のパートでは HTTP/2 に関する仕様や libcurl の実装面でのもう少しディープな解説をさせて頂こうと思います。

HPACK の圧縮率を確認する

HTTP/1.1 までの通信では、HTTP ヘッダはプレーンテキスト形式で記述され、クッキー等により時にはその合計サイズは 1 キロバイトを超えることもありました。 HTTP/2 ではこうしたヘッダのサイズ問題を解消するべく HPACK という専用の圧縮機構が採用されています。

講演を聞いてこの HPACK で実際どれくらいヘッダが圧縮されるのか、気になった方もいると思います。

f:id:sgtech:20191024153931p:plain

そこで、この項では HPACK の仕組みを、「どれくらいヘッダサイズが削減されるか」についても触れながら簡単に解説してみます。 かなり効果があるので、独自拡張等ヘッダに色々仕込んでいる場合は導入を検討してみても面白いと思います。

[HPACK]HTTP/2 のヘッダ管理

講演でも触れたように、 HTTP/2 のヘッダはバイナリとして扱われるようになりました。 更にパラメータは 全て小文字で表現されるようになった のに加え、従来のリクエストラインやヘッダの表現形式も若干変更されています。

例えば、 HTTP/1.1 の典型的なリクエストラインとヘッダの組み合わせである以下は

GET /resource HTTP/1.1
Host: sega.com
Accept: text/html

HTTP/2 では次のような集合として表現されます。

:method = GET
:scheme = https
:path = /resource
host = sega.com
accept = text/html

HPACK ではこれらの Header Name/Value の組み合わせをヘッダフィールドと呼び、文字列で表すか、独自のインデックス値でエンコードして表すか選択することが可能です。 更に、文字列で表す場合は Huffman Coding(ハフマン符号) で圧縮するかどうかも選択することができます。

[HPACK]Huffman Coding での圧縮

Huffman Coding は、出現頻度の高い文字には短いビット列を割り当て、低い文字には長いビット列を割り当てることにより圧縮を図る方式です。

例えば、文字 A が 1 回、B が 3 回、C が 5 回、D が 2 回、E が 1 回出現するような文字列「ABBBCCCCCDDE」に対して以下のように符号を割り当てます。

f:id:sgtech:20191024154846p:plain

この割り当てられた符号を使って前述の文字列「ABBBCCCCCDDE」を表現すると、

1110 10 10 10 0 0 0 0 0 110 110 1111

となり、全体を 25bit で表現することができるようになりました。

実際の符号の割り当てには、圧縮したいデータ内の文字の出現頻度をベースにして構築した Huffman Tree という二分木を利用します。 Huffman Tree の構造はベースにしたデータ内の文字の出現頻度により変化するので、適用したいデータのパターン毎に用意する必要があります。 そこで、 HPACK では過去に利用された HTTP のリクエスト・レスポンスのヘッダを解析した結果を基にして構築した専用の Huffman Tree が採用されています。

RFC 7541 - HPACK: Header Compression for HTTP/2

それでは、Huffman Coding でどの程度のデータの圧縮が可能なのか、先ほどのヘッダフィールドの内容を例に確認してみましょう。

まずは :method を Huffman Coding してみると

":method"  1011100 101001 00101 01001 100111 00111 100100
"GET"  1100010 1100000 1101111

となるので、これを合算して 61bit に圧縮できることがわかります。
※ヘッダフィールドは Name/Value でそれぞれ管理されるので "=" は不要となります

HPACK では Huffman Coding されたデータがオクテット単位に揃わない場合、余ったデータ部は 1 でパディングされるというルールがあるので実際には

":method"  1011100 101001 00101 01001 100111 00111 100100
"GET"  1100010 1100000 1101111 {111}

となり、 64bit(8byte) のデータ長となります。

元々の文字列は ":method" → 7byte, "GET" → 3byte で 10byte ですので、 20% 圧縮されたことが分かります。
※ HTTP/3 に使われている QPACK では、このパディングが不要となり、さらに圧縮率が上がっています!

このように、 Huffman Coding を用いると、頻出文字で構成されるデータであれば大幅にデータを圧縮可能です。 上記よりもう少し頻出文字が多い文字列だと 30% を超える圧縮率になることもあります。 反面、バックスラッシュ(19bit)やアンダースコア(15bit)といった出現頻度の低い文字については、元の8bitより遙かに大きくなってしまうので注意が必要です。 実装によっては、 Huffman Coding を掛けた前後のサイズを比較し小さい方を採用する、というような工夫もしているものもあるようです。

[HPACK]インデックス値を用いた圧縮 : Static Table

HPACK には Huffman Coding の他にも、Header Name と Header Value を対応させた辞書である Indexing Table という独自の圧縮機構が用意されています。 Indexing Table には Static Table と Dynamic Table の二種類が存在しています。

Static Table は Huffman Tree のように過去の利用頻度の高いヘッダが予め登録されているテーブルで、HTTP/2 の RFC に全 61 種類が定義されています。

RFC 7541 - HPACK: Header Compression for HTTP/2

先ほど例に挙げたヘッダを上記の RFC の Static Table で表現しようとすると

:method → 2
:scheme → 7
:path → 4
host → 38
accept → 19

と対応していますので、以下のように表現できるようになります。

 2
 7
 4 /resource
38 sega.com
19 text/html

※インデックスは 1byte で扱われます

結果、 63byte → 31byte となり、約 51% 削減という Huffman Coding を大幅に超えた値で圧縮することができました。

※実際には Literal Header Field という独自の形式でヘッダフィールドを表現する為に、圧縮率はこの値より少し小さくなります。詳細は RFC 7541 - HPACK: Header Compression for HTTP/2 を参照ください

更にテーブルを適用できなかった文字列部には Huffman Coding を掛けてさらにデータを圧縮することも可能です。

[HPACK]インデックス値を用いた圧縮 : Dynamic Table

Dynamic Table は、通信に使用したヘッダフィールドを動的にテーブルに登録していき、 Static Table のようにインデックス値で指定できるようにする圧縮機構です。 テーブルへの登録可能な上限サイズの初期値は 4096 オクテットで、上限を超えた場合はファー ストインファーストアウトのルールで登録が抹消されていきます。 Dynamic Table のインデックスは Static Table のインデックスの続きの 62 から始まり、追加する毎にインクリメントされていきます。

先ほどの Static Table で表現したヘッダフィールドをさらに Dynamic Table に登録してみましょう。

 2 → 2 のまま
 7 → 7 のまま
 4 /resource → 新規に 63 に登録
38 sega.com → 新規に 64 に登録
19 text/html → 新規に 65 に登録

すると、以下のようにかなりすっきりとした形で表現できるようになります。

 2
 7
62
63
64

結果、 63byte → 5byte となり、圧縮率は驚異の約 92% まで上がりました。

Dynamic Table のサイズは前述した通り 4096 オクテット(変更は可能です)なので、なんでもかんでも登録するわけにはいきません。 しかし、同じヘッダのリクエストを何度も送信する場合にはかなりの効果をあげますので、こうした事例では Dynamic Table を積極的に利用するのをお勧めします。

[HPACK]まとめ

若干長くなってしまいましたが、 HPACK を利用すると大幅にヘッダを圧縮することができることを理解して頂けたと思います。

最近のゲームは API リクエストをかなり頻繁に送信するものや独自にヘッダを拡張しているケースも多く、これらの積み重ねによって結構なデータ送信量になってしまうこともあります。 こうしたデータを削減するにも HTTP/2 はかなり効果的です。

アセットのダウンロードだけでなく API 通信にも HTTP/2 をお勧めします


HTTP/2 特有の設定を libcurl から行うには?

HPACK の高い圧縮率を見ると使ってみたくなるのはプログラマの性ですよね。

それでは libcurl から HPACK はどのように操作できるのでしょうか。……と期待を煽っておいて申し訳ありませんが、実は libcurl を用いた場合は HPACK についてのパラメータを変更することはできません

libcurl が依存している nghttp2 という OSS のレイヤーで「Huffman Coding」及び「Static/Dynamic Table」の利用については以下のようにそれぞれよろしくやってくれます。

  • Huffman Coding エンコード実施後、元の値より小さい場合のみ適用されます。
  • Static Table 自動的に適用されます。
  • Dynamic Table 特定の条件を満たすもののみ登録されます。

Dynamic Table への登録条件は以下の通りです。

/* Don't index authorization header field since it may contain low
     entropy secret data (e.g., id/password).  Also cookie header
     field with less than 20 bytes value is also never indexed.  This
     is the same criteria used in Firefox codebase. */

※ nghttp2 のソースコードコメントより

要約すると、

  • id や password, authorization 等のセキュリティ上問題になるようなヘッダーフィールドはインデックス化しない
  • 20 byte 未満の Cookie ヘッダーフィールドはインデックス化しない
  • これらは Firefox で使用されている基準と同じである

という内容です。

この基準以外で Dynamic Table を利用したい場合は、 nghttp2 に用意されている HPACK API を利用すると良いでしょう。

Tutorial: HPACK API — nghttp2 1.40.0-DEV documentation

※筆者も libcurl との併用が可能かどうか等については未検証です

また、 libcurl から制御できない HTTP/2 のパラメータは、実は HPACK だけではなく他にもいくつかあります。

例えば、

  • クライアントが指定する「最大ストリーム数の設定」 : SETTINGS_MAX_CONCURRENT_STREAMS
  • Dynamic Table の最大サイズ : SETTINGS_HEADER_TABLE_SIZE
  • ストリームの初期ウィンドウサイズ : SETTINGS_INITIAL_WINDOW_SIZE

等はすべて libcurl 内で隠蔽されています。

この辺りの HTTP/2 独自のパラメータを細かく制御したい人は nghttp2 をそのまま使うのをお勧めします。 ただし、 libcurl はクッキーの制御や HTTP/1 系への対応等、実装に手間のかかる所をケアしてくれています。 HTTP/2 のパラメータをどこまで制御したいか、プロジェクトの都合に合わせてどちらを使うか決めるのが良いと思います。


優先度制御の現在とこれから

講演中で HTTP/2 の優先度については仕様が見直し中、という話をさせて頂きました。

それでは、具体的にどのような仕様に見直し中なのか、少し補足しようと思います。

まず、三行でまとめると以下の通りです。

  • 優先度は現在 HTTP バージョンに紐づかない 仕様として現在審議中です
  • 従来の HTTP/2 の優先度に関しては 優先度制御しない 機能が追加予定です
  • 現在策定中の HTTP/3 では、優先度の機能を持たないことに決まりました

これだけではつまらないので、新しく提案されている優先度がどのようなものなのかについても軽く説明しようと思います。

※あくまで議論中の仕様なので今後変更される可能性があります

新しく提案された優先度はとてもシンプルです。

まず、Stream Weight は urgency level (緊急度) に置き換わり、全 8 段階へと縮小されました。

f:id:sgtech:20191024155737p:plain

※ここで言う「ファイルダウンロード」とはブラウザ経由での大きなサイズのファイルのダウンロードなどを指します

その他の変更点や特徴は以下の通りです。

  • 制御は HTTP ヘッダで行います
  • ヘッダで設定した値をさらに変更したい場合は HTTP/2,3 共に Priority フレームを利用する方向で話が進んでいるようです
  • クライアントからの urgency はあくまで hint であり、サーバ側の都合で urgency の値を上書き可能なようです
  • progressive jpeg 等のリソースの識別用のフラグも用意されます
  • HTTP/2 との優先度の互換性についてはこれから検討するようです

新しい優先度は基本的には web ページを基準に議論が進んでいる仕様のようですが、ゲームでも似たような区分でデータ分けは可能なので、割と使い易いのではないかと思います。 優先度についてより詳細が気になる方は、以下のページも参照してみてください


PKP と Expect-CT

講演の中で Public Key Pinning (PKP) について触れました。

f:id:sgtech:20191024160646p:plain

しかしこの PKP は、実は世の中的には古い仕様として非推奨となりつつあります。 理由は、講演でも触れたように、証明書の更新タイミングに運用側に負荷が掛かるからです。 例えば、 2019/1/29 にリリースされた Chrome 72 では PKP は既に廃止となっています。

それでは、中間者攻撃への対策はどうすれば良いのでしょうか?

そこで出番となるのが Expect-CT ヘッダです。

Expect-CT ヘッダーは、サーバが Certificate Transparency (CT) に対応していることをクライアントに伝える為に使用されます。

Certificate Transparency とは(ざっくり説明)

CT は証明書の発行のログと突き合わせることで、対象の証明書が不正なものであるかどうかを検知する機構です。 CT には Signed Certificate Timestamp (SCT) という、上記のログを管理するサーバに対象の証明書が登録された時刻を保証するタイムスタンプを利用します。 (利用の仕方は証明書に埋め込んだり、TLS Extension として送信したり、色々あります) この値からログ管理サーバに問い合わせを行うことで、自分たちの知らない所で証明書が発行されていないか(偽装されていないか)を確認します。

これ以上深堀りするととても長くなりますので、詳細が気になる方は RFC 6962 - Certificate Transparency を参照してください。

Expect-CT ヘッダの現状

リーグ・オブ・ワンダーランド導入時にもこの Expect-CT の検討は行ったのですが、まだ draft であった為に導入には早いとして最終的に PKP を選択しました。

それでは現在はどうなのか……というと現状 draft で止まっている状態なようです。

GitHub - httpwg/http-extensions: HTTP Extensions in progress

しかし、 Nginx や Apache では対応されているようですので、将来を見据えて PKP ではなく Expect-CT を採用してみるのも面白いかと思います。

最後に

私たちは、新しい技術でユーザの体験を変えていける、チャレンジ精神のある方を求めています。

当記事で弊社に興味を持った方は是非下のリンクをクリックしてください。

sega-games.co.jp

ゲーム開発に使われるプログラミング言語

 ゲーム=プログラム?

みなさんこんばんは。セガゲームス開発技術部の林です。

長年、技術と名のつく部門で技術者をやっています。このブログも TECH とついているためぜひ何か情報を発信してみたいと考えていましたが、やっと順番が回ってきました。

これまでやってきたことを控えめに表現するとゲームタイトルを開発しているチームのお手伝いです。遠慮せずに表現すると、技術的に難易度の高い部分を引き受けて成功に導くのが役割です。

そのため、家庭用ゲーム・アーケードゲーム・スマートフォンアプリなどいろいろなタイプや規模のゲーム開発に触れる機会が数多くありました。そこで、今回ブログのテーマとしてはその全てに関わる内容をご紹介したいと思います。

 

ゲーム開発に使用するプログラミング言語について取り上げます。

 

プログラム上のテクニックや技術の詳細ではなく、実際の開発現場でどのプログラミング言語が何に使われているのかをご紹介します。また、単に列挙するだけでなく、そのプログラミング言語の使われ方を通じて、ゲーム開発中にプログラミングが必要な場面としてどのようなことが行われているかの雰囲気もお伝えできればと思います。


プログラミング言語

ゲームはプログラムとデータでできています。最近プログラミングは特殊な技術者だけに必要なものではなく、その論理的な考え方は現代に生きる上で必要だとしてプログラミング教育が行われるようになりました。2020年からは小学校でのプログラミング教育が必修化されます。そういった流れから、ゲームはプログラムで動いており、プログラミングすることでゲームを動作させられるということを知っている人も多くなっているはずです。

そのプログラムを記述してゲーム機を含むコンピューターに命令するために使用するのがプログラミング言語です。プログラミング言語には非常に多くの種類が存在しており、ゲーム開発現場でもその中から選択された数多くのプログラミング言語が使用されています。

ゲーム業界と一般的なIT産業で全く違うプログラミング言語を使うということはなく、基本的には同じものを使いますが、全体に対する割合や重要度は業界によって異なる特徴が出ます。

この記事は、ゲーム業界を目指す方にとって、どのプログラミング言語を学習すればよいかの参考になるかもしれません。


よく使われるプログラミング言語

f:id:sgtech:20190916160513p:plain
C++

家庭用ゲームとアーケードゲームの多くは C++言語 で書かれています。ゲームは特に高速な動作が要求されるプログラムであり、高速な動作が期待できる C++ で実行速度を意識して書くことが重要です。

C++ やその元になった C言語 はハードウェア(コンピューター)に近い層の「原始的」な言語であり、ハードウェアの性能を100パーセント引き出すことに適しています。

C++ は十分に使いこなすには難易度が高めの言語ですが、その分機能が非常に多く、様々な目的に対して様々なやり方でプログラムを記述できる大きな自由度があります。そのため大規模なものを含む様々なプロジェクトで使用することができます。

 

また、ゲームそのもののプログラムだけでなく、特に速度の要求されるサーバープログラムやゲーム開発に必要なツール類の開発にも使用されます。

ゲーム開発において、ゲームプログラマーはゲーム本体のプログラムだけでなく、ゲームを作るのに必要なツールを作るためにもプログラミングします。一つのゲームを完成させるためには数多くのツールを作り、そのツールでゲームを組み立てていく作業が多くあります。

 

C++ の元になった C言語 は過去に広く使われていたため今でも一部に残っています。シンプルなため他言語との橋渡し部分に使われることもあります。C++ を学習する場合は必然的に C言語 も学ぶことになります。

 

f:id:sgtech:20190916155107p:plain
C#

スマートフォン向けゲームの多くは Unity というゲームエンジンを使って開発されています。この Unity では主に C#言語 を使ってプログラミングを行います。

 

また、C# は Windows PC 上で動くツールを作成するのにも向いており、ゲーム開発に使う社内ツールの多くは C# でプログラミングされています。 得意な処理を分担して、 C#C++ を併用しているツールもたくさんあります。

 

f:id:sgtech:20190916162024p:plain
Java

現代はすべてのゲーム機やスマートフォンがネットワークに接続しています。インターネットを経由した接続先にはサーバーが用意され、サーバーと通信することでネットワークゲームを実現しています。そういったネットワークゲームのサーバーや、ゲームと連動しているWEBサイトのサーバーなどゲーム会社は様々なサーバーを提供しており、それらのサーバー上でプログラムが動いています。サーバー上で動いているプログラムには様々な言語が使われていますが、 Java言語 が使われているケースが比較的多いです。

 

また、サーバーの場合は Java やその他の言語で直接プログラムを書くだけでなく、既存のソフトウェアをインストールして動かして使うことも多くあります。間接的にそれらのソフトウェアを作成するのに使われたプログラミング言語を使っているということができます。一部をカスタマイズして使うこともあります。

 

Java は他にも Android アプリ開発に使用することができ、一部のアプリで使用されています。

 

f:id:sgtech:20190916163211p:plain
Python

Python は様々な用途に使える人気の言語です。ゲーム業界や映像業界で広く使われているCGツールである Autodesk Maya の中でも実行できるため、面倒な繰り返し作業を自動処理させるなど、ツールを使いやすくするためにもよく使われています。

 

また、 Python は最近技術の進歩が目覚ましい人工知能(AI)の処理を記述するのに向いています。ゲーム開発現場においても人工知能を活用したツールを作るために使われる機会が増えてきました。

 

f:id:sgtech:20190916164031p:plain
JavaScript

JavaScript は、主にWEBページを作るために使われます。JavaScript を使うとWEBサイトで様々な機能や演出が実現できるようになります。このページにも使われていますね。

ゲームプレイヤー向けのWEBサイトだけでなく、ゲーム開発中に必要な情報を蓄積する社内向けWEBサイトも作成されます。チームではそれを参照しながら仕事を進めます。

 

また、JavaScript は Adobe Photoshop などのツールを自動化したり便利にするスクリプト処理にも使うことができます。

 

JavaScript のプログラムを直接書かず、TypeScript という JavaScript を強化した言語で記述し、それを JavaScript に変換してから使うこともあります。


その他の言語

その他にもシーンに応じて多くのプログラミング言語が業務に使われています。ここからはそれぞれ簡単に紹介していきます。

シェーダー言語

現代のゲーム機で画面表示を行うためには、専用のプログラミング言語を使って表示方法を細かく記述する必要があります。これをシェーダー言語といいます。キャラクターやメニューなどあらゆる画面表示はシェーダー言語の指示によって行われています。ゲームにとって表示の美しさや個性はとても大事なため、シェーダー言語によるプログラミングも重要です。

シェーダー言語としては、 HLSLGLSL などが使用されます。

アセンブリ言語

最も原始的でハードウェアに近い言語である アセンブリ言語 は、大きなプログラムを書くことには向いていませんが、特に高速に処理を行いたい部分にピンポイントに利用されています。

なお、最近メガドライブミニの登場で話題のメガドライブなど過去の16bitゲーム機時代のころまでは、ゲームプログラム全てが アセンブリ言語 で書かれていました。

スクリプト系言語

ゲームプログラム本体でもツールそのものでもなく、開発時に必要な様々な処理を行うためにも多くのプログラムが書かれます。 RubyPerl 、そしてすでに出てきた PythonJavaScript は作業を補助するためのスクリプト言語として使われます

Visual Basic もそういった処理の他、ゲーム開発でデータの管理によく使われる Microsoft Excel の制御にも使われます。

開発時ではなく、ゲーム実行時にゲームの動作を補助するスクリプト言語として、 LuaSquirrel が使われることもあります。

その他の言語

iOSアプリの開発には Objective-CSwift 、Androidアプリの開発には Kotlin といった目的に特に合ったプログラミング言語を使用することがあります。ゲームエンジン Unreal Engine 4 では専用ビジュアル言語である Blueprints が使われます。

bash 、 cmd.exe(コマンドプロンプト)、 PowerShell といった作業環境で使用する言語もプログラミング言語だと言えそうです。

既存のプログラミング言語ではできないことを実現するために、独自のプログラミング言語を新たに開発してそれを使うこともあります。


多様なプログラミング言語との付き合い方

ここまで多くのプログラミング言語を紹介してきましたが、ゲーム開発はチーム作業ですので、これら全てを一人で使いこなせるようになっている必要はありません。ここまで紹介してきたものの中で私が実際に業務で使ったことがある言語は半分ほどです。

使ったことがある言語でも、ほとんどが入社後に初めて触れています。セガに入社した時点では全く存在していなかった言語もあります。今後もゲーム機や開発に使う技術、プログラミング言語の進化に合わせて様々な局面に適した新しい言語がどんどん登場してくるでしょう。

 

プログラマーとして特に得意な言語はもちろんあったほうがよいですが、仕事で必要になった時に新しい言語をすぐに使いこなせるようになっておくと仕事の幅が広がります。まずは書きたい処理をすぐにスラスラと書ける得意な言語を軸として一つ二つ準備しつつ、それ以外の言語は新たに使いながら学んでいくことができれば問題ありません。

 

どのプログラミング言語を習得しておけばよいかという問いに対しては、どんなプログラミング言語でもすぐに習得できるようになっておけばよいというのが答えになります。

 

私たちは、常に新しい分野に好奇心を持ち、多くのプログラミング言語を使いこなしてゲーム開発に取り組める方を求めています。興味のある方は次にもアクセスしてみてください。

sega-games.co.jp

記載されている会社名、製品名は、各社の登録商標または商標です。

セガ・セガロゴとメガドライブは株式会社セガホールディングスまたはその関連会社の登録商標または商標です。

©SEGA

CEDEC 2019 セガグループによるセッション紹介!

皆さんこんにちは!
セガゲームス、第3事業部の麓です。

今年でSEGA TECHBogもこの8月に4年目を迎え、とても多くの方々がこのブログを知り、読んでくださるようになってきまして、続けることの大切さを噛み締めているところです。

来月にパシフィコ横浜で開催されるゲーム業界最大のカンファレンス

CEDEC2019

会期:2019年9月4日(水)~9月6日(金)
にセガグループ(および関連会社)からも何名か今年も登壇します!
それでは今回で4回目となる、セガグループ関係者によるセッションと登壇者紹介に加え、ここでしか見れない講演者からのメッセージや、当日の資料からの抜粋等、紹介します。

 

セッション

スクラムチームでモブプロ!-立ちはだかる導入・運用の壁とその成果-

セッション内容と講演者より

私たちは約3年、スクラムチームとして開発業務に携わっています。
事業に貢献したい、属人化を解消したい、新しい事にチャレンジしたいという課題を解決する手段を探してる中で、モブプロの導入を決めました。
導入を決めたものの、モブプロの導入を思い描いた方ならすぐに直面する壁からエンジニアならではの壁など、いくつかの壁に直面しました。
その壁をチームがどう乗り越え、どう成長し、どのような成果が生まれたのか、実践から感じたメリットやデメリットを含め、お話させていただきます。
チームが抱える課題を分析しその解決手段を模索している方へ、参考にしていただければ幸いです。

講演者

株式会社セガゲームス DMS事業部 システム開発部 研究開発2課 課長

横島 太志

09月04日(水) 15:20 〜 15:45(ショートセッション)

cedec.cesa.or.jp

スナップショット

 

f:id:sgtech:20190816164322j:plain

f:id:sgtech:20190816164332j:plain

 

セッションについて

役割を分担開発を行うスピード感とは違った側面にあるモブプロにおけるスピード感の実感など、予想外の効果についても触れさせていただきます。

 

Mesh Effect Shape:2Dカートゥーン調デザインから、その魅力のままにアニメーションする3Dエフェクトメッシュを軽量かつ効率良く作る!

セッション内容と講演者より

Marzaが久しぶりにCEDECへ戻ってきました。
水、火、煙などのエフェクトを2Dカートゥーン調デザインの魅力そのままの形で3Dオブジェクトとして制作できる手法をご紹介します。
デザインを重視したアプローチに始まり、カスタマイズされたスカルプトツールを使い工程によってはツールで自動化し、メッシュのレゾリューションも自由にコントロールできるなど、バリエーションに富んだ機能を用意し、直感的にボリュームを持ったシェープを作ることが可能です。
本セッションのエフェクトはUnityを使用した弊社の新作ショートフィルムで使われていますので、その実例と共にご紹介します。

使用ツール:Python、2Dペイント、 Maya、Unity

講演者

マーザ・アニメーションプラネット株式会社

 

映像事業1部 リアルタイムチーム チームマネージャー 高橋 聡

技術課 Assistant Technical Director Brent Forrest

技術課 Technical Director 松成 隆正

09月05日(木) 11:20 〜 12:20

cedec.cesa.or.jp

スナップショット 

f:id:sgtech:20190816170139j:plain

f:id:sgtech:20190816170202j:plain

セッションについて

ゲームエンジンを利用した新たな進化を遂げたMarzaの新作と共に、手描きの魅力を真にCGの世界に落とし込んだ、ユニークなエフェクトをお届けします。
また、表現の進化だけではなくパイプライン面での進化もお話しします。

 

ラウンドテーブル

ワーママ・ワーパパたちの働き方と悩み/御社の悩みは何ですか?他社はどう解決しているの?

セッション内容

<<2017年から始まったラウンドテーブルです/CEDECでの恒例化を目指しています>>

2018ラウンドテーブルでは、

受講者の皆さんに、

「私たち1人1人の動きで、働きやすいゲーム会社環境を作っていきましょう」

「来年のCEDECまでに、何か1つ新しいアクションを起こしましょう」

「きっと、何かが変わっていきます」

と呼び掛け、終了しました。

この1年、皆さんの周りで、何が変わったでしょうか?

引き続き、抱えている問題点は何でしょうか?

自社だけでは解決できない問題があれば、皆に相談しましょう。話し合いましょう。

皆さんが抱えている問題の、糸口が見つかる場にしたいです。解決が難しい問題でも、相談できる相手がいるだけで、勇気づけられるものです。

冒頭で、セガでのその後1年の動きを簡単に説明します。

5グループ程度に分かれて、皆さんの会社では、この1年でどのような動きがあったか、働きかけを行ったか、等、情報の共有をしていただきます。

現在抱えている悩みに関しても、共有して下さい。

その後、グループごとに発表。

発表された各社の内容に、意見や、質問がある場合は、質疑応答を行います。

他社事例の情報は、自社へ持ち帰り、社内で情報の共有を行っていただきたいです。それぞれの会社で、さらなる1アクションを興こすキッカケにしたいと願っています。業界の、働き方改革に繋げていきましょう。

講演者

株式会社セガゲームス エンタテインメント事業本部 第4事業部

茂呂 真由美

株式会社セガインタラクティブ コンテンツ研究開発本部 デザイナー

鈴木 こずえ

09月04日(水) 11:20 〜 12:20

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20190816172117p:plain

 

f:id:sgtech:20190816172440j:plain f:id:sgtech:20190816172412j:plain

講演者からのコメント

他社様と情報共有することにより、直面しうる問題と、具体的な対応例を知ることができます。
ここで刺激を受け、自社に持ち帰った後、自ら、何か行動を興していただきたいのです。
業界全体のワークライフバランス、意識改革に繋げていきたい、という目的で主催しました。

私たち1人1人の動きで、働きやすいゲーム会社環境を作っていきましょう。変えていきましょう。
Keep on Moving!

 

「ラウンドテーブル」ですので、悩みを抱えている方、共有したい自社事例のある方は、積極的にテーブル席についていただければと思います。
見学希望の方は、ラウンドテーブルが始まったら、各テーブルの話しが聞こえる場所に移動して、是非、現場の生の声を聞いて下さいね。
(立ちたくない!という方は、椅子ごと移動していただければ!)

セッションについて

ラウンドテーブル開催前、セガでのその後1年の動きを5分程度で説明、共有します。
社内共通コミュニケーションツール「Office365 Teams」を利用して、グループ会社間でのシナジーをどう高めていったか、活用法もご紹介します。

 

日々の業務から少しずつ始める!TA育成について話すラウンドテーブル

セッション内容

本ラウンドテーブルは、昨年度の「若手テクニカルアーティスト(以下、TA)の育成とその役割について話すラウンドテーブル」、および、一昨年度の「若手TAの業務効率改善への貢献、育成について話すラウンドテーブル」の議論に続くものです。

近年、その需要から各社でTA業務を専門で行う若手を育成しようという動きが広がっています。昨年、一昨年のラウンドテーブルを通じて、TA育成について若手にTA業務をやらせてみること、その機会を与えることが大事ではないかと議論が交わされました。しかし、そのようなTAの育成を行うためには育成する側の環境や人材にある程度の余裕が必要になり、現実的には余裕がないためTA育成に向けた活動を行うことは困難の場合が多いという課題も判明しました。 

そこで今年は、実業務へのアサインを通じたTA育成に焦点を当て、日々の業務へのアサインから少しずつTAを育成していくことはできないか、どのような業務へアサインすることがTAとしての知見を得ることにつながるのかをラウンドテーブルという形で突き詰め共有し、業界への貢献へとつなげていきたいと考えています。

講演者

株式会社セガゲームス 第3事業部 第3開発2部 テクニカルサポートセクション プログラマー

清水 宣寿 他

09月04日(水) 14:50 〜 15:50

cedec.cesa.or.jp

講演者からのコメント
CEDEC2018で「若手テクニカルアーティストの育成とその役割について話すラウンドテーブル」で登壇した清水です。 昨年に引き続き、テクニカルアーティスト(以下、TA)の育成についてのラウンドテーブルを開催いたします。
今年は、「日々の業務から少しずつ始める!TA育成について話すラウンドテーブル」です。 昨年のラウンドテーブルではTAの育成について、機会と環境を与えることができれば十分に育てることができる。というまとめになりました。 今回はその機会を増やすために、実業務を通じて少しづつTAを育成していくことはできないか?という考えのもと、TAスキルを伸ばせる実業務について議論します。 当日は話のタネになるように、登壇者7名がTAスキルを伸ばせた実業務をまとめた表を持っていきます。
一緒にTA育成について議論を交わし合いませんか? ご参加、お待ちしています。

パネルディスカッション

ゲーム開発におけるOSSライセンス管理の実際 (パネルディスカッション)

セッション内容

本セッションでは、複数の企業のOSS管理の責任者にお集まり頂き、各社での取り組みをシェアいただきます。

具体的な管理法、注意すべきOSS、困ったライセンスなどをご紹介頂きます。

参加者のOSS管理への啓蒙、実際の問題の解決に役立つ情報をご提供します。

講演者

株式会社セガゲームス 開発技術部 課長

山中 勇毅 他

cedec.cesa.or.jp

 

今回紹介したセッションで聴講したい!と思ったセッションはありましたか?
多くの開発者の集まるCEDECは、パシフィコ横浜 会議センター(神奈川県横浜市西区みなとみらい)で9月4日(水)~9月6日(金)の間、開催されます。

CEDECに参加して情報収集や交流をし、ゲーム業界の今を知り、業界の未来について語り合いませんか?
それでは皆さんCEDECでお会いましょう!

 

私達は将来CEDECに登壇してみたいと思っている、技術に興味のある方を求めています。
そんな貴方、以下にアクセスしてみませんか?

 

sega-games.co.jp

 

最後に、今月はこのSEGA TECHBlogの運営についてCGWORLD.jpに取材いただきまして、記事として公開もされました。

これまでの3年間、このブログを通じで何が起きて、生まれてきたか、これからのアイデアなどお話しさせていただいています。

よかったらこちらも合わせて読んで頂ければ幸いです!!

cgworld.jp

 

※複数社登壇の場合でもセガの社員のみ表記しています 

『Readyyy!』でのLive2D活用事例

2019年6月末でサービスを終了した『Readyyy!』。その『Readyyy!』にテクニカルアーティストとして参加していましたセガゲームスの宮下です。『Readyyy!』をプレイしてくださった皆様、本当にありがとうございました。


また、社内はもちろん、大勢の社外の方々のお力添えでリリースした『Readyyy!』でしたが、アプリのサービスを早々に終了させる結果になってしまったこと、誠に申し訳ありませんでした。スタッフ一同一丸となって取り組みましたが、力及びませんでした。

そんな中『Readyyy!』をプレイしていただき、サービス終了を惜しんでくださる皆様からは、厳しいご意見をはじめ、心温まるお手紙、想いの詰まった色紙などをいただきました。皆様のお声は開発チームまでちゃんと届いており、スタッフ一同ありがたく読ませていただいております。そして、そのような𠮟咤激励のお声にどう応えていくのか、日々考えながら業務に励んでおります。


テクニカルアーティストの自分と致しましては、『Readyyy!』の開発を通じて得た知見や技術を、この「セガテックブログ」の場で伝え、そして楽しんでいただくことで、皆様からのお声に少しでも応えられたらと思い、このブログを書かせていただきました。


今回『Readyyy!』でのLive2D活用事例として2つご紹介します。

1つはライティング表現で、主にその仕組みやテクスチャの使い方に関する内容です。すでにプレイできなくなっているアプリの画面などを用いての説明となってしまい、重ね重ね申し訳ありません。

もう1つは、今後も『Readyyy!』のアイドルたちの姿を届けられることになったコンテンツ、多人数の同時生配信についてです。こちらは、多人数同時生配信の仕組みと、それを作り上げていくスタッフとのやりとりの様子をお伝えします。もしかするとその当時のやりとりで気になるところもあるかもしれませんが、お付き合いいただけますと幸いです。


それでは、始めさせていただきます。


Live2D®とは?

Live2Dとは、元のイメージを保ったままイラストを動かしたり、疑似的に3Dのように見せられる特徴を持つ、株式会社Live2D*1が開発した技術やソフト、データのことです。ソフトの正式名称は「Live2D Cubism」と言います。「Cubism SDK 3.0*2」でUnity*3からLive2Dへのアクセス方法が一新されたのですが、柔軟性が高くとても良い出来だったので『Readyyy!』で採用することに決めました。ただし「Live2D Cubisim」と「Cubism SDK 3.0」だけではライティングの実現には足りていません。新たなシェーダーとコンポーネント*4の開発、それを活用するための特別なデータが必要でした。

Live2Dライティング表現のあれこれ

f:id:sgtech:20190726221016g:plain:w500

『Readyyy!』のLive2Dでのライティング表現が一部で話題*5になっていましたが、開発初期にプロトタイプを部内で紹介したときも、驚きの声とともに「力技?!」という声があがりました。そのときは「力技とは心外だな」と内心ふくれていたのですが、いまにして思えば…まあ力技ですね。やっていることは単純なんです。

それでは、『Readyyy!』のアイドルの1人、上條雅楽(かみじょううた)君に手伝ってもらって、ライティングの仕組みを説明していきます。

f:id:sgtech:20190725002118p:plain
『Readyyy!』の上條雅楽君

使っているテクスチャについて

ライティングを実現するために、1ポリゴンにつき3つのテクスチャを使ってます。具体的には、アルベドマップ(色)、シャドウマップ(影)、スペキュラマップ(光沢)です。
「Live2D Cubism」はマルチテクスチャに対応していないので、この3つのテクスチャを生成するために、3回の出力作業が必要ですが、この面倒な作業はSikuliX*6を使ってほぼ自動化しています。UV座標はLive2Dのものをそのまま利用して、ライティングの主な処理はUnity上のシェーダーで行っています。

アルベドマップ

まず、体と顔のアルベドマップが1枚ずつ、計2枚あります。画像サイズは1024x1024ピクセルと600x600ピクセル*7で、フォーマットはRGBA Crunched ETC2を使っています。これはUnity2017.3から導入されたフォーマットで、ストレージの消費量削減に抜群の効果があります。それまでは、JPEGファイルをダイレクトに使う計画で、その場合だと、RAMへの展開後にTrueColorになってしまい、メモリ消費量も膨大だったので、このフォーマットには助けられました。

なおRGBA Crunched ETC2はノイズが目立つので、軽減するようにアルベドマップのサイズは比較的大きめにしてあります。ノイズの軽減については、またあとで説明しますね。

f:id:sgtech:20190725002113j:plain
アルベドマップ

シャドウマップとスペキュラマップ

続いて、シャドウマップとスペキュラマップです。

f:id:sgtech:20190725002216j:plain
シャドウマップ(上)とスペキュラマップ(下)

シャドウマップとスペキュラマップに関しては、グレースケールで、かつ、ちょうど合計4枚なので、劣化しないTrueColorフォーマットを使ってRGBAチャンネルにパッキングしています。先ほども言いましたが、TrueColorだとメモリ消費が大きいので、画像サイズをぎりぎりの380x380ピクセルまで下げています。ETC2フォーマットで圧縮したケースも試してみましたが、見栄えが悪かったので不採用にしました。

f:id:sgtech:20190725002108p:plain
パッキングされたシャドウマップとスペキュラマップ

陰影のバリエーションについて

ちょっとややこしいのですが、アイドル1ポーズにつき、シャドウマップとスペキュラマップをそれぞれ3種類用意しています(下の画像の左から、逆光左順光右順光)。これは太陽や照明の位置の違いを表現するためで、このバリエーションはライティングの効果を発揮するための大切な部分です。なぜなら、これが1種類しかないと、この一連の仕組みはあまり意味がなくなってしまうからです。

f:id:sgtech:20190725002155j:plain
シャドウマップのバリエーション例

テクスチャの種類のまとめ

マップの種類 画像サイズ 作業上の枚数 実際の枚数 画像
アルベド 1024x1024 2 2 f:id:sgtech:20190725002113j:plain:w300
シャドウ、スペキュラ 380x380 2x3、2x3 3 f:id:sgtech:20190725002213j:plain:w300

ここまでの説明を表にまとめてみました。つまり1ポーズあたり5枚のテクスチャが必要ということです。なお『Readyyy!』では、アイドル1人に対してポーズを7種類用意する予定でした。また衣装差分は5種類あるため、5x7x5で合計175枚のテクスチャが1人あたりに必要となります。なかなかのボリュームですね。

シャドウマップとスペキュラマップの縮小

少し話を戻します。シャドウマップとスペキュラマップの画像サイズを下げた(380x380ピクセル、下の画像の左)ということは、アルベドマップ(1024x1024ピクセル)と比較して、相当ぼけているということなんですが、思いの外うまくなじんでいます。それどころか、64x64ピクセルまで縮小しても破綻しないんですね。

解像度を下げても破綻しないというのは、いわゆる3Dのシャドウマップと似ていますね。

ノイズ軽減のためアルベドが大きめという理由もあるのですが、シャドウマップとスペキュラマップはアルベドマップと同じサイズであるべきという固定観念にとらわれていたので、個人的にこの発見は大きいものでした。

f:id:sgtech:20190725002204j:plain:w1000
シャドウマップのサイズによる見た目の変化

アートディレクターからのチェックで、縮小は380x380ピクセルで止めたのですが、曇り空のときは、右の64x64ピクセルバージョンを使うように提案してみてもおもしろかったですね。

シェーダーでレイヤー合成

シェーダー上で、先ほどのアルベドマップとシャドウマップを乗算し、スペキュラマップを加算してライティングを実現しています。

fixed4 main_tex = tex2D(_MainTex, IN.texcoord);
fixed4 packed_tex = tex2D(_PackedTex, IN.texcoord);
fixed3 albedo = main_tex.rgb;
fixed3 shadow = packed_tex.rrr;
fixed3 specular = packed_tex.ggg;
// 計算を省略しています!
fixed3 clr = albedo * lerp( IN.ambient, fixed3(1,1,1), shadow ) + specular; 
return fixed4( clr.rgb, main_tex.a );

Photoshopのレイヤー合成みたいなことをシェーダーでやっているわけですね。

f:id:sgtech:20190725002125p:plain
アルベドのみ
f:id:sgtech:20190725002130p:plain
シャドウのみ

また、 影の色味の違いを表現するために、頂点カラーを利用しています。頂点カラーは「Live2D Cubisim」上で直接設定可能なのですが、ヒューマンエラーが発生しそうなので、ノード名に特定のキーワードを入れてもらって、Unityでのインポート時に、自動的にキーワードから頂点カラーを設定するようにしました。ただし、間接的な方法を採用したことで「Live2D Cubism」上で色を視認できないという弊害が発生してしまい、肌なのに服のキーワードになっているなどの設定ミスが多発することになりました。チェックにも修正にも結構時間がかかってしまったので、この方法は、もっと検討改良すべきでした。

髪の毛(赤色)、肌(緑色)、服とヘッドセット(青色)として設定していますが、この色をダイレクトに乗算しているわけではありません。

f:id:sgtech:20190725002136p:plain
頂点カラーのみ

あくまで質感の種類を識別するために使っていて、このようなシェーダーコードにしています。

ambient = _HairAmbient*v.color.r + _SkinAmbient*v.color.g + _ClothAmbient*v.color.b;

本来質感が異なる場合は、マテリアルを分けて表現しますが、今回はドローコール数を増やしたくないため、このような仕組みにしています。

f:id:sgtech:20190725002118p:plain
合成結果

桜や建物などの落ち影

Live2Dへの落ち影は、かなり反響があったので、うれしかったですね。桜や建物の落ち影用のテクスチャは、必要な背景にだけ用意しており、スクリーン座標系を使ってシェーダーで計算しています。

f:id:sgtech:20190725002142p:plain
桜の落ち影


f:id:sgtech:20190725002148p:plain
落ち影テクスチャ

スクリーン座標系はUV座標系よりも単純で、シェーダーでよく使うテクニックです。Live2Dに対して、落ち影テクスチャをプロジェクションマッピングしているといったほうがわかりやすいかもしれません。

『Readyyy!』では、Live2Dを半透明化させて消すときに、一時的にレンダーテクスチャを使っています。そのときにスクリーン座標系が画面全体ではなくレンダーテクスチャの大きさのものに変化にしてしまうため、同じ計算方法のままだと、落ち影がずれてしまうのです。その問題に対応するために、少し面倒な計算になっています。

half4 screenPos = ComputeScreenPos(OUT.position);
half2 uv2 = screenPos.xy / screenPos.w;
// _ViewportScaleX等は、CPU側で計算している
uv2.x = uv2.x * _ViewportScaleX + _ViewportOffsetX;
uv2.y = uv2.y * _ViewportScaleY + _ViewportOffsetY;

言い忘れていましたが、背景ごとのライティング用パラメーターの設定は、手動で行っています。

f:id:sgtech:20190725002249g:plain

逆光陰影のクオリティアップ

もともと逆光陰影は1段階でした。下は2段階と1段階の比較画像です。

f:id:sgtech:20190725002231j:plain

1段階のものでは物足りなさを感じていたので、順光時の陰影とブレンドして陰影を2段階とする手法を提案し承認されました。手作業でテクスチャをブレンドするのは面倒なので、スクリプト言語のRuby*8とRMagick*9という画像処理ライブラリで自動化しました。

そういえば、最近、RMagickのメモリ使用量を減らしたという素晴らしい記事を見つけまして、一人で大興奮していました。RMagickのメモリリークには、苦労させられていたので!ありがとうございます!うれしさのあまり、テクニカルアーティストの同僚たちにもチャットで共有したのですが、特に反応はありませんでした。テクニカルアーティストの使うスクリプト言語は主にPython*10ですから、まあそりゃそうですよね。

watson.hatenablog.com

RGBA Crunched ETC2のノイズ軽減について

RGBA Crunched ETC2のストレージ上での圧縮性能はとても高いのですが、そのかわりノイズが発生します。このノイズに対抗するには、テクスチャを大きくすればいいのですが、比例してRAMとストレージの消費量も増えるので、それとクオリティとを天秤にかけることになります。『Readyyy!』ではLive2Dのテクスチャの他に、フォトにもこのテクニック(大きくするだけなんですが!)を使っています。

フォトとはガチャで引くことのできる、アイドルの写真のことです。

f:id:sgtech:20190725002059j:plain
『Readyyy!』のフォト

『Readyyy!』は画面サイズ1334x750ピクセルの想定で作っているので、画面サイズに近い1336(4の倍数)、画面サイズを大きく超えた2048、4096ピクセルの3種類のフォト用の画像で、ノイズがどのように変化するか比較してみました。

横幅(ピクセル) RAM(MB) ストレージ(MB) フィット後に切り抜いた一部画像
1336 4 4 (参考データ)TrueColorだった場合
1336 1.2 0.2 f:id:sgtech:20190725002220p:plain:w300
2048 2.8 0.45 f:id:sgtech:20190725002224p:plain:w300
4096 12 1.3 f:id:sgtech:20190725002228p:plain:w300


上は、1334x750ピクセルの画面サイズにフィットさせて、一部分を切り抜いた画像と容量の表です。4096ピクセルのものが一番きれいですが『Readyyy!』ではバランスを取って2048ピクセルのものを採用しました。

ここで「フォトにはアルファチャンネルがなさそうなのに、なぜRGBA Crunched ETC2フォーマットを使うのか?」という疑問をもつ方がいるでしょう。その理由はiOSとAndroid両方で有効なCrunchedなフォーマットがRGBA Crunched ETC2しかないからです。ですから実はアルファチャンネル分、無駄にRAMを使っているのですが、それを踏まえてもストレージ上での圧縮性能が魅力的ということなのです。

最後のは少し余談でしたが、Live2Dのライティング表現については、以上です!

つづいて「多人数による同時生配信」に話を移しましょう。

多人数による同時生配信

f:id:sgtech:20190725002236j:plain
SHOWROOMさんでの生配信の様子

IPプロデューサーのOさんから、生配信の相談は突然やってきました。

「2月14日のバレンタインデーに、アイドル2人で生配信をやりたい!」

2人同時に生配信するには、リアルタイムでアイドル2人の映像を生成して、配信サービスを提供しているSHOWROOMさんのサーバーに転送する必要があります。私がLive2Dのデータ組み込みやライティングを含めた実装まわりを担当していたので、引き受けることになりました。

ところで、この生配信の見た目って何かに似ています。そう『Readyyy!』のアドベンチャーパートです。

f:id:sgtech:20190725002200j:plain
『Readyyy!』のアドベンチャーパート画面

事前に収録した音声を使っているのと、スクリプターさんが、あらかじめ設定したポーズを表示している点が異なりますが、要するに、この生配信というのは『Readyyy!』のアドベンチャーパートのようなものをリアルタイムで生成しようという試みなんです。

アイドル1人での生配信は、SHOWROOMさんのスマホアプリ「SHOWROOM V」で確立されていましたが、2人の仕組みは備わっていなかったので、セガ側で用意する必要がありました。

そのときは配信日までの時間と生配信に関する知識が不足していて、とても間に合わせる自信がなかったので、Oさんとの相談の結果、1か月後の「3月14日のホワイトデー」までに2人同時生配信の仕組みを用意する、ということになりました。リハーサルのことを考慮するとその1週間ぐらい前が締め切りですね。

ところで、Live2Dをバーチャルキャラクターとして操作するツールというと、「FaceRig」が有名ですね。

store.steampowered.com

『Readyyy!』のLive2Dは、アイドル1人に対して7種類のポーズがあるのですが、これは「FaceRig」でいうところのアバターが7種類あるという意味になります。ネットの情報を調べた限りでは「FaceRig」は多機能なんですが、生配信中に7つのアバターを切り替えていくやり方には向いていないと判断し(もし問題なくできるとしたらごめんなさい!)、Unityで簡易的なアプリを作ることにしました。

2人同時生配信の誕生

こうして会社のヘッドセットを借りての検証と開発の日々が始まりました。自席でマイクに向かって声を出す恥ずかしさと言ったら…。なので人が少なくなった夜中に声を出したり、会議室を取ってそこで検証したり、いろんな人に「これって、もはやテクニカルアーティストの仕事じゃないよね…。」とも言われたり。褒め言葉と解釈しましたが。

通常バーチャルキャラクターといえば、カメラによる顔認識などで実際の動きをトレースして、キャラに反映するものですが、今回は割り切ってウェブカメラは使わずに、インタラクティブなものはマイクから入力された声の音量による口パクの動きのみ。体の動きはキーボードの操作でポーズやアニメーションを切り替えるだけ、例えば「1」を押すと喜んでいるポーズ、「2」を押すと悲しんでいるポーズになる、というような何ともレトロな仕組みにしました。

FaceRigの代わりになるUniyアプリはできたので、次は2人同時の部分をどう実現するかです。

参考にしたのがこのサイトです。

www.cg-method.com

なるほど。2人目は「Skype」や「Discard」でビデオ通話して、そこからキャプチャしているんですね。しかし今回の場合、すぐそばに2台のノートPCがあるのに、わざわざネットワークを介してビデオ通話というのは、ちょっと大げさすぎますし、無意味に遅延が発生してしまいますよね。

数日、他の仕事しながらぼんやり考えた結果「ネットワークの代わりにHDMIを使うアイデア」にたどり着きました。

  1. 市販のキャプチャボックスを使って2台のノートPCを、HDMIとUSBでつなぐ。
  2. ヘッドセットをノートPCにつなぐ。普通のマイクでも可。
  3. それぞれでUnityアプリを立ち上げて、アイドルが映った状態にする。
  4. 下記図の左側のノートPCから、右側のノートPCに画面を転送する。右側のノートPCにはUnityアプリの画面が2つ映った状態になる。
  5. 右側のノートPCのOBS*11上で、2人のアイドルをクロマキー合成する。
  6. OBSからSHOWROOMさんのサーバーに転送する。

f:id:sgtech:20190725002244j:plain

この方法で、2人同時生配信を実現できました!
ただし、HDMIを使う方法には2つ問題がありました。

問題の1つは、HDMIでの動画と音声の転送の遅延です。これにより相互のマイクで音声を拾った場合に、遅延した音声も合わせて配信されてエコーがかかったような現象が発生しました。

もう1つは、HDMIでPC同士を接続することの不安定さです。なかなか認識しなくて、何度もHDMIを抜き差しして、やっと成功する…といった具合で、本番の配信中に接続が切れないかと心配でした。

結局未解決のまま生配信したのですが、そのときダイジェストがこちらです。

www.youtube.com

なんとかそれっぽくなりましたね。

なお、機材のセットアップや生配信中のOBSの操作、トラブル対応のため本番は毎回立ち会っています。

5人同時生配信への道

この段階では、Oさんには「同時に生配信できる人数は2人までですからっ」とクギを刺していました。

ところが、その後この仕組みを使ってユニットごとに「新曲発表」の生配信をするという企画が立ち上がりました。それも、そのユニットのメンバー全員(2人〜5人)で、です。

新曲発表1組目は「La-Veritta(ラヴェリッタ)」という2人組のユニットだったので、トラブル*12もありましたが、そのままの仕組みで乗り切れました。

2組目の「Just 4U(ジャストフォーユー)」という4人組ユニットのときは、Oさんの提案で、2人ずつ入れ替わりで生配信しました。結果、トラブルもなく大成功でしたが、でも私は負けた気がしたのです。そのときの視聴者の書き込みからもメンバー4人全員がそろっている姿を見たいという気持ちを感じましたし、なにより、できない理由が技術的な事情というところに、敗北感を覚えました。

このままではつまらない。『Readyyy!』で一番人数の多いユニット「SP!CA(スピカ)」は5人組なので、5人同時生配信の仕組みを作ってやる、と心に決めました。

f:id:sgtech:20190725002104j:plain
「SP!CA」のメンバー

単純に5台のPCをHDMIでつなげば、今の仕組みのまま対応できるかもしれません。ただPCが2台のときでさえ多少不安定なのに、5台だなんてとんでもない…。トラブルが発生することは容易に想像できます。

そんなことをぼやいていたら、いつもお世話になっているインフラ屋のAさんの助言がヒントになりました。

Aさん「1台で完結させればいいんじゃない?」

Aさんも深い意味で言ったわけではなかったと思うのですが、理にかなっています。1台…そうか…できるかも…。

PC1台で5人同時生配信を行う仕組みはこうなりました。まず以下の機材を用意します。

  • デスクトップPC1台
  • USB接続のマイク5本
  • USB接続のコントローラー5台(実は4台でよかった)
  • 液晶モニター2台
  • USBハブ2個
  • Live2Dのアイドルを表示する自作Unityアプリ
    • 使用するマイクやコントローラーを切り替える機能
    • マイクからの音量に合わせてアイドルが口パクする機能
    • アイドルを切り替える機能
    • コントローラーでアイドルのポーズを切り替える機能
  • OBS

セットアップの手順はこうです。

  1. PCにマイクとコントローラーを5台ずつ、つなぎます。
  2. そのPCで自作Unityアプリを5つ*13立ち上げます。
  3. Unityアプリ上で、それぞれ、アイドル、マイク、コントローラーの設定をします。
  4. OBSでUnityアプリの画面をすべて取り込んで、クロマキー合成します。
  5. OBSからSHOWROOMさんのサーバーへ転送。

f:id:sgtech:20190725002240j:plain

これだけの機材の数になると、セットアップの手間もかなりのものになったのですが、その苦労の甲斐あってか、5人同時生配信の野望を達成できました!また、PCが1台になったことで遅延の問題も解決して一石二鳥です。

『Readyyy!』のアプリでは、パフォーマンスの都合上、アイドルの同時表示数を3人に制限していたので、ある意味で「生配信はアプリを超えた!」とも言えます。

f:id:sgtech:20190725002209p:plain
生配信中の「SP!CA」のメンバー

ツイッター上でも5人全員そろっていることへの驚きの反応があったので、うれしかったですね。ちなみに明るさが人によって異なっているのは、話している人が誰かをわかりやすくするためです。

では次に、5人同時生配信をする上で遭遇したトラブルを3つ紹介します。

マイクデバイスを選択できない問題

Unity2017.4では、複数マイクデバイスから任意の1つを選択できないバグがあり、どう解決するか悩まされましたが、そのバグが修正されたUnity2018.2を使うことで、あっさり解決しました。直っててよかったです…。

Unity Issue Tracker - Microphone.start is not recording the audio from selected recording device

バックグラウンドのUnityアプリでは、コントローラーが反応しない

Unityアプリを5つ立ち上げるので、すべてのアプリをアクティブにしておくことはできません。そのためUnityアプリがバックグラウンドの状態でも、操作できるようにしておく必要があります。

qiita.com

このサイトを参考にXInputを使って解決したまではよかったのですが、リハーサルで、5台目のコンローラーがまったく反応しないトラブルに遭遇しました。ネットで調べてみると、XInputはコントローラーを4台までしかサポートしていないそうで。そのためUnityアプリを修正して、5人目はキーボードでポーズを切り替えるようにしました。キーボードでの操作は2人同時生配信のときに実装していたので、対応自体はスムーズでしたが、まさかそんな落とし穴があるとは…。でも、プログラマのK君に聞いたら常識のようでした。

しゃべっていないアイドルが口パクをしてしまう

指向性のマイクを用意したのですが、それでもマイク同士が近いため、他のメンバーの声を拾ってしまい、しゃべってないアイドルが口パクをしてしまう問題が発生しました。超指向性のマイクを導入する方法もありましたが、今回はコントローラーの右トリガーを引いたときにのみ口パクをするようにプログラムを修正しました。ちょっとかっこ悪い解決方法ですね。

先ほど紹介した2人同時配信のダイジェスト動画もよく見ると、右側のアイドル(全)の口が時々、左側のアイドル(淳之介)につられて動いているのが分かります。

多人数生配信のまとめ

生配信の仕組み作りについては、世間のVTuberさんにとっては目新しいことはなかったと思いますが(結果的に)遅延のない5人同時生配信の試みはちょっとおもしろかったんじゃないでしょうか?条件は異なりますが「FaceRig」のマルチアバター機能も4人までみたいですし。
生配信自体、まったく新しいチャレンジだったので、プレッシャーがありながらも「SP!CA」5人全員を登場させることができたときは、達成感ありました(疲労感も…)。また、生配信中にトラブルがよく発生するので、臨機応変で、かつ、一か八かの対応も、普段のゲーム開発では味わえないスリリングさがありました。あと、OBSというツールがほんとよく出来ています。

最後に…

『Readyyy!』でのLive2D活用事例、いかがだったでしょうか?今後も「応援し続けてよかった」と思えるくらい楽しんでいただけるよう、アイドルの生配信をはじめとするさまざまな可能性に、『Readyyy!』に関係するスタッフ一丸となって取り組んでいきます。

この記事が、皆様のモチベーションに少しでもプラスの影響を与えることができたのなら、幸いです。



©SEGA

*1:https://www.live2d.com/ja/

*2:UnityでLive2Dを扱うためのプログラム https://live2d.github.io/#unity

*3:ゲームを作るための統合開発環境 https://unity.com/ja

*4:特定の機能を持たせたプログラムのかたまり

*5:https://togetter.com/li/1316881

*6:http://sikulix.com/ GUI上での操作をRubyやPythonで自動化するツール。

*7:ETC2は2のべき乗ではなく4の倍数でOK

*8:まつもとゆきひろ氏が開発した、個人的に大好きなスクリプト言語。テクニカルアーティストにはどちらかというと人気はない。

*9:画像処理ライブラリImageMagickのRubyインターフェス。Rubyで簡単に画像を処理できるようになる。

*10:Mayaをはじめ多くのツールに組み込まれているスクリプト言語。DeepLearningでも良く使われている。テクニカルアーティストに大人気。

*11:正式には「OBS Studio」という。生配信で使われるオープンフリーなソフトウェアのこと。

*12:1人の声が突然ロボットみたいな声になるというトラブルが発生し、めちゃくちゃ焦りましたが、Unityアプリを再起動したら直った。

*13:1アプリで5人表示させる方法もアリかもしれませんが、生配信中にアイドルの数を増減させる演出をすることがあり、別々のアプリにしておいてOBSで人数を管理する方法がやりやすかった。

Powered by はてなブログ