この GitHub のプロジェクトは Unity の Projector コンポーネントを Lightweight/Universal Render Pipeline でも使えるようにするための C# スクリプトとシェーダーファイルを提供します。
ブランチ
ブランチ名 | 検証済みの RP バージョン |
---|---|
master | Lightweigt RP 6.9.0 |
master-universalrp | Universal RP 7.1.7 |
インストール
Git をお使いの場合、リポジトリを Unity プロジェクトの Assets フォルダに clone (もしくは submodule add) してください。Git をお使いではない場合、Zip ファイルをダウンロードして、それを Assets フォルダに展開してください。
Lightweight RP: https://github.com/nyahoon-games/ProjectorForLWRP/tree/master
Universal RP: https://github.com/nyahoon-games/ProjectorForLWRP/tree/master-universalrp
Zip ダウンロード: Universal RP 用, Lightweight RP 用
セットアップ
まず始めに、ProjectorRendererFeature を Lightweight Render Pipeline に追加しておく必要があります。プロジェクトを LWRP のテンプレートから作成している (もしくは正しく LWRP が設定されている) ならば、Lightweight Render Pipeline アセットが Graphics Settings の Scriptable Render Pipeline Settings のところにセットされているはずです。
この Lightweight Render Pipeline アセットをダブルクリックして、Inspector View に表示します。
もしデフォルトの Forward Renderer を使っている場合、Renderer Type を Custom に変更し、Data フィールドの脇にある小さなボタンをクリックします。そして、ForwardRendererWithProjectorPass を選択してください(Universal RPではRender Typeフィールドがありません。デフォルトのRendererをForwardRendererWithProjectorPassに置き換えてください)。
もし既に独自の Forward Renderer を使っているのであれば、ProjectorRendererFeature を Forward Renderer Data に追加してください。
使い方
既にある Projector オブジェクト、もしくは空の GameObject に Projector For LWRP コンポーネントを追加します。
Projector For LWRP コンポーネントを追加すると、Projector コンポーネントはインスペクタービューから隠されてしまいますが、Projector コンポーネントのプロパティーは Projector For LWRP コンポーネントの中に表示されるので、通常通りに設定してください。ひとつ通常と違うのは、Standard Assets に含まれている Projector 用のシェーダーは使えないということです。 Projector Foe LWRP のシェーダーを使うか、もし必要であれば、カスタムシェーダーを作成してください (詳細は下記参照)。Fast Shadow Receiver や Dynamic Shadow Projector に含まれるシェーダーも使うことができます。
場合によっては、Projector のプロパティーに加えて、下記の Projector For LWRP コンポーネントのプロパティーも設定する必要があるかもしれません。
Projector For LWRP コンポーネントのプロパティー
Rendering Layer Mask | Renderer の renderingLayerMask プロパティがここで指定したレイヤのいずれかを含む場合にのみ、Renderer はこの Projector による投影を受け取ることができます。 |
Render Queue Lower/Upper Bound | マテリアルの Render Queue の値がここで指定した範囲である場合にのみ、Renderer はこの Projector による投影を受け取ることができます。 |
Terrain Render Flags | Terrains To Be Filtered With Render Flags に含まれるテレインのどの部分がプロジェクターの投影を受け取るかを指定します。 |
Terrains To Be Filtered With Render Flags | Terrain Render Flags プロパティの影響を受けるテレインのリストを指定します。このプロパティは Fast Shadow Receiver に関連付けられたテレインに有用です。Ignore Layers を使う代わりに、テレインをこのリストに追加することで、テレインの地面の部分だけ無視して、木やディテイルなどにはプロジェクターを投影することができるようになります。 |
Shader Tag List | LightMode タグの値の配列を指定します。ここで指定した LightMode のパスを含むシェーダーが使われている Renderer のみが、この Projector による投影を受け取ることができます。シェーダーのパスが LightMode タグを持たない場合、その LightMode は SRPDefaultUnlit とみなされます。デフォルトは空の配列で、その場合は LightweightForward (もしくはUniversalForward) と SRPDefaultUnlit の2つのタグを使います。配列が空ではない場合は、デフォルトの値を上書きします(追加ではありません)。タグを追加するには、まず Size を増やしてください。 |
Render Pass Event | Projector を描画するパスが挿入されるタイミングを選択します。Projector のマテリアルが持つ Render Queue の値は無視されることにご注意ください。 |
Per Object Data | トランスフォームマトリクス以外で、Projector のマテリアルがオブジェクト毎のデータを必要とする場合は、それをここで指定します。 |
Use Stencil Test | このオプションをチェックすると、ステンシルバッファを書き込む追加のパスが挿入されますが、プロジェクターを描画するパスのコストを下げることができます。もし追加のパスのコストより、プロジェクターを描画するパスのコストの方が多く下がれば、パフォーマンスを向上させることができます。まずは試してみて、効果があるかどうかみてみてください。GPU によってはステンシルテストを使っても描画のコストが全く下がらない可能性もあります。もし、Fast Shadow Receiver と一緒に使っている場合はステンシルテストを使う必要はありません。 |
Clear stencil after draw | このオプションをチェックすると、後に続くプロジェクターの描画が正しくなるように、ステンシルバッファをクリアするパスがプロジェクターを描画するパスの後に追加されます。このオプションにチェックがない場合は、後に続くプロジェクターの描画のために別のステンシルビットが確保され使われるようになります。そして、全てのステンシルビットを使い果たした後に、ステンシルバッファがクリアされます。デフォルトでは、8つの全てのステンシルビットがプロジェクターの描画のために予約されています。もし他のレンダリング用に一部のステンシルビットを確保しておきたい場合は、Projector Renderer Feature の Stencil Mask プロパティを変更してください。 |
Prevent overwriting | このオプションをチェックすると、ステンシルテストによってパフォーマンスが改善されることはなくなってしまいますが、このプロジェクターが同じピクセルに2回以上描画されるのを防ぐことができます。これはプロジェクターの中に透明なオブジェクトが含まれるときに起きる可能性があります。 |
Projector 用のカスタムシェーダーを作成する
もし Projector 用のカスタムシェーダーを作成する必要がある場合は “Assets/ProjectorForLWRP/Shaders/P4LWRP.cginc” をインクルードして fsrTransformVertex
関数で頂点の座標変換やプロジェクションの UV を計算するようにしてください。また、シェーダーは FSR_PROJECTOR_FOR_LWRP
キーワードをつけてコンパイルする必要があります。
SRP Batcher を有効にするには、CGPROGRAM
の代わりに HLSLPROGRAM
を使います。
サンプルコード:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Shader "Custom/Projector/Shadow" { Properties { [NoScaleOffset] _ShadowTex ("Cookie", 2D) = "gray" {} [NoScaleOffset] _FalloffTex ("FallOff", 2D) = "white" {} _Offset ("Offset", Range (-1, -10)) = -1.0 } SubShader { Tags {"Queue"="Transparent-1"} Pass { ZWrite Off Fog { Color (1, 1, 1) } ColorMask RGB Blend DstColor Zero Offset -1, [_Offset] HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma shader_feature_local FSR_PROJECTOR_FOR_LWRP #pragma multi_compile_local _ FSR_RECEIVER #pragma multi_compile_fog #include "Assets/ProjectorForLWRP/Shaders/P4LWRP.cginc" P4LWRP_V2F_PROJECTOR vert(float4 vertex : POSITION) { P4LWRP_V2F_PROJECTOR o; fsrTransformVertex(vertex, o.pos, o.uvShadow); UNITY_TRANSFER_FOG(o, o.pos); return o; } fixed4 frag(P4LWRP_V2F_PROJECTOR i) : SV_Target { fixed4 col; fixed falloff = tex2D(_FalloffTex, i.uvShadow.zz).a; col.rgb = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow)).rgb; col.a = 1.0f; col.rgb = lerp(fixed3(1,1,1), col.rgb, falloff); UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(1,1,1,1)); return col; } ENDHLSL } } } |