検索
連載

サーフェースシェーダーのリムライティングで3Dモデルをガラスのように表示させるUnityで始めるシェーダー入門(6)

Unityを使ってシェーダーを作る方法を学ぶ連載。今回はサーフェースシェーダーのリムライティングを扱う。

Share
Tweet
LINE
Hatena

サーフェースシェーダーの「リムライティング」とは

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

 今回はサーフェースシェーダーのリムライティングについて解説する。今回紹介する「リムライティング」とは、3Dモデルの輪郭が強調されて中心が半透明な、ガラスのような感じになるシェーダーだ。先に、シェーダーを適用した結果を図1に示しておこう。


図1 今回のシェーダーで実装される処理の結果

 連載第1回でインポートしておいた、「Ethan」というキャラクターの3DモデルをScene画面上に2体配置しておこう。カメラの位置やEthanの位置を調整して図2のように配置しておく。


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

リムライティングを実装するシェーダー

 まず、連載第1回で作成した「Shaders」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Shader」→「Standard Surface Shader」と選択する。新しく作成されたShaderには「RimlightingShader」と名付けておこう。

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

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

Shader "Custom/RimlightingShader" {
    Properties{
        _Color("Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _DotProduct("Rim effect", Range(-1,1)) = 0.25
    }
    SubShader{
        Tags{
            "Queue" = "Transparent"
            "RenderType" = "Transparent"
        }
        LOD 200
        Cull Off
        CGPROGRAM
        
        #pragma surface surf Lambert alpha:fade
        sampler2D _MainTex;
        fixed4 _Color;
        float _DotProduct;
    
        struct Input {
            float2 uv_MainTex;
            float3 worldNormal;
            float3 viewDir;
        };
        void surf(Input IN, inout SurfaceOutput o) {
            float4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            float border = 1 - (abs(dot(IN.viewDir, IN.worldNormal)));
            float alpha = (border * (1 - _DotProduct) + _DotProduct);
            o.Alpha = c.a * alpha;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
リスト1 RimlightningShaderのコード

 2〜6行目のPropertiesの中で、Inspector内に表示させる項目名と型を宣言している。

 5行目はプロパティ変数名が「_DotProduct」で、インスペクターに表示するのが「Rim effect」という項目名で、変数の型には「Range」を使用して範囲制限付きのスライダーを表示することを意味する。規定値は「0.25」としておく。

 13行目では、使用するオブジェクトの種類に応じて、その裏面が表示されるようにすることができる。このような場合は、モデルの背面が削除(カリング)されないように「Cull Off」を追加する。

 16行目では、非常に手軽なランバート反射率を使用している。さらに「alpha:fade」を用いた透明シェーダーを「Cg」に送る。

 21〜25行目のInput構造体では、Unityが現在のビュー方向とワールド法線方向を入力するように、入力構造を変更するための、各変数名の定義を行っている。

 今回のシェーダーはオブジェクトのシルエットのみを表示することで機能する。オブジェクトを別の角度から見ると、その輪郭が変わる。幾何学的に言えば、モデルのエッジは、法線方向が現在のビュー方向に対して直交(90度)である全ての三角形だ。

 Input構造体では、それぞれworldNormal(オブジェクトの法線ベクトル)とviewDir(視線ベクトル)というパラメーターを宣言している。

 2つのベクトルが直交するときの問題は、dot関数で「視線ベクトル」と「法線ベクトル」との内積を使用して解くことができる(29〜30行目)。この辺りは、ちょっと難しいので、このシェーダーをScene上に配置したSphere(球体)に適用させて、実際にどのように表示されるかを見てみよう。図3のように表示される。


図3 SphereにRimlightingMaterialを適用させた

 図3を見ると分かるが、Sphereの輪郭部分は透明度が低く、中央部分は透明度が高くなっている。輪郭部分では視線ベクトル(カメラから見た位置)と法線ベクトルが垂直近い角度で交わるが、中央部分では並行に近い角度で交わる。

 このベクトルが交わる角度を透明にすればいい。そのためには、29行目で、内積の値を取得し、垂直に交わる場合は透明度を1、並行の場合は透明度を0にするために、絶対値(abs)を取って1から差し引いている。よって、垂直に交わる場合は1、並行に交わる場合は0となる。この値を変数borderに代入している。平行に交わる中心部分が透明化されていくわけだ。

 31行目では、最終的な見栄えを決定するために、テクスチャの元のalphaに新たに計算された係数を掛けてAlphaに指定している。

実行結果

 MaterialsフォルダにあるRimlightningMaterialを選択してInspectorを表示させると、図4のように表示される。Colorには水色を選択。Rim Effectのスライダーを動かすと、中央部分の透明度が変化する。


図4 TimlightningMaterialのInspector

 このマテリアルを図2の2体の3Dモデルにドラッグ&ドロップする。すると図5のような表示になる。


図5 3Dモデルがガラスのような表示になっている

次回は、オブジェクトのスライスについて

 次回は、オブジェクトのスライスについて解説する。お楽しみに。

参考書籍

著者プロフィール

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

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

ページトップに戻る