そんなことよりHoudiniやろうぜ!

初めての方は初めまして、そうでない方はお久しぶりです。
ここ10年龍が如くシリーズ製作にどっぷり浸かってるVFXアーティストの伊地知と申します。

今日は最近巷で大人気のHoudiniで基本部分の理解から簡単なエフェクトをUE4に表示してみるまでを皆さんにお届けしようと思います。

とりあえずこれだけは知っておきたい基礎知識
●操作方法
選択モード:s→2(Point)、3(Edge)、4(Primitive)、5(Vertex)
編集モード:Enter
カメラモード:Esc(選択モードや編集モードの時は一時的にSpace又はAlt)
ノード生成:Tab→ノード名検索キーワード(例えばattribute wrangleならaw、Sphereならsph)



Houdiniではジオメトリを扱う際に各コンポーネントの種類毎にグループとアトリビュートという情報が持てます。
データの構造と流れを各ノードに把握しておくのが重要になってきます。

コンポーネントの種類
Point、Primitive、Vertex、Detailの4種類があります。
f:id:sgtech:20180120232427p:plain
それぞれのコンポーネントにランダムで色を付けるとこの様になります。
それぞれ点、面、面毎の点、全体と覚えておくと良いでしょう

アトリビュートの種類
各コンポーネントにアトリビュートが持てます
デフォルトのアトリビュートとしてはP(座標),N(法線),uv,Cd(色)などがあります。
また独自のアトリビュートを作成して情報を格納しておくことが出来ます。
後述しますがwrangleでの記述方法としては
f@hogehoge = rand(@ptnum);
// 上記はfloat型のhogehogeというアトリビュートを作る例です。@の前の1文字で型の指定が出来ます。vならベクター型、sなら文字列型です。
// ちなみに右項は頂点番号をシードにして0~1までの乱数を生成しています。
●アトリビュートの確認方法
ビューポート上の画面下半分でAlt+] → Alt+8 と押して下さい。GeometrySpreadSheetが表示されます。
GeometrySpreadSheetはデータの構造を確認する上で重要なものなので常に表示してのが良いでしょう。
f:id:sgtech:20180120232423p:plain

最も簡単なVOPとwrangleの例:
VEXでアトリビュートを扱うにはVOP(VEX Oprater)wrangleを使った二通りの方法があります。

SphereSOPを作りPrimitiveTypeをPolygonにしてFrequencyを10に上げます。
f:id:sgtech:20180120232146p:plain

次にpointVOPSOPを作りiやダブルクリックでpointVOPの中に潜ると

f:id:sgtech:20180120232139p:plain

こんな感じのインターフェイスがあります。
左側のgeometryvopglobal1というノードはpointVOPの第1入力の事です。
そして右側のgeometryvopoutput1はこのVOPノードネットワークの結果を返します。
試しにgeometryvopglobal1の出力のP(頂点の位置)とgeometryvopoutput1の入力のCd(頂点カラー)を繋いでみましょう。
すると球に頂点カラーが設定されます。

では同じ事をwrangeでやってみましょう。

先程のsphereSOPの下にpointwrangleSOPを作成し繋げます。
f:id:sgtech:20180120232132p:plain

pointwrangleSOPのパラメータにはコードを書き込む為のテキストエリアが存在し
そこに@Cd = @P;と入力しても先程のVOPと同じ結果が得られます。
f:id:sgtech:20180120232126p:plain

この様にVOPやwrangleを用いて頂点座標や頂点カラー、法線、UVなど様々なアトリビュートにアクセス出来るのがVEXの強みです。
またwrangleの場合、非常に高速に動作する(C/C++コンパイル相当)のも魅力的です。

ちなみにこの例の場合Cd(頂点カラー)にマイナスの値が入り込んでくるので
VOPであればfit rangeVOPを用いてwrangleであればfit01関数を用いて0~1の間に合わせてやると正しいデータになります。
f:id:sgtech:20180120232119p:plain
f:id:sgtech:20180120232431p:plain

Attributeのコピーや転送
同じトポロジー同士であればAttribute Copy、距離でアトリビュートを転写するのであればAttribute Transferを使うと良いです。
また違うコンポーネントにアトリビュートを移したい時はAttributePromoteを使うのが定石です。

グループ
各コンポーネントにグループを設定出来ます。
バウンディングオブジェクトでポイントのグループを指定する例
f:id:sgtech:20180120232418p:plain
法線でプリミティブのグループを指定をする例
f:id:sgtech:20180120232414p:plain

グループのコンポーネントの変換
ポイントグループをプリミティブグループに変換するのはGroup Promoteで出来ます。

駆け足でしたがここまでで基本的なジオメトリに関する操作は理解出来たでしょう。
ここまでの知識とSOPの機能を学んでいけばプロシージャルモデリングは可能です。
他のDCCツールと比較して無い機能もあったりしますがそうした際はポータルサイトで、英語で調べるとたいていは情報を得られますので、
あまり心配しなくとも良いでしょう。



ではここからは実際にループするパーティクルを作成してUE4に出力してみましょう。

ループするパーティクルの作成

フォースフィールドの作成
まずはフォースフィールドを生み出すガイドとなるカーブを作成します。
LineとCircleからSweepに繋いでねじれたチューブを作ってCarveで螺旋を取り出すという事をやります。
その際Lineの方に@pscaleと@orientというアトリビュートを持たせてSweepに渡す事で形状の調整をします。
そしてCopyStampでY軸回転に均等コピーしておきます。
f:id:sgtech:20180120232809j:plain
point wrangleには

float div = (@ptnum)/float(@numpt);
f@pscale = chramp("widthControl",div)*chf("widthBase");
@orient = quaternion( radians(chf("roll")+div*360)*chi("twistNum")*chramp("twistPow",div),@N );
の様に記述してパラメータを出し調整する事ですぼんだ様な形状にする事が出来ます。
ちなみにアトリビュートを使わない設定にすると
f:id:sgtech:20180120232822j:plain
この様に均等なねじれになります。
あとはDOPNetworkに渡す前に@forceアトリビュートを作っておけばフォースのガイドは完成です。

ワンショットパーティクルの作成
DOPNetworkにつないでパーティクルを作成する際popnetという名前で作成しておけば
自動的にPOP ObjectPOP SourcePOP Solverを作って繋げておいてくれるので楽です。
f:id:sgtech:20180120232804j:plain

なぜループのパーティクルを作るのにワンショットを作るのかといいますと
シミュレーションでノイズをかけるとパーティクルは周期的にはなりませんので
ワンショットパーティクルを作成してそれを連続再生させてループに見せる手法を取るためです。
(残念ながらGameDevelopmentToolSetのMakeLoopはパーティクルには効きません)
f:id:sgtech:20180120232816p:plain
図にするとこんな感じです
f:id:sgtech:20180120232806p:plain
ファイルキャッシュにした時点でトライ&エラーがやりづらいのであらかじめワンショットの時点で
動きや雰囲気などを皆さんの感覚で良い感じに見えるようにしておきます。
もっとうまい方法があれば良いんですが世の中そう都合の良い話は無いですね。
DOPNetowork内に話を戻すのですが先程作ったフォースのガイドを
あらかじめDOPNetworkの2番目に繋いでおいてSOPGeometryのSOP Pathに

`opinputpath("..",1)`
としてfieldforceDOPに繋いでPOPSolverとoutputの間に差し込みます。
f:id:sgtech:20180120232930j:plain
またPOPSourceの下にちょっとしたノイズを足す為にPOP Wind DOPを足しておきます。
すると動き的にはこんな感じになります。
f:id:sgtech:20180120232919g:plain

ループパーティクルの作成
これをfile cacheSOPでキャッシュを取っておいて前述の半分にして折り返す処理をします。
Alt+Shit+Gを押してGlobal Animation Optionsを出してシーンのフレーム数を半分にして
Time Shiftでフレーム数の半分を足してMergeします
f:id:sgtech:20180120232916j:plain

すると動きがループになります。
f:id:sgtech:20180120232905g:plain

