KLabGames Tech Blog

KLabは、多くのスマートフォン向けゲームを開発・提供しています。 スマートフォン向けゲームの開発と運用は、Webソーシャルゲームと比べて格段に複雑で、またコンシューマゲーム開発とも異なったノウハウが求められる領域もあります。 このブログでは、KLabのゲーム開発・運用の中で培われた様々な技術や挑戦とそのノウハウについて、広く紹介していきます。

カテゴリ: 3D

前回Blenderで作った望遠鏡のモデルのテクスチャを作っていきます。
使用するソフトはSubstance Painter (バージョン2019.3.3)です。

cap01
前回作成したfbxファイルをインポートしました。
メッシュが表示される3Dビューと、その隣にはUVが表示されています。

cap02
右上には前回Blender上でマテリアルを分けた通り、M_Lens/M_Telescopeが並んでいます。 M_Lensは接眼レンズのマテリアルなので、UE4上でマテリアルを組んでリアルタイムにレンダリングされた風景が映るようにします。Substance Painter上の作業はありません。

cap03
M_Telescopeを選択します。すると接眼レンズ以外の部分のUVが表示されます。
デフォルトのレイヤはごみ箱のアイコンを押して削除しておきましょう。

cap04
モデルに質感を加えていくのにはブラシで色(マテリアル)を塗る方法と、Smart materialをレイヤーにのせる方法があります。
今回は後者の方法のみを使って望遠鏡のテクスチャを作ります。
Smart materialsの中から好きなものを選んでレイヤにのせ、パラメータを調整するという作業なので誰がやっても同じ見た目を作る事が出来ます。

cap05
まずはベースとなるSmart materialを選びます。Copper Red Bleachedがいいでしょう。

cap06
レイヤにドラッグ&ドロップします。
すると3DビューやUVのビューに質感が加わります。

cap07
次に持ち手の部分に革のマテリアルをあてます。
Leather Creasedを使います。

cap08
先ほどのCopper Red Bleachedより階層が上になるようにレイヤにのせます。
これだけだと全体が革張りになってしまいますのでマスクを使って持ち手の部分にだけLeather Creasedが適用されるように設定しましょう。

cap09
レイヤ上のLeather Creasedを右クリックして「黒のマスクを追加」を選択します。

cap10
レイヤ上のLeather Creasedで追加されたマスクの方に青枠が当たっていることを確認して、左端のメニューからPolygon Fillを選びます。
すると3DモデルとUVにワイヤーフレームの表示がかかります。
この状態で持ち手の部分のポリゴンを選択しましょう。
3DビューからもUVのビューからも選択できます。今回の場合はUVから上部の長方形を選択するのが簡単だと思います。

cap11
するとこのような見た目になります。
凹凸や光の反射具合など革の質感はそのままに、もう少し赤に近い茶色に色を変えていきたいと思います。

cap12
レイヤ上のLeather Creasedのフォルダアイコンをクリックすると、Smart materialの詳細な項目が表示されます。
その中のBaseを選んで下のPROPERTIESパネルからBase Colorを探し出して色を赤茶色っぽく変更します。

cap13
3Dビューで見た目を確認するとこのようになります。

cap14
持ち手の革と同様の方法で対物レンズにもSmart materialをあてて完成です。Glass Visorがオススメです。

cap15
最後にテクスチャのエクスポートを行います。
ファイル > Export Textures を選択すると画像のような画面が開きます。
エクスポート先のパスを設定して、ConfigにはUnreal Engine 4(Packed)を選択します(この他にもUnity用など様々なConfigが用意されています)。
Texture setsではM_Lensが不要なのでチェックを外し、M_Telescopeのテクスチャだけエクスポートされるように設定します。
上記の設定が終わったらエクスポートボタンを押します。

cap16
BaseColor / NormalMap / OcclusionRoughnessMetallic の3つのテクスチャがエクスポートされれば成功です。

以上でテクスチャ製作は終了です。
今回はブラシを使う方法ではなくSmart materialをレイヤに載せてパラメータ調整する方法を紹介しました。 この方法であれば本職のアーティストでなくとも簡単な操作でクオリティの高いテクスチャを作る事が出来ます。
プロの間でデフォルトとなりつつあるSubstance Painterですが、本職ではない私のような人にもおススメしたいツールです。

