Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion Assets/Demo/Workshop_HeatDistortion/Global Volume Profile.asset
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,53 @@ MonoBehaviour:
<fieldHash>k__BackingField: 218281240
m_OverrideState: 0
m_Value: 1.7
--- !u!114 &-2917405184620356695
MonoBehaviour:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 19a67b886d9240d43bab0e4aee471186, type: 3}
m_Name: HeatDistortionVolume
m_EditorClassIdentifier: Sirius.PostProcessing.Runtime::Sirius.PostProcessing.Runtime.Scripts.Volumes.HeatDistortionVolume
active: 1
_intensity:
m_OverrideState: 1
m_Value: 2
_blend:
m_OverrideState: 1
m_Value: 0.5
_startDistance:
m_OverrideState: 1
m_Value: 20
_fadeDistance:
m_OverrideState: 1
m_Value: 150
_speed:
m_OverrideState: 1
m_Value: 0.2
_chromaticSeparation:
m_OverrideState: 1
m_Value: 0.2
_zenithMask:
m_OverrideState: 1
m_Value: 0
_horizonMask:
m_OverrideState: 1
m_Value: 0
_horizonExponent:
m_OverrideState: 1
m_Value: 3
_noiseScale:
m_OverrideState: 1
m_Value: 2
_noiseTexture:
m_OverrideState: 1
m_Value: {fileID: 18700000, guid: f3f8592ee4a4db144887fb9fe80683b8, type: 3}
dimension: 1
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
Expand All @@ -62,4 +109,5 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3}
m_Name: Global Volume Profile
m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.VolumeProfile
components: []
components:
- {fileID: -2917405184620356695}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ MonoBehaviour:
m_Active: 1
allowRadialBlurPostProcess: 1
allowDirectionalBlurPostProcess: 1
allowHeatDistortionPostProcess: 1
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
Expand Down
28 changes: 27 additions & 1 deletion SiriusAssets/Sirius.Core.Assets/Assets/3DCells64Sheet.png.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ description: "Sirius.PostProcessingパッケージの設計詳細。Use when: (1
|------|------------|--------|---------|
| RadialBlurRenderPass | `allowRadialBlurPostProcess` | RadialBlurVolume | - |
| DirectionalBlurRenderPass | `allowDirectionalBlurPostProcess` | DirectionalBlurVolume | - |
| HeatDistortionRenderPass | `allowHeatDistortionPostProcess` | HeatDistortionVolume | `_CameraDepthTexture` が必要 |

シェーダーは `Runtime/Shaders/`(`DirectionalBlur.shader` / `RadialBlur.shader` / `RotationBlur.shader`)。
シェーダーは `Runtime/Shaders/`(`DirectionalBlur.shader` / `RadialBlur.shader` / `RotationBlur.shader` / `HeatDistortion.shader`)。
`Editor/Scripts/ShaderIncluder.cs` がリフレクションで各パスの `UsingShaderNameList` を収集し、ビルドの AlwaysIncludedShaders へ登録する。

## HeatDistortion(陽炎)固有の注意点

- **深度依存**: カメラ距離を `StartDistance`〜`FadeDistance` で減衰カーブに変換して歪み強度を決めるため、URP Renderer の `m_RequireDepthTexture` が有効である必要がある。深度は `Sirius.Core` の `ScreenSpaceUtil.hlsl`(`GetCameraDistance` / `GetCameraVector`)経由で参照しており、RenderGraph 側での `builder.UseTexture` 宣言は不要(`_CameraDepthTexture` は URP のグローバルテクスチャ)。
- **ノイズテクスチャは Texture2DArray**: `_HeatDistortionNoiseTex` は `TEXTURE2D_ARRAY` で宣言している。プリセットの `3DCells64Sheet`(64 スライス)を想定し、時間をスライス番号に対応させて隣接 2 スライスを lerp する。**Texture3D や Texture2D を割り当てると次元不一致になる**ので、インポート設定の Texture Shape を `2D Array` にすること。
- **null 許容**: `NoiseTexture` 未設定時も `RenderPass` 側で `SetTexture` を毎回呼び、null をそのままバインドする(マテリアルをパスで使い回すため、分岐でスキップすると以前のテクスチャが残り Volume の現在値とズレる)。null を渡した場合は次元の一致するシェーダー側デフォルトへフォールバックする。`Texture2D.whiteTexture` のような次元の異なるフォールバックを明示的に渡すと次元不一致になるため、他パスの `Mask` パターン(`mask ? mask : whiteTexture`)は流用できない。
- **既定値 0 でゼロコスト**: `IsActive()` は `Blend > 0 && Intensity > 0 && FadeDistance > 0`。`_intensity` の既定値は他 Volume の `_strength` と同じく **0.0f** にしてある。これにより Volume の Weight を 0 にした場合(=既定値へ補間される場合)も `IsActive()` が false になり、パスがスキップされる。
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using Sirius.PostProcessing.Runtime.Scripts.Volumes;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