ブラーが欲しくなるので気持ち的にはここでTrailSOPを使いたくなるのですが
スタートフレームとエンドフレームで破綻するのでTrailは使わずに一旦file cacheに動きを保存しておいて
Time ShiftSOPのエクスプレッションで対応します。
f:id:sgtech:20180120232901j:plain
こうすることでループさせてもスタートとエンドがキレイにつながります。

パーティクルのメッシュ化
Particle Fluid Surfaceにつなげてパーティクルをメッシュ化します。
物凄く重いので形がカッコよくなった段階で一度file cacheに取りLoad From Diskにチェックを付け
滑らかに再生出来る状態で動きを確認します。
f:id:sgtech:20180120233044j:plain

メッシュの削減
Poly Reduceなどを用いて最適なポリゴン数にまで落とし込みます。
CleanやRemesh、Dissolveなども使っても良いかもしれません。
f:id:sgtech:20180120233019g:plain

VertexAnimationTexturesノードを使ってデータを出力する
この状態をUE4に持っていくことにします。
/outモジュールに移って Vertex Animation Texturesノードを作ります。
f:id:sgtech:20180120233014p:plain
このノード名がメニューに出てこない方は
github.com
をダウンロードして入れて下さい。
入れ方が分からない人は同梱されてるREADMEを読んで下さい。
(英語ですけどそんなに難しく無いので大体分かると思います。)
で、
f:id:sgtech:20180120233010p:plain
MethodはここではFluid、ExportNodeを設定、Target Poly Countを決定しRenderボタンを押します。
※@Cd(頂点カラー)のアトリビュートを設定しておけばColorMapのチェックボックスを付ける事で色情報も出せます。

VertexAnimationTexturesのシェーダをUE4上で構築する
次にVertexAnimationTexturesのシェーダをUE4に持っていきます。
VertexAnimationTexturesノードの下の方にあるFluid VertexAnimation UE4 Codeの+ボタンを押してUE4のシェーダーコードを表示し
f:id:sgtech:20180120233006p:plain
全選択してコピーします。
f:id:sgtech:20180120233137p:plain
UE4上で新規マテリアルを作成して
[ff:id:sgtech:20180120233132p:plain]
ダブルクリックしてマテリアルエディタを開きます。
f:id:sgtech:20180120233124p:plain
そして先程コピーしておいたUE4のシェーダーコードをペーストします。
f:id:sgtech:20180120233119p:plain
するとこの様にマテリアルエディタ上にシェーダのノードネットワークが構築されます。
f:id:sgtech:20180120233115p:plain
マテリアルエディタの詳細タブの目玉マークのプルダウンメニューからアドバンスな詳細を表示にチェックを付けます。
f:id:sgtech:20180120233308p:plain
さらにカスタムUVの数3に設定します。
あとはノードネットワークのコメントに従って対応するパラメータを接続します。
f:id:sgtech:20180120233303p:plain
これでマテリアルは完成です。

マテリアルインスタンスの設定
先程Renderボタンで作成されたFBX(モデル)とEXR(テクスチャ)をUE4にドラッグ&ドロップしてインポートします。
f:id:sgtech:20180120233259p:plain
「全てインポート」で構いません。
f:id:sgtech:20180120233251p:plain
次にマテリアルインスタンスを作ります。
f:id:sgtech:20180120233248p:plain
ダブルクリックして設定ウィンドウを開き先程作ったマテリアルを親マテリアルにします。
f:id:sgtech:20180120233420p:plain
HoudiniのVertex AnimationノードのBBOX MAXとMINの値をコピーして
UE4にペーストします。あと該当するチェックやフレーム数も同様です。
f:id:sgtech:20180120233417p:plain
あとポジションのテクスチャも設定しておきます。
f:id:sgtech:20180120233412p:plain
これでマテリアルインスタンスの設定は出来ました。

モデルにマテリアルインスタンスをアサインする
先程インポートしたFBXモデルをダブルクリックして設定ウィンドウを開きます。
マテリアルスロットに作成したマテリアルインスタンスを設定します。
ビルド設定の「最大制度のUVを使用」にチェックを付けてモデルへのマテリアルインスタンスの設定は終了です。
f:id:sgtech:20180120233409p:plain

これでモデルをビューポートにドラッグ&ドロップすればUE4上で再生出来るループする流体エフェクトの完成です。

f:id:sgtech:20180120233345g:plain

いかがでしたでしょうか?
ゲームに出力する部分は意外と手続き的な処理が多く煩わしさはありますが、Houdiniで作った流体表現が
ゲームに表示出来るというのは感慨深いものがあるのではないでしょうか?
こういったエフェクトの手法は日々進化していきます。
現状ビルボードが主流のゲームエフェクトですがデータとシェーダを工夫する事でこの様な表現が可能になりました。
5年後10年後どういった表現が可能になるのかワクワクしますね。

という訳で恒例の求人タイムです。
弊社ではHoudiniに興味を持って取り組めるような人を募集しています!
私の作ったシーンを見放題にもなれますし社内でハンズオンセミナーなども開催していますので
興味のある方は以下のリンクをクリックしてみてください。



採用情報 | セガ企業情報サイト

Ruby on Railsでアセットライブラリを作ろう!

 年の瀬も押し迫り、すっかり寒くなりましたね。今年最後のお役目をつとめます、セガゲームス開発統括部アート&デザイン部TA(テクニカルアーティスト)セクションの宮下です。
 普段はUnityでアーティストとプログラマを繋いだり、Mayaプラグイン(C++)やスクリプトを書いたり、たまにデザインデータを作ったりしてます。今回は、TAの業務でも少し変わったネタとして、Webアプリ作成についてお伝えします。とくに最新のネタというわけでもないので、プログラマの方には退屈な記事かと思いますが、ご容赦ください。

そもそもWebアプリって?

 ブラウザ上で動く、サーバーを介したアプリケーション、みなさんも普段から使ってますよね。GoogleやFacebook、Twitter、Slackなど、インターネットを通して提供されているサービスは、ほぼWebアプリと呼んでいいでしょう。あのような有用なサービス、そこまでいかなくてもちょっとしたサービスをプロジェクトや部署の中で提供できたら楽しくないですか?もちろん会社内でのWebアプリなので、インターネットではなく、イントラネットを使ったサービスということです。

Docker

 その方法の1つは、オープンソースのWebアプリを探してインストールし運用することです。最近はDockerというものがあって、簡単にWebアプリをPCにインストールできます。

docker run --name mattermost-preview -d --publish 8065:8065 mattermost/mattermost-preview

 Dockerがインストールされていれば、このコマンドを実行するだけでSlackのようなチャットサービスMattermostを提供できます。
 もしかすると、これぐらい当たり前のように感じられるかもしれませんが、まともにWebアプリをインストールしようとすると面倒なことになるので、このDockerはなかなか画期的です。
 ニーズにマッチしたオープンソースのWebアプリが見つかればいいですが、探しても見つからない…。そんなときは、もう1つの方法、自分で作るしかない!TAだから!(昔はデザグラマって言われてました…。今はいい言葉があります。)
 今回は、アセットライブラリとボット管理ツールなど3例、紹介します。

アセットライブラリ

f:id:sgtech:20171224002340j:plain
f:id:sgtech:20171224002335j:plain
 2015年に作った部内用のWebアプリで、アーティストの作成したデータの共有を目的としています。具体的には、psdやtgaなどの画像ファイル、UnityのスクリプトやPrefabなどを格納できるUnitypackageファイルなどを共有しています。基本的に誰でもブラウザからアップロード、ダウンロード可能で、検索やタグ付け、フォルダのような階層構造も持っています。合わせてgifサムネイルを自動的に作成しUnity上からアップロードできるUnityスクリプトも用意しました。モーションやエフェクトは、gifアニメで視覚的にどのようなアセットかを確認できます。
 ファイルをアップロードする機能を作って公開した直後に、誰かがアップロードしていると、他の人がアクセス不能状態になることが判明し、あわてたことを覚えています。1人で開発とテストをしているときには分からなかった問題だったのですが、原因はアップロードした画像のサムネイルを生成するなどの後処理がメインプロセスを占有してしまうためで、後処理を非同期にすることで対応しました。
 

