トラブルシューティング
このセクションでは、Custom Pass コンポーネントを利用する際に経験するであろう、よくある問題の例と、その解決法について説明します。
ディスプレイのスケーリング問題
スケーリング問題は、解像度が違う 2 つのカメラを使うときに、ビルドに現れる場合があります。これはインゲーム、およびシーンビューで最もよく見られます。この問題は、次のような場合に発生します。
- コードが CommandBuffer.SetRenderTarget を呼び出し、
CoreUtilsSetRenderTarget
がビューポートを設定するとき。 RTHandle
バッファをサンプリングするときに、シェーダーコードで_RTHandleScale.xy
を乗算していないとき。
これらのケースにおける原因を修正する方法は以下の通りです。
CommandBuffer.SetRenderTarget
の代わりにCoreUtils.SetRenderTarget
を使います。RTHandle
バッファをサンプリングするときに、シェーダーコードで_RTHandleScale.xy
を使います。
ビルドで消える不透明なオブジェクト
プログラムのビルド中に、シーンで不透明なマテリアルを含むゲームオブジェクトが消えてしまうときは、HDRP アセット設定の再設定が必要な場合があります。
これを修正する方法は以下の通りです。
- Project ウィンドウで、HDRenderPipelineAsset に移動します (デフォルトの HDRP ビルドを使っている場合は、
Assets > Settings
と移動します)。 - HDRP アセットで、Lit Shader Mode を Both に変更します。
TAA が有効なときにジッターを起こすゲームオブジェクト
Temporal Anti-aliasing (TAA) が有効なときに、ゲームオブジェクトがジッターを起こす場合があります。
ジッターは次の両方の条件がそろったときに生じます。
- オブジェクトが AfterPostProcess Injection Point でレンダリングされている場合です。これを修正するには、Custom Pass Volume コンポーネントで Injection Point を変更します。
- オブジェクトの Depth Test が有効化されている場合。これを修正するには、シェーダープロパティー で Depth Test を無効にするか、または Draw Renders Custom Pass コンポーネント の Depth Test プロパティーの Enabled のチェックを外します。
間違った方向を向いた Shuriken パーティクル
次の条件が、シーン中のパーティクルが間違った方向を向く原因となります。
- パーティクルシステムが Custom Pass でのみ表示される。
AggregateCullingParameters
にオーバーライドが実装されていない。
Unity はカリングステップ中に AggregateCullingParameters
を実行する際に、Built-in Particle System でパーティクルの方向を計算します。従ってオーバライドがない場合、HDRP は適切にレンダリングしません。
デカールが非表示
次の条件で、シーン中のデカールが非表示になります。
- Unity が Custom Pass でレンダリングするゲームオブジェクトにデカールが適用される。
- デカールが AfterOpaqueDepthAndNormal Injection Point の前に Unity がレンダリングする、透明オブジェクトにある。
この問題を修正するには、ゲームオブジェクトの Injection point を AfterOpaqueDepthAndNormal 後の Injection Point のいずれかに変更します。
カリング問題
シーンで見えないオブジェクトがある場合は、Execute
メソッドで受信する cullingResult
が HDRP が Custom Pass のみでレンダリングするオブジェクトを含まないことが原因です。
これは Camera カリングマスク でオブジェクトのレイヤーを無効にすると発生します。
なぜなら、この cullingResult
はデフォルトでカメラの cullingResult
だからです。この問題を修正するには、このメソッドを CustomPass
クラスでオーバーライドします。
protected virtual void AggregateCullingParameters(ref ScriptableCullingParameters cullingParameters, HDCamera camera) {}
その後、ScriptableCullingParameters を使って Execute
メソッドで受け取る cullingResult
にレイヤーまたはカスタムカリングオプションをさらに追加できます。
Unity がシェーダーを読み込むときに画面が黒くなる
Unity がシェーダーを読み込むときに画面が黒くなる場合は、Unity がシーンで参照されていないシェーダーをレンダリングしようとしていることが原因かもしれません。この問題は、次のような場合に発生します。
- Custom Pass が
Shader.Find
のみを使ってシェーダーを検索するとき。 - Resources フォルダーにシェーダーが含まれていないとき。
- シェーダーが Custom Pass で参照されていないとき。
これを修正するには、次のコードを追加して Custom Pass でシェーダーを参照します。
[SerializeField, HideInInspector]
Shader shaderName;
例:
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
class Outline : CustomPass
{
public LayerMask outlineLayer = 0;
[ColorUsage(false, true)]
public Color outlineColor = Color.black;
public float threshold = 1;
// シェーダーが参照するビルドにあることを確認する
[SerializeField, HideInInspector]
Shader outlineShader;
Material fullscreenOutline;
RTHandle outlineBuffer;
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{
outlineShader = Shader.Find("Hidden/Outline");
fullscreenOutline = CoreUtils.CreateEngineMaterial(outlineShader);
// アウトラインバッファを定義する
outlineBuffer = RTHandles.Alloc(
Vector2.one, TextureXR.slices, dimension: TextureXR.dimension,
colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
// このエフェクトにアルファは必要ない
useDynamicScale: true, name: "Outline Buffer"
);
}
protected override void Execute(CustomPassContext ctx)
{
// アウトラインバッファでアウトラインエフェクトを適用したいメッシュをレンダリングする
CoreUtils.SetRenderTarget(ctx.cmd, outlineBuffer, ClearFlag.Color);
CustomPassUtils.DrawRenderers(ctx, outlineLayer);
// アウトラインエフェクトプロパティーを設定する
ctx.propertyBlock.SetColor("_OutlineColor", outlineColor);
ctx.propertyBlock.SetTexture("_OutlineBuffer", outlineBuffer);
ctx.propertyBlock.SetFloat("_Threshold", threshold);
// アウトラインバッファフルスクリーンをレンダリングする
CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer, ClearFlag.None);
CoreUtils.DrawFullScreen(ctx.cmd, fullscreenOutline, ctx.propertyBlock, shaderPassId: 0);
}
protected override void Cleanup()
{
CoreUtils.Destroy(fullscreenOutline);
outlineBuffer.Release();
}
}