オブジェクトの見え方はシェーダーによって決まります。
Unity のバージョン 3 と 4 のシェーダーマッピングは Unity 5 以降のそれとは違う挙動をします。古いシェーダーマッピングは Unity 5 以降でもまだ、サポートされています。後述の古いマテリアルマッピングを参照してください。
Unity 3 や 4 では、ライトマッパーのマテリアルプロパティにはマテリアルプロパティの簡易なマッピングをそのまま使っていました。一般的なケースには機能しましたが、ネーミング規則、タグ、文字列に基づいていました。特定の挙動をするように効果的にハードコードされていたため、サーフェスプロパティをカスタムすることはできませんでした。Unity 5.0 以降では柔軟なシェーダーマッピングを行えます。
アルベドとエミッシブは特別なメタシェーダーパスを使ってレンダリングされます。ライトマップの静的ゲームオブジェクトは、GPU を使ってライトマップ空間にレンダリングされます。つまり、ゲームオブジェクトが画面上でどのように見えるかと、ライトマッパーにどのように見えるかは別のことです。ですから、シェーダーをカスタマイズすることができます。
メタパスはアルベドとエミッシブを分離します。これは、通常のシェーダーパスでは、グローバルイルミネーション (GI) を計算するのに使われます。こうすることにより、リアルタイムレンダリングに使用するシェーダーに影響を与えることなく GI を制御できます。標準シェーダーにはデフォルトでメタパスが含まれています。GI は Unity では Enlighten と呼ばれるミドルウェアによって制御されています。
メタパスを使うことで、Unity エディターは内部でメタリックなサーフェスのアルベドを処理します。Enlighten は、各反射のディフューズトランスポートを処理し、サーフェスのアルべドを使用します。黒、または黒に近いアルべドのメタリックなサーフェスは、どんなライトも反射しません。アルべドをレンダリングするシェーダーパスは、金属のような色合いでアルべドを明るめの色にレンダリングする傾向があります。絶縁体のマテリアル (木、プラスチック、石、コンクリート、皮、皮膚) には白いスペキュラーリフレクションがあります。金属にはスペクトル正反射率があります。
ノート メタパスを使用すると、DynamicGI.SetEmissive ほど速くはありませんが、単色に制限していないためより適応性があります。
Unity の 5.0 版以降のビルトインの古いシェーダーには、すでにメタパスが含まれています。Unity の 5.0 版以前のプロジェクトをアップグレードする場合には、メタパスを加える必要があります。詳しくは、後述のメタパスを使ったシェーダー例 を参照してください。
_TransparencyLM
というテクスチャプロパティをシェーダーに加えることによって、カスタムのカラーベースの RGB 透過性を加えることができます。この場合、標準の挙動は失われ、このテクスチャの値だけが、マテリアルを通過する透過度の検証に使用されます。これは、マテリアルの色やアルベドテクスチャとは関係ないカラーベースの透明度を作成したいときに役立ちます。
カスタムの透過挙動を作成するためには、以下をシェーダーに追加し、テクスチャを指定します。
_TransparencyLM ("Transmissive Texture", 2D) = "white" {}
ノート Unity はシェーダーのプロパティ、パス/ネームのキーワード (例えばTransparent
, Tree
, Leaf
, Leaves
など) で、特定の古いシェーダーを検出します。
下のシェーダーでは、GI システムのためだけのカスタムのアルベド色とテクスチャを指定することができます。
Shader "Custom/metaPassShader"{
Properties {
_Color ("Color", Color)=(1,1,1,1)
_MainTex ("Albedo (RGB)",2D)="white"{}
_Glossiness ("Smoothness", Range(0,1))=0.5
_Metallic ("Metallic", Range(0,1))=0.0
_GIAlbedoColor ("Color Albedo (GI)", Color)=(1,1,1,1)
_GIAlbedoTex ("Albedo (GI)",2D)="white"{}
}
SubShader {
// ------------------------------------------------------------------
// ライトマッピング、 GI (エミッション、アルベド、 ...) の情報を抽出
// このパスは通常のレンダリングの間には使用されません。
Pass
{
Name "META"
Tags {"LightMode"="Meta"}
Cull Off
CGPROGRAM
#include"UnityStandardMeta.cginc"
sampler2D _GIAlbedoTex;
fixed4 _GIAlbedoColor;
float4 frag_meta2 (v2f_meta i): SV_Target
{
// ディフューズ色とスペキュラー色と
// サーフェスの粗さで、最終的なアルベドを求めます。
FragmentCommonData data = UNITY_SETUP_BRDF_INPUT (i.uv);
UnityMetaInput o;
UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
fixed4 c = tex2D (_GIAlbedoTex, i.uv);
o.Albedo = fixed3(c.rgb * _GIAlbedoColor.rgb);
o.Emission = Emission(i.uv.xy);
return UnityMetaFragment(o);
}
#pragma vertex vert_meta
#pragma fragment frag_meta2
#pragma shader_feature _EMISSION
#pragma shader_feature _METALLICGLOSSMAP
#pragma shader_feature ___ _DETAIL_MULX2
ENDCG
}
Tags {"RenderType"="Opaque"}
LOD 200
CGPROGRAM
// 物理ベースの標準ライティングモデル。すべてのライトの種類で影は有効
#pragma surface surf Standard fullforwardshadows nometa
// 体裁のよいライティングを得るためにシェーダーモデル 3.0 target を使用。
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN,inout SurfaceOutputStandard o){
// カラーで色付けされたテクスチャからAlbedo を求める
fixed4 c = tex2D (_MainTex, IN.uv_MainTex)* _Color;
o.Albedo = c.rgb;
// Metallic と smoothness をスライダーの値から求める
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}