ボット管理ツール

f:id:sgtech:20171224002348j:plain
 私たちの組織では、Cisco SPARKというチャットツール(チャットワークやSlackのようなものです)を導入しています。それにはボットを組み込む機能があり、何らかの情報をボットから提供することができます。ただし、APIが公開されているだけで、使うにはハードルが少々高い。そこで、ボット管理ツールをWebアプリとして作りました。
 このWebアプリでは、ボットのスケジュールや発言内容、週替わりや日替わりの当番の指定ができます。たとえば、特定のメッセージを決まった時刻に発言させる、毎週水曜日のミーティングの議事録当番を知らせる…といったことが可能になります。
 もともとは今参加しているプロジェクトの朝会当番を、ボットに教えてもらうために作ったのですが、現在では他プロジェクトやセクションのミーティング告知など、幅広く活用してもらっています。
 面白かったのは、本来当番のメンバー名を入力すべき箇所(上のスクリーンショットでぼかしの入っているところですね)に、カレーやラーメンなどの食べ物名を入れて、ボットに今日食べる昼ごはんを日替わりでつぶやかせているプロジェクトがあったことです。遊び心のある思いもよらなかった使い方に驚かされました。

アーティストアサイン管理ツール

f:id:sgtech:20171224002344j:plain
 プロジェクトがいくつも平行している中、アーティストのアサインの調整がスピーディに求められていませんか?私たちの組織では求められています。エクセルでの管理もいいのですが、もっと効果的に管理はできないものかと突貫で作り上げたのが、このWebアプリです。リーダーがメンバーのスケジュールを入力し、どういったスキルのアーティストを求めているのか、また、いつアーティストがプロジェクトからリリースされるのかを視覚的に分かるようにして管理しています。まだまだ発展途上のWebアプリで現在も作成中です。
 
 それでは、次にこのようなWebアプリの作成方法を簡単に説明します。

Ruby on Rails

 私、個人的にRubyが大好きで処理の自動化などに使っています。でも、MayaなどのDCCツールのスクリプトに採用されている言語はもっぱらPythonなので、実はあまりアーティストには勧められません。
 Webアプリを作るためのフレームワークとして、とても有名なものがあります。それが、このRubyで作られたフレームワーク「Ruby on Rails」です。「Ruby on Rails」の思想は、ほかのフレームワークにも大きな影響を与えていて、Pythonなら「Django」、phpなら「CakePHP」というフレームワークがあります。「Ruby on Rails」は2004年の誕生でなかなか歴史があり日本でも人気です。それゆえ、Web上での日本語の情報も豊富でビギナーにもお勧めできるフレームワークです。大抵の問題や要望は、Webで検索すれば解決できます。

 「Ruby on Rails」はActive Recordが有名で、この機能により簡単にデータベースにアクセスできます。具体的には、オブジェクトのインスタンスが、そのデータベースの1つの行を表すような仕組みです。

a = Game.new 
a.name = "sonic the hedgehog"
a.price = 5000
a.save

このコードで、新しい行を追加できます。すばらしい!

 「10分で Rails」とWebで検索するとたくさんヒットするように、とても簡単にWebアプリのひな形を作ることができます。ここでは「セガ」というWebアプリを新しく作ってみますね。

rails new sega
cd sega
rails generate scaffold game name:string price:integer
rake db:migrate
rails s

 これらを実行したのちに

 http://localhost:3000/games

にブラウザでアクセスすると、
f:id:sgtech:20171224002332j:plain
のような画面が出てくると思います。
New Gameをクリックすると、
f:id:sgtech:20171224002411j:plain
このような画面に遷移して、ゲーム名と値段を入れることができます。先ほどActive Recordでの例をブラウザから入力して、「Create Game」ボタンを押してみます。
f:id:sgtech:20171224002407j:plain
どうですか?簡単ですね!
 上記のアセットライブラリやボット管理ツールは、この「Ruby on Rails」のバージョン4で作成し、このようなひな形から肉付けして発展させたものです。そして、その作業を助けてくれるのがRubyGemsです。

RubyGems

 Webアプリの機能を作る上で、すべてを1から書くのはとても時間がかかります。RubyGemsはRubyのパッケージ管理システムで、世界中のスペシャリストたちが作ってくれた便利機能を簡単にインストールできます。ここで、さきほど紹介したアセットライブラリを作る上で組み込んだパッケージを紹介します。

devise

アカウント管理のためのGemです。ユーザーアカウントとパスワードにまつわる部分を簡単に実装できます。
github.com

CarrierWave

ファイルのアップロード機能を組み込むためのGemです。
github.com

kaminari

ページ切り替え機能を提供します。こういう名前が日本語由来のGemを見ると、ちょっとうれしくなりますね。
github.com

rmagick

画像フォーマットを扱うのに便利です。psdやtgaのサムネイルをブラウザで表示させるためにjpegに変換するのに使っています。ただ、psdをうまく処理できないケースがあって、それに対応するため、「psd.rb」というGemも使っています。
github.com

psd.rb

psdファイルを読み込んだり、サムネイルを作成するためのGemです。
github.com

ransack

便利な検索機能を提供してくれます。
github.com

最後に

 アセットライブラリのWebアプリ(サービス)と言えば、このサイトが良くできてます。
sketchfab.com
 こんなの作ってみたいですね。ブラウザさえ動けば、もはや何もいらない時代は意外と近そうです。

 ここまで読んでくださった方、ありがとうございました。
 TAセクションではこのようにアーティストの制作に役立つ環境を提供できるよう力を注いでおります。Unityの登場でTAの活躍できるフィールドは格段に広がり、シェーダーやポストエフェクトなど面白い表現を生み出せないかと日々切磋琢磨しております。そんな中でお仕事したい方はぜひ下記の弊社グループ採用サイトをご確認ください。いっしょに働きましょう!

採用情報 | セガ企業情報サイト

TAが勉強を兼ねてモバイル向け電光掲示板シェーダー書いてみた

はじめまして、亀川と申します。


セガゲームス開発統括部アート&デザイン部TAセクションというところに所属しており普段はモバイル向けのゲーム開発に従事しております。


所属はTAセクションですが、業務内容はデザイン業務とTA業務が半々ぐらいです。
内容はモーション制作・管理、Mayaをはじめ各種DCCツールのツールやライブラリの開発、保守など日々TAセクションに寄せられる要望に応える形で作業を行っております。


弊部のゲーム開発は全てUnityで行われているのですが、ご存じの通りUnityはかなりオープンなゲームエンジンなので各種情報が公式ドキュメントやWEB上でも入手しやすく学習しやすいものとなっており、ゲームの実装に関わる部分でもTAが関われる部分が増えてきたというのが実感としてあります。


そういった中でもシェーダー開発は飛躍的に敷居が低くなったのではないかと思います。
少しプログラムをかじったことがあればレベルにもよりますが、すぐにでも画面に出るものが作って試せます。これは非常に楽しいです。


そういった事もあり、ここ1、2年は空前のシェーダープログラミングブームが来ていると思います。
私もご多分に漏れず、これまであまり触れる事のなかったゲーム中のビジュアル周りに関わるシェーダーの勉強を始めてみました。


前置きが長くなってしまいましたが、今回の記事は以前に部内のあるプロジェクト用に作った「電光広告看板」、「電光掲示板」用シェーダーについて作成のプロセスと内容について触れていきたいと思います。

電光広告看板とは?

電光広告看板という言葉は普段生活している中ではほぼ聞く事はないのですが、街中や施設の中など目にする機会は非常に多いと思います。


LED電球を並べて広告を映像として表示させることができるものです。
その中でも特に今回はサッカー場の横に置かれている電光広告看板を想定して作成しました。

制作物

結果から先に見せてしまうと、こういう物を制作しました。