テクスチャをエクスポートできたのでUE4上での作業を進める準備が整いました。 ですがその前に今回のテクスチャの見た目をBlender上で確認する方法を次回見ていきましょう。

fmystB

こんにちは。
KLabでVRの研究開発をしているfmystBです。
普段3Dのゲームを開発しているプログラマですが、アセットの制作も行っています。
今回から数回に分けて、研究室内で作っているデモの一部を紹介します。

VR研究開発で使用するツール

ゲームエンジンはUE4を使用しています。
アセットの制作は、モデリングにはBlender2.81(連載中にアップデートされたら都度バージョンを上げます)、テクスチャはSubstance Painterを使用しています。
アニメ調のものではなく、フォトリアルなデモを作っているのでこの組み合わせは使いやすいです。
この連載ではBlenderでのモデリング・UV展開、Substance Painterでのテクスチャ作成、UE4でのマテリアル作成やプログラム開発といった、VRデバイスでプレイ可能な作品を作るための一連の流れを紹介していきます。

Blender2.81

今回の記事ではBlenderでの作業を紹介していきます。
この記事を書いている時点での最新版2.81を使用します。
バージョンが2.8になってからEpic Gamesが資金を提供するなど、ここ最近ますます勢いを増しているツールです。

VRで面白アイテムを作りたい!!

デスクトップ向けのゲームではなく、VRという環境なのでより現実に近い体験を3D空間の中に作り出したい。そんな思いで研究開発を進めています。そこでVRで利用できる面白アイテムを多数作っているのですが、今回はその中の一つ、望遠鏡の作り方を紹介します。
実際にVRデバイス(VIVE)でプレイした映像↓

動画のように昔の海賊をイメージしたアンティークな仕上げにします。

オブジェクトのサイズと向き

それでは作業を始めていきましょう! 望遠鏡の全長は30cmとします。 接眼レンズ側が原点に、対物レンズ側がX軸上の30cmのところに来るようモデリングを進めていきます。
Capture001
デフォルトのCubeのサイズは2m×2m×2mです。
Capture002
Capture002a
テンキーの1を押し-Yから+Yへの視点にして、マウスホイールをスクロールして1マスのサイズ(画像の①)が10 Centimetersになるように拡大していきます。この1マスのサイズは②がorthographic(平行投影)になっているときのみ表示されるもので、テンキー1/3/7で視点をY/X/Z軸方向に調整したときは自動的に平行投影になります。

View Clip の調整

視点がオブジェクトに接近すると
Capture003
のように手前側の表示が欠けてしまう事があります。これを避けるために3Dview上でNキーを押して出てくるメニューでClip startの値を調整します。今回は0.001mまで下げておけば十分でしょう。 Capture005

モデリング

Capture006
デフォルトのCubeを削除し、Cylinderを追加してオブジェクト名をTelescopeに変更します。
Capture007
Edit Modeに切り替えて以下の操作にてモデリングを進めます。

キー 操作
G 移動
R 回転
S 拡大縮小
E 押し出し

G/R/Sの操作はCtrlキーを押しながらマウスを動かすことでキリの良い数値に調整することができます。
3D view上で(テンキーではない)キーボードの3を押して面選択モードに切り替えておきます。(左上の方のアイコンからも切り替えることが可能です。)
まずRキーで全体を90度回転させてX軸方向を向くようにたおします。
次にSキーで底面の直径が4cmになるように縮小します。
その後接眼レンズ側が原点に来るようにGキーで移動し、反対側の面のみを選択して10cmの位置に来るようにします。
そこからEキーを押して真ん中の筒を作ります。大きさは直径5cmになるように調整します。
同様に対物レンズ側の筒も作ります。直径は6cmです。

Capture008
Loop Cutを使い、3つの筒に線を入れます。(Loop Cutをすることで辺選択モードに自動的に切り替わります。)
線が入ったら再び面選択モードに切り替えて
Capture009
の面を1周選択(altキーを押しながら選択することでループ選択になります。)してEキーで押し出して少し拡大します。

