Version: Unity 6.0 (6000.0)
言語 : 日本語
ビルトインレンダーパイプラインでのサーフェスシェーダーの作成
サーフェスシェーダーの最適化

ビルトインレンダーパイプラインのサーフェスシェーダーにライティングモデルを設定する

ビルトインレンダーパイプラインでは、サーフェスシェーダー を作成するときに、サーフェスのプロパティ (アルベドカラーや法線など) を記述し、ライティングモデル がライトの相互作用を計算します。

ビルトインライティングモデルには、ディフューズライティング用の Lambert と、スペキュラーライティング用の BlinnPhong の 2 つがあります。Unity 内にある Lighting.cginc ファイルはこれらのモデルを定義するものです (Windows: <unity install path>/Data/CGIncludes/Lighting.cginc、macOS: /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc)。

カスタムライティングモデルを使いたい場合には、サーフェスシェーダーを使用できます。ライティングモデルは、いくつかの規則に一致する Cg/HLSL 関数にすぎません。

レンダーパイプラインの互換性

機能名 ユニバーサルレンダーパイプライン (URP) HD レンダーパイプライン (HDRP) カスタム SRP ビルトインレンダーパイプライン
サーフェスシェーダー いいえ

URP でシェーダーオブジェクトを効率的に作成する方法については、Shader Graph を参照してください。
いいえ

HDRP でシェーダーオブジェクトを効率的に作成する方法については、Shader Graph を参照してください。
いいえ はい

ライティングモデルの宣言

ライティングモデルは、名前が Lighting で始まる通常の関数です。これらは、シェーダーファイルやインクルードファイルの任意の場所で宣言できます。以下の関数があります。

  1. half4 Lighting<Name> (SurfaceOutput s, UnityGI gi); は、ビューの向きに依存 しない ライトモデルのフォワードレンダリングパスで使用します。

  2. half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi); は、ビューの向きに依存 する ライトモデルのフォワードレンダリングパスで使用します。

  3. half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal); は、ディファードシェーディングパスで使用します。

すべての関数を宣言する必要はありません。ライティングモデルは、ビューの向きを使用するか、しないかのいずれかです。同様に、ライティングモデルがフォワードレンダリングでしか機能しない場合は、_Deferred 関数を宣言しないでください。こうすることによって、それを使用するシェーダーは、フォワードレンダリングだけにコンパイルされます。

カスタム GI

以下の関数を宣言して、デコードするライトマップデータとプローブをカスタマイズします。

  1. half4 Lighting<Name>_GI (SurfaceOutput s, UnityGIInput data, inout UnityGI gi);

標準の Unity ライトマップと SH プローブをデコードするには、Unity 内の UnityGlobalIllumination.cginc ファイルの UnityGI_Base にあるビルトインの DecodeLightmap 関数と ShadeSHPerPixel 関数を使用できます (Windows: <unity install path>/Data/CGIncludes/UnityGlobalIllumination.cginc、macOS: /Applications/Unity/Unity.app/Contents/CGIncludes/UnityGlobalIllumination.cginc_)。

以下は、ビルトインの Lambert ライティングモデルを使用するシェーダーです。

  Shader "Example/Diffuse Texture" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      
      struct Input {
          float2 uv_MainTex;
      };
      
      sampler2D _MainTex;
      
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

これは、シーンにディレクショナルライトが 1つあるとき、テクスチャがある場合とない場合の見え方の違いです。

ビルトインレンダーパイプラインでのサーフェスシェーダーの作成
サーフェスシェーダーの最適化