f:id:sgtech:20171123211804j:plain:w120
f:id:sgtech:20171123211800j:plain:w120
f:id:sgtech:20171123211753j:plain:w120
f:id:sgtech:20171123211749j:plain:w120
f:id:sgtech:20171123211745j:plain:w120

電光広告看板に見えますでしょうか?実際はアニメーションしていますので本当は動画を置きたかったのですが”はてなblog”に動画を直接アップロードできなかったので静止画になっています。

それではこの看板シェーダーを作るプロセスと実際のコード内容を説明していきたいと思います。

制作前の仕様確認

制作前には仕様の確認が必要となりますので発注者であるアートリーダーと最終イメージと使い方などを含めた仕様のすり合わせを行いました。


具体的には広告の動かし方?テクスチャは何パターン用意するのか?メッシュのUVの持たせ方は?背景のライティングとの兼ね合いは?プログラムからの操作、アーティストがどこまで調整できるかなどなどをまずはざっくりで良いのでヒヤリングを行いシェーダーに持たせるパラメータや仕様を決めて行きます。


最初のヒヤリングで全ての要求仕様が出揃うことはないので、まずは最低限作成できるレベルの仕様はつめます。


ここでざっくり決まった仕様はこんな感じです。


・最近の電光掲示板のような広告
・サッカー場の回りにポリゴン板を立てて置くイメージ。何パターンか置きたい。
・ライティングは反映する必要はない。
・テクスチャスロットは2枚。プログラムで切り替える。
・2枚とも非表示にする事がある。その時は指定色が出るようにしたい。
・ブレンドで切り替えたい。
・広告テクスチャの移動はUVアニメーションで制御したい。

電光掲示板らしさの要素抽出

機能的な仕様が出そろったのでいよいよ今度はビジュアル面の方向性を固めていきます。


今回のゲームでは中継カメラを意識したような視点が想定されるので素直にTVを通して見た電光掲示板らしい表現を目指すことにします。


そのためは電光掲示板がそれらしく見えている特徴的な部分の抽出が必要です。この要素分解をするのが楽しいところですが、私はこう考えました。


・LEDならではのドット感。
・カメラのレンズを通す事による色収差、にじみ感。
・広告が切り替わる動き。スクロールする時のアニメーション。
・LED表示を描画しているスキャンラインの雰囲気。
・光のにじみのグロー表現


以上の要素があればだいたいそれらしく見えるのではないかと思いました。
今回は、広告の動きはUVアニメーション、光のにじみはポストエフェクトで適宜行うとして看板シェーダー自体の描画ではその前段階までを表現することにしました。

シェーダー実制作

先に完成したコードがこちらになります。

全体のシェーダーコードは以下のようになります。


インスペクターに表示されるシェーダープロパティはこんな風になっています。
f:id:sgtech:20171123211818p:plain:w120


それでは上で書いた要素がソース中でどのように実装されているのか中身を追って見ていきたいと思います。

LED球のドット感の表現

ドット感の表現はシンプルにLED球1つを表現したテクスチャ1枚をタイリングでしきつめて上から乗算で被せます。加えて、広告画像の方にも少し手を加えますがこちらは実装に少し迷ったので2つの表現を用意しました。

LED枠のイメージ

まずはLED枠のイメージですがこんな感じシンプルにタイリングするだけです。
この枠の下に広告画像が来る事になります。
f:id:sgtech:20171123211722p:plain

広告画像テクスチャの加工1 ”1ドット1色”

一つ目は広告画像をタイリング枠に合わせて1ドット1色という色の取り方をするものです。
こちらの方がLED球1つに対して1色なので原理的にはより本物に近いのですが、一方で相当細かくLED球をタイリングしないと絵が潰れてしまい判別できなくなる問題もあります。

f:id:sgtech:20171123211718p:plain

ソースはこうなっています。

                #ifdef _IS_REAL_REAL_LED
                    //こちらが1ドット1色
                    //Pixelate for MainTex
                    half2 steppedUV = i.uv.xy + _CellSizeXY*0.5;
                    steppedUV /= _CellSizeXY.xy;
                    steppedUV = round(steppedUV);
                    steppedUV *= _CellSizeXY.xy;
                    col = tex2D(_MainTex, steppedUV);

                    //Pixelate for MainTex2
                    steppedUV = i.uv2.xy + _CellSizeXY*0.5;
                    steppedUV /= _CellSizeXY.xy;
                    steppedUV = round(steppedUV);
                    steppedUV *= _CellSizeXY.xy;
                    col_mt2 = tex2D(_MainTex2, steppedUV);

この部分でポイントになってくるのは"_LedTex"で取得したLED枠テクスチャのタイリング単位でテクスチャの色を1色だけサンプリングしてくる部分です。

テクスチャのタイリング数は"_LedTex_ST.xy"でxyそれぞれのタイリング回数を得る事が出来ます。xを3回、yを3回繰り返すなら(3,3)という形で格納されています。


またテクスチャの色はUV空間で取得するのでこのタイリングのxy回数の1回分のサイズを0-1のUV空間の値で知る必要があります。それをコード中で事前に行っている部分がこちらです。

static const half2 _CellSizeXY = 1.0 / _LedTex_ST.xy;


UV値単位で1つのセルサイズを知ることが出来たら後はテクスチャのUVの値に対してセルサイズの半分を足しその値をセルサイズで割り、roundで端数を切り捨てる事で段階的なUV値を得ます。そのUV値を使ってテクスチャの色を取得することで段階的に取得することが出来ます。

広告画像テクスチャの加工2 ”画素ずらしによる疑似色収差”

1ドット1色は本物に近いのですがやはりLED枠タイリングを細かくしないとそもそも画像の認識が難しいです。
そのため、ドット化なしに通常通りテクスチャを張り付けるパターンも用意しました。これが2つ目です。

こちらはそのままテクスチャを表示するだけなのですが、そのままでは少し物足りなかったのでカメラのレンズによる色収差を表現する事にしました。
非常にお手軽な手法ですが色を取得する際にrgbの各チャンネルを1pxずつずらして取得することにしました。

それがこの画像になります。
f:id:sgtech:20171123211714p:plain


よりアップで見た画像がこちらです。LEDの枠はまたいで色はあるものの離れて見るときは1ドット1色とそう差異は感じられない印象です。

f:id:sgtech:20171123211710p:plain

こちらのソースはこうなっています。

                #elif _IS_REAL_FAKE_LED
                    //枠は関係なくテクスチャを読み込む
                    //Shift Texture color by 1px
                    col = tex2D(_MainTex, i.uv);
                    col.g = tex2D(_MainTex, i.uv.xy + _Texby1pt.x).g;
                    col.b = tex2D(_MainTex, i.uv.xy + _Texby1pt.x).b;

                    //Shift Texture color by 1px
                    col_mt2 = tex2D(_MainTex2, i.uv2);
                    col_mt2.g = tex2D(_MainTex2, i.uv2.xy + _Texby1pt.x).g;
                    col_mt2.b = tex2D(_MainTex2, i.uv2.xy + _Texby1pt.x).b;
                    
                #endif

テクスチャからrgbチャンネルごとに1pxずつずらして取得していることがわかります。
テクスチャの解像度の1px単位がUV値に換算するとどれぐらいになるのかは下に書いた行で事前に取得していました。

static const half2 _Texby1pt = half2(_MainTex_TexelSize.x , _MainTex_TexelSize.y );
マルチコンパイル

この2つの表現方法をUnityのマルチコンパイルという機能を使い1つのシェーダー内で2つのバリエーションのシェーダーを持てるように実装しています。


この機能の実装部分はCGPROGRAM~の少し下の行のスニペットと呼ばれる部分に記述されている以下の行となります。

#pragma multi_compile _IS_REAL_LED _IS_FAKE_LED

これはプロパティ部分を記述している部分に

[KeywordEnum(REAL_LED, FAKE_LED )]
_IS_REAL("IS Real LED", Float) = 0

このように記載することでアーティストがシェーダープロパティからどちらのモードを使用するか使い分ける事が出来ます。