namespace Sirius.PostProcessing.Runtime.Scripts.Features.Passes
{
/// <summary>
/// HeatDistortion描画パス
/// </summary>
public sealed class HeatDistortionRenderPass : ScriptableRenderPass, IAllowExecute
{
public static string[] UsingShaderNameList { get; } =
{
"Hidden/Sirius/HeatDistortion"
};

public bool AllowExecute { get; set; }

private static string ShaderName => UsingShaderNameList[0];
private readonly ProfilingSampler _profilingSampler;
private Material _postProcessMaterial;

/// <summary>
/// コンストラクタ
/// </summary>
public HeatDistortionRenderPass()
{
_profilingSampler = new ProfilingSampler("Sirius.HeatDistortion");
}

private void UpdateMaterialProperties(HeatDistortionVolume heatDistortionVolume)
{
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionIntensity, heatDistortionVolume.Intensity);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionBlend, heatDistortionVolume.Blend);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionStartDistance, heatDistortionVolume.StartDistance);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionFadeDistance, heatDistortionVolume.FadeDistance);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionSpeed, heatDistortionVolume.Speed);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionChromaticSeparation, heatDistortionVolume.ChromaticSeparation);
_postProcessMaterial.SetFloat(ShaderPropertyIDs.HeatDistortionNoiseScale, heatDistortionVolume.NoiseScale);
// NoiseTextureがnullのときもバインドを更新する。マテリアルはパスで使い回すため、
// 分岐でSetTextureを飛ばすと以前のTexture2DArrayが残り、Volumeの現在値とバインドがズレる。
// nullを渡した場合は次元の一致するシェーダー側デフォルトへフォールバックする
// (Texture2D.whiteTextureのような次元の異なるフォールバックを明示的に渡してはならない)
_postProcessMaterial.SetTexture(ShaderPropertyIDs.HeatDistortionNoiseTex, heatDistortionVolume.NoiseTexture);
}

public void Cleanup()
{
CoreUtils.Destroy(_postProcessMaterial);
_postProcessMaterial = null;
}

/// <summary>
/// PropertyID
/// </summary>
private static class ShaderPropertyIDs
{
public static readonly int HeatDistortionIntensity = Shader.PropertyToID("_HeatDistortionIntensity");
public static readonly int HeatDistortionBlend = Shader.PropertyToID("_HeatDistortionBlend");
public static readonly int HeatDistortionStartDistance = Shader.PropertyToID("_HeatDistortionStartDistance");
public static readonly int HeatDistortionFadeDistance = Shader.PropertyToID("_HeatDistortionFadeDistance");
public static readonly int HeatDistortionSpeed = Shader.PropertyToID("_HeatDistortionSpeed");
public static readonly int HeatDistortionChromaticSeparation = Shader.PropertyToID("_HeatDistortionChromaticSeparation");
public static readonly int HeatDistortionNoiseScale = Shader.PropertyToID("_HeatDistortionNoiseScale");
public static readonly int HeatDistortionNoiseTex = Shader.PropertyToID("_HeatDistortionNoiseTex");
}

private class PassData
{
public Material Mat;
public TextureHandle Source;
}

public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
var cameraData = frameData.Get<UniversalCameraData>();
if (cameraData.camera.cameraType == CameraType.Preview)
{
return;
}

if (cameraData.postProcessEnabled == false)
{
return;
}
if (_postProcessMaterial == null)
{
_postProcessMaterial = CoreUtils.CreateEngineMaterial(ShaderName);
}

if (!VolumeManager.instance.IsComponentActiveInMask<HeatDistortionVolume>(cameraData.volumeLayerMask)) return;

var heatDistortionVolume = VolumeManager.instance.stack.GetComponent<HeatDistortionVolume>();

if (!heatDistortionVolume.IsActive()) return;

UpdateMaterialProperties(heatDistortionVolume);

