連載
» 2018年06月21日 05時00分 公開

Unityで始めるシェーダー入門(9):カスタムライティングモデルを使用した、影を付けるシェーダー

Unityを使ってシェーダーを作る方法を学ぶ連載。今回はカスタムライティングモデルを使用した、影を付けるシェーダーを扱う。

[薬師寺国安,PROJECT KySS]

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

 今回は、「カスタムライティングモデル」を使用した、3Dキャラクターに影を付けるシェーダーの書き方を解説する。カスタムライティングモデルとは自作のライティングモデルのことだ。Standard Surface Shaderを基に作成したシェーダーは自作(Custom)シェーダーとなる。

 今回、ライティングを適用した3Dキャラクターは図1のように表示される。影と一緒にテクスチャも指定している。

図1 テクスチャと影の付いた3Dキャラクター

 以前の連載でインポートしておいた、EthanキャラをScene上に2体配置しておこう(図2)。カメラはキャラクターの位置を調整して図2のような表示になるようにする。

図2 Scene画面上にEthanキャラを2体配置した。Game画面での確認もできる

「CustomlightingShader」の中身を確認

 新しいScene画面を開き、「Shaders」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Shader」→「Standard Surface Shader」と選択する。新しく作成されたShaderには「CustomlightningShader」と名前を付けておこう。

 次に、「Materials」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Material」と選択する。新しく作成されたMaterialには「CustomlightningMaterial」と名前を付けておこう。

 先ほど作成したCustomlightningMaterialを選択して、Inspectorを表示させてみよう。Shaderの位置に先ほど作成したCustomlightningShaderが「Custom/CustomlightningShader」として関連付けられている。通常は、Standard Surface Shaderとして作成したシェーダーはCustomというグループ名付きで表示される。

 CustomlightingShaderの中身は、これまでの連載通り、Standard Surface Shaderのコードが記述されている。このコードをリスト1のように変更する。

Shader "Custom/CustomlightingShader" {
    Properties{
        _MainTex("Texture", 2D) = "white" {}
    }
    SubShader{
        Tags{ "RenderType" = "Opaque" }
        CGPROGRAM
 
        #pragma surface surf SimpleLambert
 
        struct Input {
            float2 uv_MainTex;
        };
 
        sampler2D _MainTex;
        void surf(Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
        }
 
        half4 LightingSimpleLambert(SurfaceOutput s, half3 lightDir, half atten) {
            half NdotL = dot(s.Normal, lightDir);
            half4 c;
            c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 3);
            c.a = s.Alpha;
            return c;
        }
        ENDCG
    }
    Fallback "Diffuse"
}
リスト1 SliceShaderのコード

 9行目では、シェーダーの#pragmaディレクティブを、Standardの代わりにカスタムライティングモデル(SimpleLambert)を使用するように変更している。後述するカスタムライティングモデルである「LightingSimpleLambert」関数を呼び出すために必要だ。

 11〜13行目のInput構造体では、テクスチャをカスタムライティングモデル(LightingSimpleLambert関数)の中で使用できるようにしている。変数名「_MainTex」の前に「uv」と付けることで、自動的にマテリアルのテクスチャ座標設定(TilingとOffset)が適用されたUV座標が入ってくる。

 17行目では、Cgの「tex2D」関数を使って、該当するテクスチャ座標の色を参照している。tex2D関数は、UV座標(uv_MainTex)からテクスチャ(_MainTex)上のピクセルの色を計算して返す関数だ。

 20〜26行目のLightingSimpleLambert関数が、今回の肝となる部分だ。9行目で、#pragmaディレクティブの「SimpleLambert」の先頭に、「Lighting」を付けたものが関数名になっている。LightingSimpleLambert関数の中では、ライティングの処理を書いている。引数では、サーフェースシェーダーからの出力(SurfaceOutput s)、ライトの方向ベクトル(half3 lightDir)、ライトの減衰値(half atten)を受け取る。

 21行目では、ベクトルの各要素に係数を乗算するのに、「dot」関数を使用し、光源の方向を向いているほど明るくなるように、光の当たっている量を計算している。ベクトルの内積を取得して、NdotL変数に代入しているのだ。

 22行目では、halfを4要素含んだベクトルとして表している。

 23行目では、光のブロック率を出している。サーフェースシェーダーからの出力された色に対して、「_ LightColor0.rgb」(ライトの色)とNdotL(先ほど計算した光源の影響による明るさ)と「atten(減衰) * 3」を乗算している。乗算している「3」という数値を変更すると、影の濃淡が変わる。

CustomlightingMaterialのInspectorを設定する

 CustomlightingMaterialのInspectorを開き、TextureのSelectボタンから図3のテクスチャを選択する。影の濃淡は、シェーダーの中で設定しているので(23行目)、Inspectorには表示されない。

図3 テクスチャを選択した

 このマテリアルをScene画面上の2体の3Dキャラクターにドラッグ&ドロップすると、図4のような表示になる。テクスチャと影が付いて表示されている。

図4 テクスチャと影が付いて表示された3Dキャラクター

次回は、身体に雪が降ったようなシェーダーを作る

 今回は、なかなか難しかったのではないだろうか。肝は、LightingSimpleLambert関数の処理だと思う。簡単に言うと、この関数の中で「光の当たる量を調整してオブジェクトに反映させている」ということになる。参考として「サーフェイスシェーダーライティングの例」のページを紹介しておく。

 次回は最終回で、身体に雪が降ったようなシェーダーを作るので、お楽しみに。

参考書籍

著者プロフィール

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

薬師寺国安事務所代表。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のメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。