f:id:sgtech:20171123211706p:plain


さらにフラグメントシェーダーの中もこれに対応している部分があります。上述のLED部分の中で#ifdefから始まり#endifまでの部分でプロパティのキーワードで条件として処理を分けています。

個人的にはピクセル化を行うREAL_LEDモードの方の方が力を入れて用意したのですが実際の現場では疑似モードの方でLEDの枠のわかりやすさ、テクスチャのわかりやすさから選択されているようです。

広告画像の切り替え

Lerp関数

1枚目と2枚目、そしてベースカラーの3つの色の切り替えは主にlerp関数を使って行っています。
動画が貼れないのでまた静止画ですみません。左から時系列でベースカラー、広告1、広告2そしてまたベースカラーへと変遷しています。

f:id:sgtech:20171123212418j:plain

                //Blend Texture Main and Main2farPower
                col.rgb = lerp(col.rgb, col_mt2.rgb, _MainTex2_BlendPower);
                //Blend Base color and Textures.
                col.rgb = lerp(_BaseColor.rgb, col.rgb, _BlendPower);


lerp関数を2回使う事で3つの色の切り替えを行っています。
最初の行で2枚の広告テクスチャの切り替えを、次のlerpで広告と指定カラーの切り替えを行います。


lerp関数はテクスチャのブレンドを行う際はよく使う関数でlerp(x, y, s)という形で使用しx,yの2枚のテクスチャをs(0~1)の値でブレンド度合を決めます。勿論用途はテクスチャに限らず2つの要素を0~1で割合でブレンド調整したい時には使いやすい関数だと思います。


広告の切り替えなので2つのテクスチャで十分ではないかと思われるかもしれませんがどちらの広告もオフにして何も表示しない状態にする時に第三の色が必要になってくるのでこの形式を取っています。また完全にどちらの広告が表示されないという状態の時にプログラムから広告テクスチャを入れかえる事も可能です。

LED描画更新による輝度ムラの表現

ここまでやってきましたがまだ何か物足りない気がしましたので輝度を時間軸で少しいじってみることにしました。

実際のLED電光掲示板は人間の目では意識できないほど高速に1ラインずつ描画を更新しています。それをカメラで写すとシャッタースピードのズレから輝度のムラのようなものを感じる事があります。そういうニュアンスを入れる事でさらに電光掲示板らしさが増します。

f:id:sgtech:20171123212531j:plain


左が何もしない時の映像で右が輝度の変化を加えたものになります。
どうでしょうか。上は静止画ですが実際は輝度ムラが上下左右でアニメーションします。
少し右側の方がそれらしく見えるのではないでしょうか?


その部分のソースがこちらになります。

                // 走査線1 uv基準でスキャンラインを描画
                half scanLineColor = sin(_Time.y * _LineSpeed + i.uv.y * _LineSpacing);// / 2 + 0.5;

                // 走査線2 uv基準でスキャンラインを描画
                half scanLineColor2 = sin(_Time.y * _LineSpeed*0.5 + i.uv.y * _LineSpacing*0.1);/// 2 + 0.5;
                
                // 走査線3 uv基準で横スキャンラインを描画
                half scanLineColor3 = sin(_Time.y * _LineSpeed*0.25 + i.uv.x * _LineSpacing2); //; / 2 + 0.5;

                col += (saturate(scanLineColor) + saturate(scanLineColor2) + saturate(scanLineColor3)) * lerp(_LineBrightness, 0.0, farPower) * _BlendPower;


やっていることは簡単です。sin関数を用いて現在の表示色に白を加算する事で輝度ムラを加えています。
それを波形のリズムを変えて3つ重ねています。こうする事で1つの時より自然な感じが出ます。

カメラからの距離に応じた対策

上述の輝度の変化ですがこれは看板に近い時は効果的ですが離れたところから見た時はやや不自然に感じました。


そこでカメラの距離に応じてその影響を加減することにしました。実は上で書いたコードにはそれはすでに含まれています。計算式の中のこの部分になります。

 (_LineBrightness * (1 - farPower)) * _BlendPower;

事前にカメラからの距離をfarPowerという変数に格納してあり距離に応じて光の強度が乗算する割合を変えています。

シェーダー高速化について

シェーダーを書く上で常に意識しないといけないのはやはり処理負荷の部分です。

この高速化について少し触れてみたいと思います。これに関しては月並みですがUnityドキュメントの”シェーダーを書く場合のパフォーマンスのヒント”という項目を忠実に行うにつきるかと思います。
https://docs.unity3d.com/jp/560/Manual/SL-ShaderPerformance.html


できるだけ頂点シェーダー内で済ませる

頂点シェーダー部分で取得した情報はフラグメントシェーダー内では”補間された値”で受け取ることができるので、ライティング情報など頂点で受け取っても問題ない場合は頂点シェーダー内で受け取ります。例えば3頂点で囲まれたポリゴンの場合、頂点シェーダーでの計算は3回ですがフラグメントはピクセル数に応じて行われますのでその計算量の差は圧倒的です。

できるだけ計算の精度を下げる。

floatよりhalf、halfよりfixedの順で計算が低精度になっていくので処理負荷が低くなります。
fixedで問題のないケースは積極的にfixedを使うとよいでしょう。

ただし

現代の多くの GPU(OpenGL ES 3 や Metal を実行することができるもの)は固定小数点数と
半精度浮動小数点数を、内部的にはまったく同じものとして取り扱います。

とUnityのドキュメントにもありますのでhalfで書いていても実質は問題ないというケースは多いのではないかと思います。

テクスチャへのフェッチ(読み込み)回数を減らす

テクスチャは通常フラグメント関数の部分でフェッチしますがピクセル数に応じて行われるのでパフォーマンスに影響します。例えば上述のシェーダーソース内の”画素ずらし”の部分でテクスチャのフェッチを4回やってますがこれはなかなかの負荷だと思われますので画像がこの用途以外に使い道がないのであれば事前にPhotoshop等で画素ずらしを行っておいてこの処理を省いてもよいでしょう。


まとめ


以上、電光掲示板シェーダーの制作事例の説明となります。今回はライティング、影や半透明ソートなどのややこしい部分は考えなくてよいのでシェーダーとしては比較的簡単な部類には入るのではないかと思いますが、それでも実機で表示されて実際のゲーム中で動作するとなかなか達成感があります。



今回は右も左もわからない、それこそセマンティクスって何ですか?というようなところからシェーダー学習を始めたのですが学習法は完全に我流でいろんな情報を並行して学んでいきました。


Unity公式ドキュメントやネット上の制作事例を参考にした他、Unityシェーダーの書籍、nVidiaのCgマニュアルなども参考にしました。

nVidiaのドキュメントはこのあたりから読む事が出来ます。


Cg Toolkit | NVIDIA Developer


ただ上記URL内のドキュメントは全て英語なので正直言ってざっと斜め読みするのも大変です。私を含めてそういった方には日本語に訳された物もあります。

http://developer.download.nvidia.com/cg/Cg_3.0/Cg_Users_Manual_JP.pdf


こちらはリリース日がかなり古いのが気になりますが、Cgの基本や数学関数の説明などは今でも使えるものですので一読されることをお薦め致します。


またゲーム会社ということもありシェーダーを始め描画周りの知識が豊富な者がたくさんおりますからアドバイスをもらったり、コードレビューしてもらったりしたことも大きな助けになりました。


ただ何にでも言えることだとは思うのですが、一番学習効果が高い勉強法は”何か作りたいものがあって実際に作ってみる”。これにつきると思います。


これが一番学習意欲が上がりますし、質問がより具体的になり、望む答えも得やすくなりますので是非皆さんも何か題材を見つけて取り組んでみてください。


次回はリグのネタでも載せられればと考えています。それでは次回またお会いしましょう。


 TAセクションではこのようにアーティストの制作に役立つ環境を提供できるよう力を注いでおります。やりたいことを遠回りせずに行える環境でお仕事したい方はぜひ下記の弊社グループ採用サイトをご確認ください。いっしょに働きましょう!現在いろいろな職種でアーティストを多数募集しております!

