【Unity】カスタムエフェクトでテクスチャを定義するメモ【PostProcessing】

Post-processing Stack v2 にてカスタムエフェクトでテクスチャを定義するサンプルコードです。
検索ではあまり出なかったのでメモ

可能な限りシンプルなコードにしてます。

プロファイルのコード

using System;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

namespace posttest{

[Serializable]
[PostProcess(typeof(PostTestRenderer), PostProcessEvent.BeforeStack, "Custom/PostTest")]
public sealed class PostTest : PostProcessEffectSettings
{
	// 歪ませるサイズ
	[Range(0, 100)]	
	public FloatParameter scale = new FloatParameter { value = 1.0f };

	// テクスチャのプロパティを定義する
	public TextureParameter normalTexture = new TextureParameter { value = null };

	// IsEnabledAndSupportedを定義したほうがいいです。
	public override bool IsEnabledAndSupported( PostProcessRenderContext context)
	{
		bool state = enabled.value && normalTexture.value != null;
		return state;
	}
} // class PostTest

public sealed class PostTestRenderer : PostProcessEffectRenderer<PostTest>
{
	//----------------------------------------------------------------------------
	public override void Init() => base.Init();
	//----------------------------------------------------------------------------
	public override void Release() => base.Release();
	//----------------------------------------------------------------------------
    public override void Render( PostProcessRenderContext context)
	{
		var sheet = context.propertySheets.Get( Shader.Find("Hidden/Custom/PostTestShader"));
		sheet.properties.SetFloat("_Scale", settings.scale);
		var normalTexture =
			settings.normalTexture.value == null ?
			RuntimeUtilities.blackTexture :
			settings.normalTexture.value;
		sheet.properties.SetTexture( "_NormalTexture", settings.normalTexture);

		Matrix4x4 clipToView = GL.GetGPUProjectionMatrix(context.camera.projectionMatrix, true).inverse;
		sheet.properties.SetMatrix("_ClipToView", clipToView);

		context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
 	}
} // class PostTestRenderer

} // namespace posttest

ファイル名とクラス名を同じにしないと、保存されないので気をつけてください。
class PostTest を PostTest.cs に書く

シェーダーコード

定義された _NormalTexture を受け取り 元画像を適当に歪ませてます。

Shader "Hidden/Custom/PostTestShader"
{
    SubShader
    {
		Cull Off ZWrite Off ZTest Always
		Pass
		{
			HLSLPROGRAM
			#pragma vertex Vert
			#pragma fragment Frag
			#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"

			TEXTURE2D_SAMPLER2D( _MainTex, sampler_MainTex);
			TEXTURE2D_SAMPLER2D( _NormalTexture, sampler_NormalTexture);

			float4 _MainTex_TexelSize;
			float4 _NormalTexture_TexelSize;
			float4x4 _ClipToView;

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 texcoord : TEXCOORD0;
				float2 texcoordStereo : TEXCOORD1;
				float3 viewSpaceDir : TEXCOORD2;
			};

			v2f Vert( AttributesDefault v)
			{
				v2f o = (v2f)0;
				o.vertex = float4( v.vertex.xy, 0.0, 1.0);
				o.texcoord = TransformTriangleVertexToUV( v.vertex.xy);
				o.viewSpaceDir = mul(_ClipToView, o.vertex).xyz;
#if UNITY_UV_STARTS_AT_TOP
				o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif
				o.texcoordStereo = TransformStereoScreenSpaceTex( o.texcoord, 1.0);

				return o;
			}

			float _Scale;

			float4 Frag( v2f i) : SV_Target
			{
				float3 normal = SAMPLE_TEXTURE2D( _NormalTexture, sampler_NormalTexture, i.texcoord);
				float2 vec = normal.xy * 2 - 1;
				float3 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord + vec*_Scale/256);
				
				return float4( color, 1);
			}

			ENDHLSL
		}//Pass
	}//SubShader
}

このサンプルでは通常のテクスチャとして読み込んで rgb の成分を 256 段階として書いてます。

Normal Texture にテクスチャを設定すると PostTestRenderer クラスが PostTestShader シェーダーに転送してくれます。
通常のテクスチャの定義と違うので注意が必要

通常のシェーダーでは 普通のテクスチャと ノーマルマップのテクスチャ を区別できるように定義できるのですが、PostProcessEffectSettings でどのように定義するかは不明。ご存じの方がいれば教えていただければ幸いです。

定義部分

TEXTURE2D_SAMPLER2D( _NormalTexture, sampler_NormalTexture);

フェッチ部分

float3 normal = SAMPLE_TEXTURE2D( _NormalTexture, sampler_NormalTexture, i.texcoord);

スケールを変更することで、ノーマルマップからUVをずらしてメインマップを描画してます。

スケール = 1
スケール = 100
設定している ノーマルマップ
Tags:

コメントを残す