PostProcessingStack v2にて、各種設定をランタイムで変更する
[SerializeField] private PostProcessVolume _ppVolume; void Start() { Bloom bloom; _ppVolume.profile.TryGetSettings(out bloom); bloom.threshold.value = 3f; }
数式をグラフ化する。Grapher(macアプリ) と desmos(webサービス)
最近知りましたが、macには標準でグラフを描くアプリが入っていました。 これでガウス関数を作ってみます。
mac標準アプリのGrapher
パラメータ化した値を操作して動かす事も出来る。
どんなパラメーターになるのか理解するのに役立ちそう。
しかし
ちょっとしか触っていませんが、どうも挙動がバグっぽいものが目立ちました。 入力欄の色が変わってしまったり、アニメーションさせるとグラフが突然ずれたり。
真打ち、desmos
webサービスでも同じような事が出来るサービスがあるんですね。 作ったものを共有できるし、使いやすい。目立ったバグもなさそう。 入力方法もGrapherと同じ感覚で出来ました。
右下の「desmos」というロゴをクリックするとサイトに飛びます。 www.desmos.com
サイトに飛ぶとパラメータを操作してグラフがどんな風に変化するのかが視覚的に理解できます。 これは便利だ。というか、理解するためには必須級だと思いました。 数式見ただけでは何も分からない。。
こちらの記事にて知りました。ありがとうございます。
PostProcessing Stackのカスタムエフェクトで解像度を下げる (ダウンサンプリングする) 方法
// AO buffer var rtMask = ShaderIDs.OcclusionTexture1; int scaledWidth = context.width / ts; int scaledHeight = context.height / ts; context.GetScreenSpaceTemporaryRT(cmd, rtMask, 0, kFormat, kRWMode, kFilter, scaledWidth, scaledHeight);
ここらへん。
context.GetScreenSpaceTemporaryRT()
などを使って、CommandBufferの操作が出来る。
解像度を下げるだけならshaderは不要で、下記で出来た。
using System; using UnityEngine; using UnityEngine.Rendering.PostProcessing; namespace White { [Serializable] [PostProcess(typeof(DownSamplingRenderer), PostProcessEvent.AfterStack, "AAA/PostEffects/DownSamplilng", true)] public sealed class DownSampling : PostProcessEffectSettings { [Range(1f, 10f)] public FloatParameter downScale = new FloatParameter {value = 1f}; } internal sealed class DownSamplingRenderer : PostProcessEffectRenderer<DownSampling> { public override void Render(PostProcessRenderContext context) { int scaledWidth = Mathf.RoundToInt(context.width / settings.downScale.value); int scaledHeight = Mathf.RoundToInt(context.height / settings.downScale.value); int tempId1 = Shader.PropertyToID("_Temp1"); context.GetScreenSpaceTemporaryRT(context.command, tempId1, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear, FilterMode.Bilinear, scaledWidth, scaledHeight); // 元画像をtempId1にコピー context.command.BuiltinBlit(context.source, tempId1); // tempId1を出力 context.command.BuiltinBlit(tempId1, context.destination); context.command.ReleaseTemporaryRT(tempId1); } } }
CommandBufferと同じ。
GetScreenSpaceTemporaryRT() contextのものを使うのは何でか?
context.command.GetTemporaryRT() に置き換えて試したが、これでも同じ結果が得られる。
context.command.GetTemporaryRT(tempId1, scaledWidth, scaledHeight, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
GetScreenSpaceTemporaryRT()のソースを見ると、
#if UNITY_2017_2_OR_NEWER
で処理を分岐させている。
BuiltinBlit()
に関してもCommandBufferに実装された関数ではなく、PostProcessing.RuntimeUtilitiesで宣言されている拡張メソッド。
将来的に何かの処理が挟まる可能性もあるのでCommandBufferのメソッドをそのまま使うのは止めたほうが良さそうだ。
GetScreenSpaceTemporaryRT
等の詳しいapi documentはこちら。https://docs.unity3d.com/Packages/com.unity.postprocessing@2.2/api/UnityEngine.Rendering.PostProcessing.RuntimeUtilities.html?q=BlitFullscreenTriangle#UnityEngine_Rendering_PostProcessing_RuntimeUtilities_CopyTexture_CommandBuffer_RenderTargetIdentifier_RenderTargetIdentifier_
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型の引数が渡されるので、そこから情報を得る。
PostProcessEffectRendererを継承する。
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
カスタムエディター
自作で拡張も可能。その仕組も用意されている。
unity C#でのpath取得関連メモ
project viewで選択中のディレクトリ取得
static private string GetSelectedDir() { foreach (Object obj in Selection.GetFiltered(typeof(DefaultAsset), SelectionMode.TopLevel)) { if (obj is DefaultAsset) { string path = AssetDatabase.GetAssetPath(obj); if (AssetDatabase.IsValidFolder(path)) { return path; } } } return ""; }
カレントディレクトリの取得。unity editorで実行すると、Projectが入ってるディレクトリの絶対パスが入っているようだ。
System.Environment.CurrentDirectory
var a = GetSelectedDir(); // Assets/xxx/xxx みたいな Assetsからの相対パス var b = System.IO.Path.GetFullPath(a); // 絶対パス変換
https://docs.microsoft.com/ja-jp/dotnet/standard/io/how-to-copy-directories
Unity2019.1 LWRPでのRenderScale、Renderer Featuresの並べ替え
パッケージマネージャーのLightwight RPは5.13.0を使用。
public ScriptableRendererData _data; public LightweightRenderPipelineAsset _asset;
をinspecterで設定した後、動的に変更する。
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Rendering.LWRP; public class LWRPTest : MonoBehaviour { public ScriptableRendererData data; public LightweightRenderPipelineAsset asset; public Button btn1; public Button btn2; // Start is called before the first frame update void Start() { List<ScriptableRendererFeature> copy = new List<ScriptableRendererFeature>(); foreach (ScriptableRendererFeature f in data.rendererFeatures) { copy.Add(f); } btn1.onClick.AddListener(() => { // Renderer Features並べ替え data.rendererFeatures[0] = copy[1]; data.rendererFeatures[1] = copy[0]; }); btn2.onClick.AddListener(() => { // RenderScale asset.renderScale = 0.5f; }); } }
参考
Lightwight RPのバージョンが低いとScriptableRendererFeatureを設定できないので注意。
ありがとうございます。こちらも5.13.0にアップグレードしたら押せるようになりました。(LWRPだけでなく、Core RP、Shader Graphも合わせてアップデートで治りました)
— ssr_maguro (@ssr_maguro) May 8, 2019