採用情報 | セガ企業情報サイト

(C)SEGA

エフェクト統一シェーダーがあると捗るよね

 みなさんUnityしてますか?僕はここ5年くらいはUnityしまくってます。
すっかりモバイル開発はUnityばっかりになりました。もちろん他にも有力なゲームエンジンはあるのですけど、いろいろなハードに出すということや運営面を考えると、セガでは現状Unityがとても強い状況です。

 はじめまして、セガゲームス開発統括部アート&デザイン部TAセクションの樋口と申します。スマホ向けゲーム開発を専門的に行う部署に所属しています。先日のCEDEC2017で「GameVFX Bootcamp 2017 ゲームエフェクトの今を4つの視点から」におきまして、弊社の綿貫が紹介していました「Effect Uber Shader(エフェクト統一シェーダー)」についてお話しします。

エフェクトのワークフロー

 ワークフローという程でもないのですが、一般的にエフェクトを作る場合には以下のような段階があります。

  1. 作成内容のパーツ分解
  2. パーツの試作
  3. 組み合わせて調整
  4. 組み込んで調整

 たとえば爆発のエフェクトを作る場合、イントロの閃光、放射状に広がる火花、少し遅れて広がる煙、衝撃波というような感じで(1)分解して、(2)それぞれを作っていくというような感じです。その後、(3)それらを組み合わせて、同期させて調整を行なっていき、一旦は完成となりますが、ゲームに組み込んでみてから(4)最終的に調整を行うことになります。

 エフェクト統一シェーダーが活躍するのは、主に(3)と(4)になります。調整の段階ではパラメータを変化させて目的に合った状態に設定していくという作業を行いますが、変化の自由度が少ないとデータの作り直しからとなってしまうため、調整作業が非常に高カロリーです。

調整作業を簡略化したい

 例えば、シェーダーが統一されておらず、各機能別にそれぞれシェーダーが用意されていたとすると、個別の機能の切り替えの際に選択するシェーダーを探し当てないとならず、間違いのもととなります。
 ありそうなシェーダー名の例だとこんな感じでしょうか。機能別にどんどん名前が追加されて似たようなものもあったりで、大変です。

  • ParticleAdditive
  • ParticleAlphaBlended
  • ParticleAdditiveZOffset
  • ParticleAdditiveOvertop
  • ParticleAdditiveUVScroll
  • ParticleAdditiveUVScrollZOffset
  • ParticleAdditiveUVScrollZOffsetCutoff
  • ParticleAdditiveUVScrollZOffsetCutoffMasked
  • ...などなど

 これが、使うシェーダーは1つだけとして、各機能別にシェーダー内の設定で必要な機能を選んだりできると調整用途に合わせて、こっちにしたらどうかな?あるいはこれは?というような形で素早く試すことができます。

複数の機能を1つのシェーダーにまとめるUnityの機能

 実は、Unityのシェーダー記法(ShaderLab)では複数の機能を1つのシェーダー内にまとめておくことができます。また、一部の機能についてはパラメータとして与えることだけで変更可能だったりします。この2つを見ていきましょう。

パラメーターだけで変更可能な機能

 はじめは、パラメータだけで変更可能にできるものを紹介します。こちらはシェーダーの書き方だけで対応できるので、省コストで使いではあるようなものです。以下の指定はパラメータを設定するだけ切り替えることができます。後述の「複数の機能を1つのシェーダーにまとめる」の場合では内部的にシェーダーバリアント数が増えてしまう問題が出ますが、以下の機能の切り替えについてはバリアント数は全く影響しませんので、どんどん使うと良いと思います。

  • アルファブレンドモード指定
  • ZTestのモード指定
  • ZWriteのON, OFF
  • カリングモード指定

 これはブレンドモードをパラメータで変更した例です。上が標準ブレンド(SrcAlpha, OneMinusSrcAlpha)で、下が加算(One, One)です。設定する数字はUnityの定義するBlendModeという列挙体のもつ値で決まっています。ここではSrcAlpha = 5, OneMinusSrcAlpha = 6, One = 1となります。
f:id:sgtech:20171023221854p:plain f:id:sgtech:20171023222012p:plain
f:id:sgtech:20171023222008p:plain f:id:sgtech:20171023222003p:plain

 シェーダーソース側では以下のように書きます。Propertiesブロックで定義した値をBlend指定に与えてあげます。

Properties
{
  _MainTex("Texture", 2D) = "white" {}
  _BlendSrc("Blend Src", Float) = 0
  _BlendDst("Blend Dst", Float) = 0
}
Blend [_BlendSrc] [_BlendDst]

 値を調べて入れるのは手間が多く間違いを誘発しますので、プロパティの値を列挙体の名前から選んで指定する機能を使うとより便利になります。以下のように書きます。

Properties
{
  _MainTex("Texture", 2D) = "white" {}
  [Enum(UnityEngine.Rendering.BlendMode)]_BlendSrc("Blend Src", Float) = 0
  [Enum(UnityEngine.Rendering.BlendMode)]_BlendDst("Blend Dst", Float) = 0
}

f:id:sgtech:20171023222052p:plain

 同じように、ZTestについても与える値はCompareFunctionという列挙体の値を使いますが、指定は似たようなものです。

[Enum(UnityEngine.Rendering.CompareFunction)]_ZTestMode("ZTest Mode", Float) = 0
ZTest [_ZTestMode]

 ZWriteはOFF = 0, ON = 1です。0と1を切り替える場合は、[Toggle]という指定を付けるとインスペクター上ではチェックボックスとなるので便利です。

[Toggle]_ZWriteParam("ZWrite", Float) = 0
ZWrite [_ZWriteParam]

 カリング指定はCullModeという列挙体の値を使います。

[Enum(UnityEngine.Rendering.CullMode)]_CullMode("Cull Mode", Float) = 0
Cull [_CullMode]

 全体のシェーダーコードは以下のようになります。

複数の機能を1つのシェーダーにまとめる

 こちらはかなり骨太な感じの内容となっていますが、実装方法をマスターすると可能性が広がります。
 サンプルとして、グレースケールの元テクスチャに対して、白と黒の部分を別の色に差し替えて利用したいとします。以下のものはフラグメントシェーダーを内容が分かる程度に書いたものです。

fixed4 frag(v2f i) : COLOR
{
  fixed4 t = tex2D(_MainTex, i.uv); //テクスチャの色を取得
  return t;
}

 上のシェーダーがテクスチャの色を表示するだけものに対し、下のものは色を差し替えて表示するものです。

fixed4 frag(v2f i) : SV_Target
{
  fixed4 t = tex2D(_MainTex, i.uv); //テクスチャの色を取得
  fixed lum = Luminance(t.rgb);  //テクスチャの色から輝度を計算
  t = lerp(_LerpColorBlack, _LerpColorWhite, lum); //黒に入れる色、白に入れる色を輝度で補間する
  return t;
}

 これを1つに合体させるには、#ifで処理を切り替えて書き分けるというのがまず最初の作業です。こんな感じになります。

fixed4 frag(v2f i) : SV_Target
{
  fixed4 t = tex2D(_MainTex, i.uv); //テクスチャの色を取得
  #if _USE_LERP_COLOR
    fixed lum = Luminance(t.rgb);  //テクスチャの色から輝度を計算
    t = lerp(_LerpColorBlack, _LerpColorWhite, lum); //黒に入れる色、白に入れる色を輝度で補間する
  #endif
  return t;
}

 あとは、#pragma multi_compileという指定でキーワードに応じたシェーダーのバリアント(バリエーション)を用意することができます。見かけは1つのシェーダーですが、指定されたキーワードに応じて選ばれるシェーダーが自動的に切り替わるというものです。以下のように書きます。

