Unityを使ってシェーダーを作る方法を学ぶ連載。今回は、「Cubemap」を使った鏡面反射について解説する。
Unityを使ってシェーダーを作る方法を学ぶ連載「Unityで始めるシェーダー入門」。連載第1回ではシェーダーの概要と作り始めるまでの環境構築を紹介した。
今回は「Cubemap」を使った鏡面反射について解説する。しかし、Unity 5では、「Reflection Probe」で鏡面反射が実現できるので、今回のような作成方法はあまり採られていないかもしれない。しかし、今回はシェーダーの作成が基本となっているので、あえてCubemapを使ってみた。
Cubemapとは、環境の反射を表す正方形6つのテクスチャの集合だ。6つの四角形は、オブジェクトを囲む架空の立方体の面を形成する。各面はワールド軸の方向に沿ったビュー(上、下、左、右、前と後)を表す。
今回、実際に作成するCubemapは図1のようなものになる。
Hierarchyの「Create」→「3D Object」→「Sphere」と選択して1個のSphereをScene画面上に配置する。カメラの位置やSphere位置を調整して図2のような表示にしておく。
新しいScene画面を開き、「Shaders」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Shader」→「Standard Surface Shader」と選択する。新しく作成されたShaderには「CubemapShader」と名前を付けておこう。
次に、「Materials」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Material」と選択する。新しく作成されたMaterialには「CubemapMaterial」と名前を付けておこう。
先ほど作成したCubemapMaterialを選択して、Inspectorを表示させてみよう。Shaderの位置に先ほど作成したCubemapShaderが「Custom/CubemapShader」として関連付けられている。通常は、Standard Surface Shaderとして作成したシェーダーはCustomというグループ名付きで表示される。
CubemapShaderの中身は、これまでの連載通り、Standard Surface Shaderのコードが記述されている。このコードをリスト1のように変更する。
Shader "Custom/CubemapShader" { Properties { _Cube("Cubemap", CUBE) = "" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float3 worldRefl; }; samplerCUBE _Cube; void surf(Input IN, inout SurfaceOutput o) { o.Emission = texCUBE(_Cube, IN.worldRefl).rgb; } ENDCG } FallBack "Diffuse" }
3行目では、プロパティの型が「CUBE」になっているので、InspectorでCubemapを選択する欄が表示されるようになる(図3)。
12〜15行目のInput構造体の中で、プロパティ名_MainTexの前に「uv」と付けることで、自動的にマテリアルのテクスチャ座標設定(TilingとOffset)が適用されたUV座標が入ってくる(図3参照)。また、float3型のworldRefl変数を定義している。これで、surf関数内でサーフェースシェーダオブジェクトの反射ベクトルの値を取得することが可能になる。
20行目では、色と表面から放出される光の強度を制御するo.Emissionに、texCUBE関数の結果を代入している。texCUBE関数では、キューブテクスチャ「_Cube」と反射ベクトル「worldRefl」の値を渡すと、その面に反射する背景の色を取得してくれる。
次に、図3で選択できるCubemapを作成する必要がある。
Cubemapを作成する素材として、Asset Storeから、無料の「Sky5X One」をインポートしておく。インポートしたら、次に、Projectから「Create」→「Legacy」→「Cubemap」と選択する(図4)。すると「New Cubemap」というCubemapが作成される。ここでは、名前はデフォルトのままにしている。
このNew CubemapのInspectorを見ると図5のように、6つの画像(+X、+Y、+Z、-X、-Y、-Z)を指定するようになっている。よってCubemapを作成するには、このように6つに分けられた画像を使用する必要がある。先ほどAsset StoreからインポートしたSky5X Oneのテクスチャはこれに対応している。
まず、Right(+Y)のSelectボタンをクリックしてみよう。すると図6のように「Select Texture2D」のウィンドウが開く。いろいろな画像が表示されているが、下の方までスクロールすると「skyX52+x」という画像がある。
これをCubemapのInspectorのRight(+X)に指定する。Select Texture2Dの中を見ると「skyX52」で+y、+z、-x、-y、-zに対応したものも存在している。これをInspectorのそれぞれの位置に取り込む。全て取り込むと図7のようになる。「Face Size」は「512」程度を指定しておくといいだろう。
すると、New Cubemapは図8のような表示に変わる。
Materialsフォルダ内のCubemapMaterialを選択してInspectorを表示させ、Cubemapの位置に先ほど作成したNew Cubemapを指定する(図9)。
このCubemapMaterialをScene上のSphere上にドラッグ&ドロップする。するとGame画面に図10のように表示される。
Sphereの代わりにCubeを配置して、CubemapMaterialを適用すると図11のように表示される。
これで、鏡面反射を伴ったCubemapの作成が完了した。適当な名前を付けて保存しておこう。
今回は、これで終わりだ。今回のシェーダーのコードは、単にCubemapのInspectorを表示させるためだけなので、難しくなかったはずだ。むしろ、Cubemapの作り方の勉強になったのではないかと思う。Asset StoreからインポートしたSky5X Oneには、今回使用したテクスチャ以外にも、Cubemapに利用できるテクスチャがあるので、各自が試してほしい。
なお、Asset Storeに完成したCubemap用の画像を1パックにしたものが有料で販売されている。いちいち6枚の画像を指定するのは面倒だと思う人は、これを使うと手っ取り早くていいかもしれない。
次回は、「ライティングシェーダー」について解説する。お楽しみに。
薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所
薬師寺国安事務所代表。Visual Basicプログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。
1997年に薬師寺聖とコラボレーション・ユニット「PROJECT KySS」を結成。
2003年よりフリーになり、PROJECT KySSの活動に本格的に参加。.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。
Windows Phoneアプリ開発を経て、現在はWindowsストアアプリを多数公開中。
Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
Microsoft MVP for Development Platforms-Windows Platform Development(Oct 2014-Sep 2015)。
Copyright © ITmedia, Inc. All Rights Reserved.