対物レンズを作ります。 Capture010
Capture011
Inset Facesを使用して筒の底面の中心に向かって面を作ります。
Capture012
Eキーで内側に凹ませます。
接眼レンズも同じように作りましょう。

対物レンズ側の一番太い筒には後で古い皮のテクスチャを貼りたいのでLoopCutで辺を1周追加しておきます。 Capture013

シェーディング(法線の向き)

デフォルトでは全ての面がFlat Shadeになっているはずです。
Capture014
画像のように曲面をすべて選択してSmooth Shadeにしましょう。
レンズやそれぞれの筒の底面などX軸方向に法線が向いている面はFlat Shadeのままにしてください。

マテリアル

Capture015
マテリアルを2つ作ります。 M_Lens:接眼レンズ
M_Telescope:対物レンズを含む望遠鏡本体
M_という表記はUE4の命名規則を意識しています。
接眼レンズにはUE4上でメインのカメラとは別のカメラで撮影した風景を映し出す特殊なマテリアルの効果を割り当てるため、他の面のマテリアルとは分けておきます。
対物レンズは特に何も映し出さず、その他の部分と同じ扱いをするのでM_Telescopeの方にAssignしてください。

UV展開

3D view上で(テンキーではない)キーボードの2を押して辺選択モードに切り替えておきます。 Capture016
画像のように選択してMark SeamしてUVの切れ目を入れます。 両方のレンズは1周選択して丸ごと切り取り、筒の一番下のラインをすべて選択して切れ目を入れることにより、筒のUVを平面に開くことができます。
一番太い筒の皮のテクスチャを貼る部分は別に切り取っておきましょう。

Capture017
UV EditingタブでUV展開用の画面を開き、接眼レンズ以外を選択してUキーでUV Mappingメニューを開いてUnwrapを選択しましょう。
選択した面のみ左側の画面にUV展開されます。UVの面は大きくとるほどテクスチャの解像度を広く利用できるのでギリギリまで広げておきます。

Capture018
次に接眼レンズを選択してテンキー1でY軸方向に視点を向けて今度はUnwrapではなく、Project from View (Bounds)を選択しましょう。 そうすると現在選択されている接眼レンズを3D Viewの視点から真っすぐにUV展開してくれて、サイズも最大限確保してくれます。

エクスポート

完成図は
Capture019
こんな感じです。
この後Substance Painterを使ってテクスチャを作るわけですが、Substance Painter / UE4 の両方にインポートできるようにFBX形式でエクスポートしましょう。 Telescopeオブジェクトのみが選択された状態で、
Capture020
File > Export > FBX(.fbx) を選択します。
Selected Objectsにはチェックを入れて、選択されたTelescopeオブジェクトのみがエクスポートされるようにします。こうすることでその他のカメラやライトを排除してFBX化することができます。 また、上記のモデリングでは全長3mの望遠鏡になっているので、Scaleを0.1にして30cmの大きさにエクスポートします。

Blenderでのモデリング作業はこれで終了です。
今回作ったFBXを使って、次回Substance Painterでテクスチャを作っていきます。

fmystB

 このエントリーは、KLab Advent Calendar 2015 の12/21の記事です。

 KLab の EM 部とクリエイティブ部テクニカルアーティストグループでテクニカルアーティストをしている(長い…) YuichiSato です。よろしくお願いします。

 普段の業務では Unity 上の C# で 3D グラフィクスゲームを作っている事が多いのですが、Smalltalk 好きとしては「3D グラフィクスプログラムも Smalltalk で書きたいなぁ」と思います。 Smalltalk で 3D グラフィクスプログラミングと言えば、Jun for Smalltalk や最近では Jun4Pharo があります。しかしながら、作ったものを気軽に多くの人に見てもらうには不便です。

 やはり、そういう場合は Web で公開できると便利です。こちらの tetha さんの記事「amber Smalltalk で knockout.js を使ってみた」 を見ると、JavaScript による Smalltalk 処理系の Amber Smalltalk(以下、Amber と略) と WebGL を使えば実現出来そうです。さすがに生の WebGL だとしんどいので、Three.js を Amber で使える様にしてみました。