#pragma multi_compile _ _USE_LERP_COLOR

 全体のシェーダーコードは以下のようになります。

 
 これだけだと機能の切り替えがGUIから出来ないので、そちらの部分を作っていきます。機能の切り替えは、マテリアルに対しShaderKeywordを設定することで切り替えることが出来ます。Material.EnableKeywordや、Material.DisableKeywordを使用します。あるいは、Material.shaderKeywordsを直接書き換える方法もとれます。

 GUIから操作させるのに一番いいのは、MaterialのInspectorを乗っ取ることで、機能に合わせて必要なパラメータだけを出したり、それに合わせて上記のShaderKeywordを切り替えたりが行えます。

 Inspectorを乗っ取らずにキーワードON、OFFだけを行うのであれば、プロパティに指定を加えるだけで簡単に設定が可能ですが、その場合は不必要なパラメータを隠すなどの凝った機能を付けることはできません。プロパティだけで行うには以下にようにします。

[Toggle(_USE_LERP_COLOR)]_UseLerpColor("Use Lerp Color", Float) = 0

f:id:sgtech:20171023222049p:plain

 ON、OFFだけの切り替えは上の方法で良いですが、複数の機能を切り替える場合は以下のように書きます。この場合は、Aを選択すると、_USEMODE_AというキーワードがONとなり、Bの場合は、_USEMODE_BがONとなります。

[KeywordEnum(A, B, C)]_UseMode("Mode Change", Float) = 0

f:id:sgtech:20171023222046p:plain

 さて、一番凝った機能を実装できる方法として、MaterialのInspectorを乗っ取るには、シェーダー側で使用するInspectorのクラス名を指定しておく必要があります。指定があると、そのシェーダーをInspectorで表示した際には指定のクラスで描画される事になります。シェーダーの最後に以下のように書き加えます。詳細についてはUnity公式のこちらを見てください。

CustomEditor "LerpColorInspector"

 出来上がったものは以下です。いろいろゴニョゴニョやってますけど、肝となるのはOnInspectorGUI()の中で、shaderKeywordsを取得してきて現在の設定値を得て、それを元にToggleを描画して切り替えスイッチの機能を提供して、また設定値をshaderKeywordsとして書き戻すというところです。
 以下の例では、先程のLerpColor機能のオンオフを切り替えるトグルスイッチを描画して、機能を使用しない場合には関連パラメータを表示しないように細工しています。使わないパラメータを隠すことでアーティストに無駄なことをさせないで済むというやつです。こんな感じで、機能ごとに切り替えを作っていくと良いです。

f:id:sgtech:20171023221859p:plain f:id:sgtech:20171023221903p:plain
f:id:sgtech:20171023221907p:plain f:id:sgtech:20171023221911p:plain

 Inspector用のコードは以下のようになります。

社内で使用しているエフェクト統一シェーダーはこんな感じです

f:id:sgtech:20171023221958p:plain

 機能別にチェックボックスやドロップダウンでモードが切り替えられるようになっており、選択されたモードに応じて有効な設定値が出るようになっています。色々設定してパラメータがいっぱい出ると以下のように長くなります。

f:id:sgtech:20171023223556p:plain

 使える機能を列挙すると以下のような感じですが、一部の機能はすでにUnityに標準で備わっていますのでそろそろ使用頻度を考慮しつつ内容の再検討したほうがいいかもしれないとは思っていますが、ご参考になれば幸いです。

  • マスク機能
  • 色変更機能
    • 輝度の暗い方に色を載せる
    • 明るい方、暗い方にそれぞれ色を差し替える
  • ブレンド機能
    • 標準ブレンド
    • 加算ブレンド
    • 事前α乗算式ブレンド(設定値次第で加算も可能)
  • Z値の操作機能
    • Zテスト無し(最前面描画)
    • Zオフセット
    • ソフトパーティクル
  • UVの操作機能
    • UVスクロール
    • パターンチェンジ
    • UVミラーリング
  • カットオフ機能
    • パンチスルー(1bit抜き)
    • 半透明カットオフ
  • HDR輝度スケーリング
  • RenderQueueの値操作

みなさんも一緒に働きませんか?

 ここまで読んでくださった方、ありがとうございます。
 TAセクションではこのようにアーティストの制作に役立つ環境を提供できるよう力を注いでおります。やりたいことを遠回りせずに行える環境でお仕事したい方はぜひ下記の弊社グループ採用サイトをご確認ください。いっしょに働きましょう!
 現在いろいろな職種でアーティストを多数募集しております!

採用情報 | セガ企業情報サイト

2日間でゲームを作ろう! ~挑戦し続けるSEGA Game Jam~

皆さん初めまして。
セガ・インタラクティブ 第三研究開発部 プログラマの山田です。
普段はアーケードゲームの開発を行っていますが、今回の記事では社内で行っているSGJ(SEGA Game Jam)についてご紹介します。技術的な内容ではありませんが、セガグループのクリエイティビティを養っている活動の一つとして、その様子とメリットをお伝えしたいと思います。

目次

SGJとは?

参加者を募集して即席のチームを作り、テーマに沿ったゲームを短期間で制作するイベントです。
年に1回、世界規模で行われているGGJ(Global Game Jam)の制作期間は48時間ですが、SGJでは34時間とより短めです。
職種や部署に制限はなく、業務ではゲーム開発を行っていない営業部や宣伝部などの方も参加しています。また、普段はプログラマだけど企画をやってみたい!といった試みも気軽に行えます。
SGJは2012年から年に2回ペースで行っていて、先日記念すべき第10回目のSGJが開催されましたので、これからその模様をかいつまんで紹介していきます。

1日目 7/15(土)

8:30~ 受付

朝早くから続々と参加者が集まってきます。
f:id:sgtech:20170924165526j:plain
f:id:sgtech:20170924165509j:plain

参加者には受付と同時に、こちらのSGJ記念Tシャツと缶バッジをプレゼントしました!
f:id:sgtech:20170924165520j:plain
f:id:sgtech:20170924165514p:plain

記念Tシャツのデザインを担当してくれた茂呂さんです。
人との繋がりを大事にしながら楽しいSGJになるようにという思いを込め、エネルギーが沸いてくるようなデザインにしたそうです!
f:id:sgtech:20170924165502p:plain

開会式までの時間を利用して、事前に募集していたテーマの候補に対し1人3票で投票します。
f:id:sgtech:20170924170005j:plain

9:00~ 開会式・テーマ決定・チーム分け

今回は30名の参加者が集い、SGJが開幕します。
f:id:sgtech:20170924170000j:plain
f:id:sgtech:20170924165955j:plain

各自簡単に自己紹介をした後、テーマを決定します。
投票で得票数の多かったものの中からサイコロを振った結果、今回のSGJのテーマは「ライブ」に決まりました!
f:id:sgtech:20170924165949j:plain
テーマの候補から参加者の趣味嗜好が伺えますね(笑)

このテーマ次第で制作するゲームが大きく変わってきます。
過去には「シバエビ」なんてテーマもありました。

次にチーム分けを行います。
参加者が使いたいツールやチャレンジしてみたいことなどをある程度考慮した結果、今回は5チームで制作をすることになりました。

制作開始!
開会式が終わるとチーム毎に分かれ、それぞれアイデア出しを始めます。
f:id:sgtech:20170924170056j:plain
f:id:sgtech:20170924170051j:plain

VRゲームを作ると意気込んでいたチームは早速機材を触り始めます。
f:id:sgtech:20170924170046j:plain
f:id:sgtech:20170924165943j:plain

昼食
そうこうしている内に昼食タイム。
アイデア出しも続けながらチームの親睦も深まります。
f:id:sgtech:20170924170041p:plain
f:id:sgtech:20170924170033p:plain
f:id:sgtech:20170924170247p:plain

昼食の後は企画発表会に向けて作業が始まります。
f:id:sgtech:20170924170241j:plain
f:id:sgtech:20170924170237j:plain
f:id:sgtech:20170924170227j:plain
f:id:sgtech:20170924170221j:plain

15:00~ 企画発表会

