リムライトや縞模様のハイライト、Roberts Crossによるエッジを追加するカスタムパスのサンプルを詳しく見てみました。
エフェクト
リムライトは明るさが繰り返し変化します。
縞状のエフェクトは太さや方向を変えられます。
ハイライトやアウトラインはデプステストを適用するかどうかを切り替えられます。
Custom Pass Volume
Custom Pass Volumeコンポーネントでは、DrawRenderersカスタムパスで対象のゲームオブジェクトごとにカラーとデプスを描画します。ターゲットはカスタムカラーバッファとカスタムデプスバッファになっています。
その後、フルスクリーンカスタムパスでカメラカラーバッファに描画します。
Draw renderers Custom Pass
Draw renderersカスタムパスでは、UnlitシェーダーグラフでColorプロパティの値をマスタースタックに入力しています。
対象のゲームオブジェクトにはC#スクリプトが付いていて、MaterialPropertyBlockで同名のプロパティの値を上書きしています。
void SetColor()
{
var rndr = GetComponent();
var propertyBlock = new MaterialPropertyBlock();
rndr.GetPropertyBlock(propertyBlock);
propertyBlock.SetColor("_SelectionColor", selectionColor);
rndr.SetPropertyBlock(propertyBlock);
}
色を設定するメソッドは初期化時やインスペクタの値が変更されたときに呼ばれます。
void Start()
{
SetColor();
}
void OnValidate()
{
SetColor();
}
フルスクリーンカスタムパス
フルスクリーンカスタムパスには、Fullscreenシェーダーグラフの設定されたマテリアルがアタッチされています。
シェーダーグラフは「ゴーストハイライト」「ストライプハイライト」「Robert Crossエッジ検出」の3つの部分に分かれています。
ゴーストハイライト
ゴーストハイライトの部分ではリムライトのエフェクトを作成しています。
まずカメラへのベクトルと法線ベクトルの内積を計算します。2つのベクトルのなす角度が広がるほど値が小さくなります。LerpノードとBool型のプロパティ使って白黒を反転できるようにしています。
時間の値を調節して、Fractionノードにいれることで、値が増加しつつ入力が1のときはまた0に戻るような繰り返しの値になります。
0.5を引いて2倍することで-1~ほぼ1の範囲になり、その絶対値を計算することで0~1の範囲を繰り返す値になります。
内積の値をPowerノードで累乗します。Timeノードからの繰り返しの値をLerpノードにいれて、その出力を指数にしています。Lerpノードでは、プロパティを使って繰り返し変化する指数の範囲を決定します。
これでリムライトのようなエフェクトができます。
リムライトにデプステストを適用します。カスタムデプスバッファの値とシーンデプスを比較してデプステストをします。カスタムデプスがシーンデプス以下のときに1、それ以外で0になります。
リムライトの値とデプステストの値をかけます。デプステストを適用した値をLerpノードのBに、適用していない値をAにいれます。Boolプロパティで切り替えられます。
最後に色かけます。
ストライプハイライト
縞状のハイライトを作ります。まずスクリーン位置と縞の並ぶ方向の内積を計算します。スクリーン位置は(0, 0)が画面の中心になるように補正されています。
スクリーン位置のベクトルを縞方向の単位ベクトルに投影したときの長さがわかります。
縞の頻度を表すFloat値をかけます。
Fractionノードにいれると、0~ほぼ1を繰り返します。
縞の頻度のプロパティ値を下げると、縞の数が減ります。
StepノードのEdgeに入力します。Inが0.5なので、Edgeが0~0.5のときは1を、それ以外では0を出力します。
その後Lerpノードを使って、白い部分と黒い部分にそれぞれ色を設定しています。
これで縞模様ができます。
LerpノードとFloat値を使って、ゴーストハイライトの影響を調節できます。
デプステストを適用するかどうかをLerpノードで切り替えます。
ゴーストハイライトの効果を足します。カスタムデプスをStepノードとOneMinusノードに入れて、対象のゲームオブジェクトだけが白くそれ以外は黒い値を作り、ハイライトの効果をかけます。
アウトライン
Roberts Crossエッジ検出を使ってアウトラインを作ります。まず注目ピクセルの対角の4つのピクセルでカスタムデプスバッファをサンプリングします。ScreenPositionに4つのオフセットを足して、Custom Depth Bufferノードに入力しています。→シェーダーグラフでRoberts Crossエッジ検出を実装する
カスタムデプスバッファの値をStepノードにいれて、対象のゲームオブジェクトとそれ以外を白黒に分けます。
対角にある画素値を引き、絶対値を足すことでマンハッタン距離を計算しています。明るさの変化の大きさを表します。
各カスタムデプスの値をシーンデプスと比較してデプステストをします。
Lerpノードとプロパティを使って、アウトラインにデプステストを適用するかしないかを切り替えられます。
アウトラインをLerpノードのTに入力します。Aにはハイライトの色、Bにはアウトラインの色プロパティが接続されています。
最後にカスタムカラーバッファの色をかけて、マスタースタックのBase Colorに接続します。カスタムカラーバッファには、ゲームオブジェクトごとに設定した色が描画されています。
これで様々なハイライトやアウトラインを作れます。
参考:https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@17.0/manual/HDRP-Sample-Content.html#fullscreen-samples
https://docs.unity3d.com/Packages/com.unity.shadergraph@16.0/manual/Screen-Position-Node.html
https://docs.unity3d.com/ja/Packages/com.unity.shadergraph@10.0/manual/Step-Node.html
https://docs.unity3d.com/Packages/com.unity.shadergraph@16.0/manual/HD-Custom-Depth-Node.html