事前準備

 以下が必要になりますので、インストール等を済ませておきます。使用したバージョンは括弧内の通りです。

  • Node.js(v5.2.0)
  • Bower(1.7.0)
  • Grunt(v0.1.13) <- grunt-cli のバージョン

なお以下では、環境は MacOSX(10.11) で Web ブラウザは Chrome を使いました。こちらのページなどで WebGL が有効になっていることを確認しておきましょう。

Amber の設定と初期化

 まずはこちらに従って Amber の設定を行います。

 次にプロジェクトのディレクトリを作成して Amber の初期化を行います。

% mkdir AmberThreeJS
% cd AmberThreeJS
% amber init

 以下のように入力を求められるので、適当に入力をします。今回はプロジェクト名以外はデフォルトで入力しました。

Please answer the following:
[?] Project title (Application or Library Title) AmberThreeJS
[?] Main class and package of Amber application.
Project name is derived by lowercasing this. (Amberthreejs) 
[?] Description (The Application or The Library doing The Thing.) 
[?] Author name (none)        
[?] Author email (none) 
[?] Namespace of the new Amber package. (amber-amberthreejs) 
[?] Version (0.1.0) 
[?] Project git repository (git://github.com/AccountName/AmberThreeJS.git) 
[?] Project homepage (https://github.com/AccountName/AmberThreeJS) 
[?] Project issues tracker (https://github.com/AccountName/AmberThreeJS/issues) 
[?] Author url (none) 
[?] Licenses (MIT) 
[?] Do you need to make any changes to the above before continuing? (y/N) 

 次の様にしてサーバーを立ち上げ、ブラウザから http://127.0.0.1:4000 にアクセスして動作を確認します。(任意の IP アドレスで立ち上げたい場合はこちらのようにします。)

% amber serve

IDE を選択するダイアログが出てきます。以降では "Helios IDE" を使って説明します。(ポップアップウィンドウを許可する必要があります)

select_ide

アクセス出来ることを確認したら、サーバーは一旦 Ctrl-C で止めておきましょう。

Three.js のインストールと設定

 次に Three.js をインストールします。

% bower install threejs -save

 インストールが出来たら Amber から使えるよう設定を行います。three.js.amd.json というファイルを作成して、以下の様に記述します。今回は ./bower_components/three.js/build/three.js を読みに行きたいので次の様になります。

{
  "paths": {
    "threejs": "build/three"
  }
}

 ファイルの作成が出来たら、次のコマンドを実行します。

% grunt devel

 無事に実行出来たら、config.js, the.js の二つのファイルが作成(または更新)されます。そしたら改めて

% amber serve

でサーバーを立ち上げます。

 ここからは Amber での作業になります。Browser から作成したパッケージを選択して importsthreejs を追加します。

add_threejs_for_imports

追加したら "SaveIt", "Commit package" して、ブラウザでリロードしましょう。これで、Three.js が使えるようになります。ブラウザのデベロッパーツールの JavaScript コンソールから THREE が有効になっていることが確認できます。

console_three

 また、IDE の Workspace からも THREE を "InspectIt" することが出来ます。IDE から Smalltalk のクラスとして確認できると最高なのですが、THREE の Smalltalk のソースコードがあるわけではないので、見ることが出来ません。残念!(最初から入っている jQuery も同様)

サンプルが動くようにしてみる

 まずはこちらの一番下にあるサンプルを動かしてみます。そのまま Amber で動くように書き下すと以下のようになります。

augmentPage
    | scene camera width height renderer geometry material cube render renderBlock |
    scene := THREE Scene new.
    
    width := window innerWidth.
    height := window innerHeight.
    camera := THREE PerspectiveCamera newWithValues: #(75 (width / height) 0.1 1000).

    renderer := THREE WebGLRenderer new.
    renderer setSize: width h: height.

    document body appendChild: renderer domElement.

    geometry := THREE BoxGeometry newValue: 1 value: 1 value: 1.
    material := THREE MeshBasicMaterial newValue: #{ 'color' -> 16r00ff00 }.
    cube := THREE Mesh newValue: geometry value: material.
    scene add: cube.

    camera position z: 5.

    renderBlock := [| x y |
        window requestAnimationFrame: renderBlock.

        cube rotation x: cube rotation x + 0.1.
        cube rotation y: cube rotation y + 0.1.

        renderer render: scene camera: camera.
    ].

    renderBlock value.

これでリロードすると JavaScript としても特にエラーは出ず、canvas 要素が真っ黒に塗りつぶされはしますが、描画されるはずの緑色の立方体が描画されません。そこで原因を調べてみました。オブジェクトを調べるために、コンソールにログ出力をすると次のような違いがあることが分かりました。

 最初の "THREE.WebGLRenderer 73" から次までが正しく描画されない場合、それ以降が正しく描画される場合の出力です。

diff_objects

 正しく描画される場合はオブジェクトのタイプがきちんと出力されていますが、そうでない場合は Object になっているものが多くあります。Object になっていないものといるもので違いをみると、インスタンスを引数ありで生成すると Object になるようです。

 そこで IDE から生成のためのメソッドを調べてみました。 JavaScript のオブジェクトは BlockClosure のインスタンス扱いになっているため、そのメソッドを調べます。生成のためのメソッドは

  • new 引数なし
  • newValue: 引数一つ
  • newValue: value: 引数二つ
  • newValue: value: value: 引数三つ
  • newWithValues: 引数複数

があり、それぞれのメソッドを見てみると new

new
    "Use the receiver as a JS constructor.
    *Do not* use this method to instanciate Smalltalk objects!"
    <return new self()

と素直に生成しています。次の三つは内部で newWithValues: メソッドを使っているので、その実装を見てみると

newWithValues: aCollection
    "Simulates JS new operator by combination of Object.create and .apply"
    <
        var object = Object.create(self.prototype);
        var result = self.apply(object, aCollection);
        return typeof result === "object" ? result : object;
    >

となっていて、これが先ほどの違いになっているようなことが分かりました。そこで、影響がありそうなオブジェクト生成時には new を使うようにしたところ、無事に描画できるようになりました。

rendering

 最終的なコードは次のようになりました。(便宜上、メソッド分割はしていません)

augmentPage
    | scene camera renderer geometry material cube width height renderBlock |

    width := window innerWidth.
    height := window innerHeight.
    
    scene := THREE Scene new.
    camera := THREE PerspectiveCamera new.
    camera fov: 75;
            aspect: width / height;
            near: 0.1;
            far: 1000;
            updateProjectionMatrix.
    
    renderer := THREE WebGLRenderer new.
    renderer setSize: width h: height.
    
    document body appendChild: renderer domElement.

    geometry := THREE BoxGeometry newValue: 1 value: 1 value: 1.
    material := THREE MeshBasicMaterial newValue: #{ 'color' -> 16r00ff00 }.
    cube := THREE Mesh newValue: geometry value: material.
    scene add: cube.
    
    camera position z: 5.
    
    renderBlock := [
        window requestAnimationFrame: renderBlock.
        
        cube rotation x: cube rotation x + 0.1.
        cube rotation y: cube rotation y + 0.1.
        
        renderer render: scene camera: camera.
    ].
    
    renderBlock value.

 ということで、Amber で Three.js を使って 3D グラフィクスプログラミングが出来るようになりました!Smalltalk で書けるので満足感は高いものの、やりやすいかというと正直微妙なところですね…。実をいうと IDE よりもデベロッパーツールとにらめっこしている時間の方が長かったですし。

 とはいえ Amber の理解が深まって良かったです。

Smalltalk への誘い

 この記事を見て Smalltalk に興味を持たれた方はぜひ、本格的な Smalltalk 環境で本来のオブジェクト指向を体験してみてはいかがでしょうか?無料で手に入るメジャーなところでは

  • Squeak <- マルチメディア機能も豊富な楽しい処理系
  • Pharo <- ビジネスっぽく洗練されたクールな処理系

あたりがあります。

明日は、wankoさんです。お楽しみに。

↑このページのトップヘ