作業時間もつかの間、企画発表の時間です。
この時点でチーム名やタイトル名を決めてもらっています。
f:id:sgtech:20170924170410j:plain
f:id:sgtech:20170924170356j:plain
f:id:sgtech:20170924170350j:plain
f:id:sgtech:20170924170342j:plain
f:id:sgtech:20170924170335j:plain
機械学習を取り入れたゲームに挑戦するチームも!
f:id:sgtech:20170924170516j:plain

制作再開!
企画発表の後はα版発表に向けて本格的に動くものを作り始めます。
短時間でやるからこそタスクやスケジュール管理も疎かにはできません。
f:id:sgtech:20170924170510j:plain
f:id:sgtech:20170924170504j:plain
f:id:sgtech:20170924170455j:plain
f:id:sgtech:20170924170611j:plain
f:id:sgtech:20170924170450j:plain
f:id:sgtech:20170924170618j:plain
f:id:sgtech:20170924170606j:plain

第10回記念として、これまでSGJで制作されたゲームの展示コーナーも用意しました。
その数なんと53!
OculusやLeapMotionなどの特殊なデバイスで遊ぶゲームもあります。
f:id:sgtech:20170924171223j:plain

中でもTobii EyeXのアイトラッキングシステムを使ったゲームが注目を集めた模様。
見学者や、参加者が休憩中に遊んで賑わいました。

見学に来てくださった「つくる女」の大河原さん。
f:id:sgtech:20170924171218p:plain

20:00~ α版発表会

開会式から早11時間!α版発表会の時間です。
軽食で英気を養いながら発表に聞き入ります。
f:id:sgtech:20170924170601j:plain
まだ大雑把ですが、各チーム動くものができています。
f:id:sgtech:20170924170552j:plain
f:id:sgtech:20170924170742j:plain
f:id:sgtech:20170924170737j:plain
f:id:sgtech:20170924170731j:plain

制作再開!
α版が終わると再び作業の時間になりますが、明日もあるのであまり無理はしません。
残っているタスクを確認して、今日中にやるものや明日のβ版までにやるものを決めておきます。
f:id:sgtech:20170924170725j:plain
f:id:sgtech:20170924170714j:plain
f:id:sgtech:20170924170856j:plain
f:id:sgtech:20170924170851j:plain
キリの良いところまで終えたら1日目終了です!お疲れ様でした!
f:id:sgtech:20170924170845j:plain

2日目 7/16(日)

2日目の朝は各チーム毎に決めた時間から作業が始まります。
f:id:sgtech:20170924171149j:plain
f:id:sgtech:20170924171142j:plain
f:id:sgtech:20170924171128j:plain

12:00~ β版発表会

午前が終わると共にβ版の発表です!
デザインやサウンドのデータも入ってきて、α版からの変化が伺えます。
f:id:sgtech:20170924170836j:plain
f:id:sgtech:20170924170830j:plain
f:id:sgtech:20170924170953j:plain
f:id:sgtech:20170924170947j:plain
f:id:sgtech:20170924170942j:plain

12:30~ 昼食

β版発表の後は完成に向けて腹ごしらえ!腹が減っては戦ができません。
お寿司やピザに加えて、
f:id:sgtech:20170924173940j:plain
f:id:sgtech:20170924171123j:plain
今回は第10回記念ということでケーキも用意しました!
f:id:sgtech:20170924170937j:plain
f:id:sgtech:20170924170929j:plain

左に写っているのは嬉しそうに「祝」の部分を貰う私。
f:id:sgtech:20170924171053j:plain
この後レッドブルと一緒に食べていたらお腹を壊しました……。

制作再開!
腹ごしらえができたら完成に向けてラストスパートをかけます。
時間との戦いになるので優先度が低いタスクは潔く除外してバグを直したり、入念にゲームバランスを調整したりとゲームのブラッシュアップを行います。
f:id:sgtech:20170924171049j:plain
f:id:sgtech:20170924171043j:plain
f:id:sgtech:20170924171036j:plain
f:id:sgtech:20170924171030j:plain
f:id:sgtech:20170924171154j:plain

そしてついに……

19:00 制作終了!

f:id:sgtech:20170924171232j:plain
やり切ったという人もいればやり残したという人もいますが、これから最終発表会が始まります。
f:id:sgtech:20170924174517j:plain

19:15~ 最終発表会

動画でお伝えできないのが心苦しいですが、どのチームもしっかりゲームができていました!

チーム:ゴトトラ
迫りくるおっさん達を掻い潜り、セガハードガールズをライブ会場に導こう!
f:id:sgtech:20170924174828j:plain
f:id:sgtech:20170924174822j:plain
f:id:sgtech:20170924174815j:plain

チーム:好きなことして生きていく
YouTuberとして人気を獲得し生計を立てるカードバトル!
f:id:sgtech:20170924175115j:plain
f:id:sgtech:20170924175105p:plain
f:id:sgtech:20170924175100p:plain

チーム:婚活研究開発部
超回復でデカい男になり、ラスボスと結婚せよ!
f:id:sgtech:20170924175328j:plain
f:id:sgtech:20170924175335p:plain
f:id:sgtech:20170924175345p:plain

チーム:がんばれ加藤くん1号
ロボットを学習させてゴールを目指そう!
f:id:sgtech:20170924175714j:plain
f:id:sgtech:20170924175710p:plain
f:id:sgtech:20170924175707p:plain

チーム:SPACE BOULDER 7
VR+宇宙空間でボルダリング!
f:id:sgtech:20170924175952j:plain
f:id:sgtech:20170924180011p:plain
f:id:sgtech:20170924175957p:plain

発表会の後に皆で試遊会。VRが大人気です!
f:id:sgtech:20170924180241j:plain
f:id:sgtech:20170924180236j:plain

最後に集合写真をパシャリ。SGJで繋がるセガグループの輪!
f:id:sgtech:20170924180230j:plain
2日間お疲れ様でした!

SGJの効果

さて、第10回SGJの模様を凝縮してご紹介しましたが、参加者には一体どのような効果があるのでしょうか。
毎回アンケートを集計して効果を測定しているので、今回の結果を一部公開します。

f:id:sgtech:20170924180422p:plain

f:id:sgtech:20170924180417p:plain

参加者の多くはSGJの経験が今後の業務にも活用できそうだと感じていることがわかります。
また、どのあたりに効果があったと感じたかという質問に対しては、第一に『モチベーションアップ』、次いで『人脈』、『ゲーム作りの経験』、『スキルアップ』という結果でした。
人により効果は様々ですが、モチベーションや人脈といった目では見えにくい部分に高い効果があることがわかります。私自身もSGJを通して初めて会った人が沢山いますし、SGJで初めて使ったツールもあります。
短期間で行うGame Jamの特性上、経験やスキルアップといった直接的な効果は他と比べて低くなっていますが、逆に短期間で行えるからこそ、「次はこうしてみよう」とか「これはうまくいった」といった振り返りがすぐに行え、繰り返し行うことで経験やスキルアップの効果はさらに高くなると私は考えています。

運営側もこうしたフィードバックを受けつつ毎回振り返りを行い、より有意義なSGJになるよう試行錯誤しています。

まとめ

SGJを開催し始めてから早6年、計10回のSGJを行ってきましたが、参加者からは概ね高い評価を得られていて、横の繋がりが深まるきっかけにもなっています。
この記事を読んでくださった方がGame Jamに興味を持ち、各地で行われているGame Jamに参加することで何かを得るきっかけになれば幸いです。

もちろん、私たちセガグループに加わり一緒にゲームを作りたいという方も大歓迎です!
もしご興味を持たれましたら、セガグループ採用サイトをご確認ください。

採用情報|株式会社セガ・インタラクティブ
採用情報|株式会社セガゲームス -【SEGA Games Co., Ltd.】







モデル協力:セガ・ハード・ガールズ



セガ・ハード・ガールズ公式 HP:http://shg.sega.jp/
公式twitter:アソビン教授(セガ・ハード・ガールズ) @SHG_Official
TVアニメ『Hi☆sCoool! セハガール』公式HP:
http://shg.sega.jp/anime.html

(C)SEGA /セハガガ学園理事会


Powered by はてなブログ