var resourceData = frameData.Get<UniversalResourceData>();
var desc = renderGraph.GetTextureDesc(resourceData.activeColorTexture);
var destTextureHandle = renderGraph.CreateTexture(desc);
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Sirius.HeatDistortion", out var passData))
{
builder.SetRenderAttachment(destTextureHandle, 0);
builder.UseTexture(resourceData.activeColorTexture);
passData.Source = resourceData.activeColorTexture;
passData.Mat = _postProcessMaterial;
builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
{
Blitter.BlitTexture(context.cmd, data.Source, Vector2.one, data.Mat, 0);
});
}
resourceData.cameraColor = destTextureHandle;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@ public sealed partial class SiriusPostProcessingFeature : ScriptableRendererFeat
{
[SerializeField] private bool allowRadialBlurPostProcess;
[SerializeField] private bool allowDirectionalBlurPostProcess;
[SerializeField] private bool allowHeatDistortionPostProcess;

[AllowFlag("allowDirectionalBlurPostProcess")]
private DirectionalBlurRenderPass _directionalBlurRenderPass;

[AllowFlag("allowRadialBlurPostProcess")]
private RadialBlurRenderPass _radialBlurRenderPass;

[AllowFlag("allowHeatDistortionPostProcess")]
private HeatDistortionRenderPass _heatDistortionRenderPass;

public override void Create()
{
_radialBlurRenderPass = new RadialBlurRenderPass();
_directionalBlurRenderPass = new DirectionalBlurRenderPass();
_heatDistortionRenderPass = new HeatDistortionRenderPass();
}

public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
Expand Down Expand Up @@ -66,12 +71,20 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD
_directionalBlurRenderPass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
renderer.EnqueuePass(_directionalBlurRenderPass);
}

// HeatDistortion
if (allowHeatDistortionPostProcess)
{
_heatDistortionRenderPass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
renderer.EnqueuePass(_heatDistortionRenderPass);
}
}

protected override void Dispose(bool disposing)
{
_directionalBlurRenderPass.Cleanup();
_radialBlurRenderPass.Cleanup();
_heatDistortionRenderPass.Cleanup();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using UnityEngine;
using UnityEngine.Rendering;

namespace Sirius.PostProcessing.Runtime.Scripts.Volumes
{
[VolumeComponentMenu("Sirius/HeatDistortion")]
public class HeatDistortionVolume : VolumeComponent, IPostProcessComponent
{
[SerializeField, Tooltip("歪みの強度")]
private ClampedFloatParameter _intensity = new(0.0f, 0.0f, 10.0f);
[SerializeField, Tooltip("歪み結果を元画像へ合成する割合(lerpのt)。0で元画像そのまま")]
private ClampedFloatParameter _blend = new(1.0f, 0.0f, 1.0f);
[SerializeField, Tooltip("効果が発生し始めるカメラからの距離")]
private ClampedFloatParameter _startDistance = new(20.0f, 0.0f, 1000.0f);
[SerializeField, Tooltip("効果が最大強度に達するカメラからの距離")]
private ClampedFloatParameter _fadeDistance = new(150.0f, 0.0f, 1000.0f);
[SerializeField, Tooltip("揺らぎパターンが流れる速さ")]
private ClampedFloatParameter _speed = new(0.1369f, 0.0f, 5.0f);
[SerializeField, Tooltip("色収差の強さ")]
private ClampedFloatParameter _chromaticSeparation = new(0.5f, 0.0f, 1.0f);
[SerializeField, Tooltip("揺らぎノイズの座標スケール")]
private ClampedFloatParameter _noiseScale = new(1.7f, 0.0f, 10.0f);
[SerializeField, Tooltip("揺らぎパターン生成用の3Dノイズテクスチャ(Texture2DArray)")]
private TextureParameter _noiseTexture = new(null);

public float Intensity
{
get => _intensity.value;
set => _intensity.value = value;
}

public float Blend
{
get => _blend.value;
set => _blend.value = value;
}

public float StartDistance
{
get => _startDistance.value;
set => _startDistance.value = value;
}

public float FadeDistance
{
get => _fadeDistance.value;
set => _fadeDistance.value = value;
}

public float Speed
{
get => _speed.value;
set => _speed.value = value;
}

public float ChromaticSeparation
{
get => _chromaticSeparation.value;
set => _chromaticSeparation.value = value;
}

public float NoiseScale
{
get => _noiseScale.value;
set => _noiseScale.value = value;
}

public Texture NoiseTexture
{
get => _noiseTexture.value;
set => _noiseTexture.value = value;
}

public bool IsActive()
{
return Blend > 0.0f && Intensity > 0.0f && FadeDistance > 0.0f;
}

public bool IsTileCompatible() => false;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading