PostProcessing Stack v2でカスタムエフェクトを作る

公式マニュアルはhttps://docs.unity3d.com/Packages/com.unity.postprocessing@2.2/manual/Writing-Custom-Effects.html

公式 APIドキュメント https://docs.unity3d.com/Packages/com.unity.postprocessing@2.2/api/

どちらもバージョンに注意。 使い方は公式マニュアルで全て説明されている。 ここでは、マニュアルを読んだ上で個人的なメモを纏めていく。

ハマりポイント

一番重要そうで忘れがちな部分を先に書く。 shaderがC#ファイルからしか参照されていないと、shaderがビルドに含まれない。 PostProcessingStack用のカスタムエフェクトを作ると、大抵こうなるはず。

Resourcesフォルダーに追加するか、Always Included Shaders(Edit -> Project Settings -> Graphics)に追加する必要がある。

さすがにこれは将来的なバージョンUPで対応されるのでは?

ファイル構成

  • c# + shaderのセット
  • shaderはshaderLabではなく、HLSL
  • 公式マニュアルにはHLSLと書いてあるが、ShaderLabでも動作する

属性部分について

[Serializable]
[PostProcess(typeof(RadialBlurRenderer), PostProcessEvent.AfterStack, "AAA/PostEffects/Radial Blur HLSL", true)]

エフェクトの注入ポイント

  • BeforeTransparent:透明なパスが完了する前に、効果は不透明なオブジェクトにのみ適用されます。
  • BeforeStack:組み込みスタックが起動する前にエフェクトが適用されます。これには、アンチエイリアス被写界深度、トーンマッピングなどが含まれます。
  • AfterStack:エフェクトは、ビルトインスタックの後、FXAA(有効な場合)および最終パスディザリングの前に適用されます。

メニューカテゴリ パスはココに表示されるための記述。

SceneViewでも有効にするか

最後に、オプションの4番目のパラメーターがallowInSceneViewあり、その名前が示すように、シーンビューでエフェクトを有効にするかどうかを指定します。trueデフォルトではに設定されていますが、一時的な効果やレベルの編集を難しくする効果のために無効にすることができます。

便利なことに、最初からScene ViewでもPostEffectがpreviewできる仕組みが整っている。 しかし逆にそれが邪魔になる事があるので、Offにする事も可能。

レンダラー部分

ドキュメントのサンプル

public sealed class GrayscaleRenderer : PostProcessEffectRenderer<Grayscale>
{
    public override void Render(PostProcessRenderContext context)
    {
        var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/Grayscale"));
        sheet.properties.SetFloat("_Blend", settings.blend);
        context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
    }
}

PostProcessRenderContext型の引数が渡されるので、そこから情報を得る。

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Runtime/PostProcessRenderContext.cs

PostProcessEffectRendererを継承する。

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Runtime/PostProcessEffectRenderer.cs

PostProcessEffectRendererでoverrideして使える関数

  • void Init():レンダラーの作成時に呼び出されます。
  • DepthTextureMode GetLegacyCameraFlags():カメラフラグを設定し、深度マップ、モーションベクトルなどを要求するために使用されます。
  • void ResetHistory():「履歴のリセット」イベントが送出されたときに呼び出されます。主に一時的な効果に使用され、履歴バッファなどをクリアします。
  • void Release():レンダラーが破棄されるときに呼び出されます。必要に応じてクリーンアップを行ってください。

パラメーターが変更された時のイベントが欲しかったが、今の所無かった。自力でチェックする必要がある。

shader

shaderLabではなく、HLSLで書く必要がある。

ドキュメントのサンプル

Shader "Hidden/Custom/Grayscale"
{
    HLSLINCLUDE

        #include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"

        TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
        float _Blend;

        float4 Frag(VaryingsDefault i) : SV_Target
        {
            float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
            float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
            color.rgb = lerp(color.rgb, luminance.xxx, _Blend.xxx);
            return color;
        }

    ENDHLSL

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            HLSLPROGRAM

                #pragma vertex VertDefault
                #pragma fragment Frag

            ENDHLSL
        }
    }
}

#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"

は必ず必要。ここのパスはバージョンによって違うようなので注意。

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Shaders/StdLib.hlsl

https://github.com/Unity-Technologies/PostProcessing/tree/v2/PostProcessing/Shaders/API

テクスチャ宣言

TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);


PostProcessing/PostProcessing/Shaders/API/

どんなマクロがあるのかは、ここのファイルをチェックするのが良いとの事。

Metal用はこちら。

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Shaders/API/Metal.hlsl

カスタムエディター

自作で拡張も可能。その仕組も用意されている。