シェーダーでオブジェクトを鏡面反射させるにはUnityで始めるシェーダー入門(8)

Unityを使ってシェーダーを作る方法を学ぶ連載。今回は、「Cubemap」を使った鏡面反射について解説する。

» 2018年06月07日 05時00分 公開
[薬師寺国安PROJECT KySS]

 Unityを使ってシェーダーを作る方法を学ぶ連載「Unityで始めるシェーダー入門」。連載第1回ではシェーダーの概要と作り始めるまでの環境構築を紹介した。

 今回は「Cubemap」を使った鏡面反射について解説する。しかし、Unity 5では、「Reflection Probe」で鏡面反射が実現できるので、今回のような作成方法はあまり採られていないかもしれない。しかし、今回はシェーダーの作成が基本となっているので、あえてCubemapを使ってみた。

 Cubemapとは、環境の反射を表す正方形6つのテクスチャの集合だ。6つの四角形は、オブジェクトを囲む架空の立方体の面を形成する。各面はワールド軸の方向に沿ったビュー(上、下、左、右、前と後)を表す。

 今回、実際に作成するCubemapは図1のようなものになる。

図1 作成したCubemap

 Hierarchyの「Create」→「3D Object」→「Sphere」と選択して1個のSphereをScene画面上に配置する。カメラの位置やSphere位置を調整して図2のような表示にしておく。

図2 Scene画面上にSphereを配置した。Game画面の確認もできる

「Cubemap」を使った鏡面反射のシェーダー

 新しい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"
}
リスト1 CubemapShaderのコード

 3行目では、プロパティの型が「CUBE」になっているので、InspectorでCubemapを選択する欄が表示されるようになる(図3)。

図3 Cubemap選択の欄が表示されている

 12〜15行目のInput構造体の中で、プロパティ名_MainTexの前に「uv」と付けることで、自動的にマテリアルのテクスチャ座標設定(TilingとOffset)が適用されたUV座標が入ってくる(図3参照)。また、float3型のworldRefl変数を定義している。これで、surf関数内でサーフェースシェーダオブジェクトの反射ベクトルの値を取得することが可能になる。

 20行目では、色と表面から放出される光の強度を制御するo.Emissionに、texCUBE関数の結果を代入している。texCUBE関数では、キューブテクスチャ「_Cube」と反射ベクトル「worldRefl」の値を渡すと、その面に反射する背景の色を取得してくれる。

Cubemapの作成

 次に、図3で選択できるCubemapを作成する必要がある。

 Cubemapを作成する素材として、Asset Storeから、無料の「Sky5X One」をインポートしておく。インポートしたら、次に、Projectから「Create」→「Legacy」→「Cubemap」と選択する(図4)。すると「New Cubemap」というCubemapが作成される。ここでは、名前はデフォルトのままにしている。

図4 Cubemapを選択する

 このNew CubemapのInspectorを見ると図5のように、6つの画像(+X、+Y、+Z、-X、-Y、-Z)を指定するようになっている。よってCubemapを作成するには、このように6つに分けられた画像を使用する必要がある。先ほどAsset StoreからインポートしたSky5X Oneのテクスチャはこれに対応している。

図5 CubemapのInspector、6枚の画像を指定するようになっている

 まず、Right(+Y)のSelectボタンをクリックしてみよう。すると図6のように「Select Texture2D」のウィンドウが開く。いろいろな画像が表示されているが、下の方までスクロールすると「skyX52+x」という画像がある。

図6 Slelect Texture2Dに含まれるCubemap用のテクスチャ

 これをCubemapのInspectorのRight(+X)に指定する。Select Texture2Dの中を見ると「skyX52」で+y、+z、-x、-y、-zに対応したものも存在している。これをInspectorのそれぞれの位置に取り込む。全て取り込むと図7のようになる。「Face Size」は「512」程度を指定しておくといいだろう。

図7 全てのテクスチャを指定した

 すると、New Cubemapは図8のような表示に変わる。

図8 New Cubemapにテクスチャが適用された

CubemapMaterialの設定

 Materialsフォルダ内のCubemapMaterialを選択してInspectorを表示させ、Cubemapの位置に先ほど作成したNew Cubemapを指定する(図9)。

図9 CubemapMaterialにNew Cubemapを指定した

 このCubemapMaterialをScene上のSphere上にドラッグ&ドロップする。するとGame画面に図10のように表示される。

図10 SphereにCubemapMaterialが適用された

 Sphereの代わりにCubeを配置して、CubemapMaterialを適用すると図11のように表示される。

図11 CubeにCubemapMaterialを適用した

 これで、鏡面反射を伴ったCubemapの作成が完了した。適当な名前を付けて保存しておこう。

次回は、「ライティングシェーダー」について

 今回は、これで終わりだ。今回のシェーダーのコードは、単にCubemapのInspectorを表示させるためだけなので、難しくなかったはずだ。むしろ、Cubemapの作り方の勉強になったのではないかと思う。Asset StoreからインポートしたSky5X Oneには、今回使用したテクスチャ以外にも、Cubemapに利用できるテクスチャがあるので、各自が試してほしい。

 なお、Asset Storeに完成したCubemap用の画像を1パックにしたものが有料で販売されている。いちいち6枚の画像を指定するのは面倒だと思う人は、これを使うと手っ取り早くていいかもしれない。

図12 CubemapをパックにしたAsset「Skybox and Cubemap Variety」

 次回は、「ライティングシェーダー」について解説する。お楽しみに。

参考書籍

著者プロフィール

薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所

薬師寺国安事務所代表。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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。