Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RenderGraph support for Distortion #111

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
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

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

22 changes: 13 additions & 9 deletions Assets/Nova/Runtime/Core/Scripts/ApplyDistortionPass.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// --------------------------------------------------------------
// Copyright 2024 CyberAgent, Inc.
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace Nova.Runtime.Core.Scripts
{
public sealed class ApplyDistortionPass : ScriptableRenderPass
public partial class ApplyDistortionPass : ScriptableRenderPass
{
private const string RenderPassName = nameof(ApplyDistortionPass);
private readonly bool _applyToSceneView;
Expand All @@ -32,13 +33,14 @@ public void Setup(RenderTargetIdentifier distortedUvBufferIdentifier)
_distortedUvBufferIdentifier = distortedUvBufferIdentifier;
}

#if UNITY_2023_3_OR_NEWER
[Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
#endif
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (_material == null)
{ return; }
if (_material == null) return;

if (!_applyToSceneView && renderingData.cameraData.cameraType == CameraType.SceneView)
{ return; }
if (!_applyToSceneView && renderingData.cameraData.cameraType == CameraType.SceneView) return;

#if UNITY_2022_1_OR_NEWER
var source = renderingData.cameraData.renderer.cameraColorTargetHandle.nameID;
Expand All @@ -49,9 +51,11 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData
var cmd = CommandBufferPool.Get();
cmd.Clear();
using (new ProfilingScope(cmd, _renderPassProfilingSampler))
{ cmd.SetGlobalTexture(_mainTexPropertyId, source);
cmd.SetGlobalTexture(_distortionBufferPropertyId, _distortedUvBufferIdentifier);
Blit(cmd, ref renderingData, _material); }
{
cmd.SetGlobalTexture(_mainTexPropertyId, source);
cmd.SetGlobalTexture(_distortionBufferPropertyId, _distortedUvBufferIdentifier);
Blit(cmd, ref renderingData, _material);
}

context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// --------------------------------------------------------------
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

#if UNITY_2023_3_OR_NEWER
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

namespace Nova.Runtime.Core.Scripts
{
public partial class ApplyDistortionPass : ScriptableRenderPass
{
private const string DistortedCameraColorTextureName = "DistortedCameraColorTexture";

public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
if (_material == null)
return;
if (!_applyToSceneView && frameData.Get<UniversalCameraData>().cameraType == CameraType.SceneView)
return;

if (!frameData.Contains<DistortionContextItem>())
{
Debug.LogError("[NOVA] Cannot execute ApplyDistortionPass. DistortedUvBufferPass must be executed.");
return;
}

var resourceData = frameData.Get<UniversalResourceData>();
TextureHandle destTexture;
{
var desc = renderGraph.GetTextureDesc(resourceData.activeColorTexture);
desc.name = DistortedCameraColorTextureName;
destTexture = renderGraph.CreateTexture(desc);
}

using (var builder =
renderGraph.AddRasterRenderPass<PassData>("NOVA.ApplyDistortionPass", out var passData))
{
// DestTexture
builder.SetRenderAttachment(destTexture, 0);

// MainTexture
{
passData.MainTex = resourceData.activeColorTexture;
builder.UseTexture(passData.MainTex);
passData.MainTexPropertyId = _mainTexPropertyId;
}

// DistortedUvBuffer
{
var contextItem = frameData.Get<DistortionContextItem>();
passData.DistortedUvBuffer = contextItem.DistortedUvTexture;
builder.UseTexture(passData.DistortedUvBuffer);
passData.DistortionBufferPropertyId = _distortionBufferPropertyId;
}

passData.Material = _material;

builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
{
data.Material.SetTexture(data.MainTexPropertyId, data.MainTex);
data.Material.SetTexture(data.DistortionBufferPropertyId, data.DistortedUvBuffer);
Blitter.BlitTexture(context.cmd, data.MainTex, Vector2.one, data.Material, 0);
});
}

resourceData.cameraColor = destTexture;
}

private class PassData
{
internal TextureHandle DistortedUvBuffer;
internal int DistortionBufferPropertyId;
internal TextureHandle MainTex;
internal int MainTexPropertyId;
internal Material Material;
}
}
}
#endif

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

12 changes: 12 additions & 0 deletions Assets/Nova/Runtime/Core/Scripts/DeprecationMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// --------------------------------------------------------------
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

namespace Nova.Runtime.Core.Scripts
{
public static class DeprecationMessage
{
public const string CompatibilityScriptingAPIObsolete =
"This rendering path is for compatibility mode only (when Render Graph is disabled). Use Render Graph API instead.";
}
}
2 changes: 2 additions & 0 deletions Assets/Nova/Runtime/Core/Scripts/DeprecationMessage.cs.meta

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

22 changes: 15 additions & 7 deletions Assets/Nova/Runtime/Core/Scripts/DistortedUvBufferPass.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// --------------------------------------------------------------
// Copyright 2024 CyberAgent, Inc.
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace Nova.Runtime.Core.Scripts
{
public sealed class DistortedUvBufferPass : ScriptableRenderPass
public partial class DistortedUvBufferPass : ScriptableRenderPass
{
private const string ProfilerTag = nameof(DistortedUvBufferPass);
private readonly ProfilingSampler _profilingSampler = new(ProfilerTag);
Expand Down Expand Up @@ -41,6 +42,9 @@ public void Setup(RenderTargetIdentifier renderTargetIdentifier)
}
#endif

#if UNITY_2023_3_OR_NEWER
[Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
#endif
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
var renderer = renderingData.cameraData.renderer;
Expand All @@ -52,24 +56,28 @@ public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderin
ConfigureClear(ClearFlag.Color, Color.gray);
}

#if UNITY_2023_3_OR_NEWER
[Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
#endif
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cmd = CommandBufferPool.Get();
cmd.Clear();

using (new ProfilingScope(cmd, _profilingSampler))
{ context.ExecuteCommandBuffer(cmd);
cmd.Clear();
{
context.ExecuteCommandBuffer(cmd);
cmd.Clear();

var drawingSettings =
CreateDrawingSettings(_shaderTagId, ref renderingData, SortingCriteria.CommonTransparent);
var drawingSettings =
CreateDrawingSettings(_shaderTagId, ref renderingData, SortingCriteria.CommonTransparent);

#if UNITY_2023_1_OR_NEWER
var param = new RendererListParams(renderingData.cullResults, drawingSettings, _filteringSettings);
var renderList = context.CreateRendererList(ref param);
cmd.DrawRendererList(renderList);
#else
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref _filteringSettings);
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref _filteringSettings);
#endif
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// --------------------------------------------------------------
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

#if UNITY_2023_3_OR_NEWER
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

namespace Nova.Runtime.Core.Scripts
{
public partial class DistortedUvBufferPass : ScriptableRenderPass
{
private const string DistortedUvBufferTexName = "DistortedUvBuffer";

public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
using (var builder = renderGraph.AddRasterRenderPass<PassData>("NOVA.DistortedUvBufferPass",
out var passData))
{
var distortedUvTexture = CreateRenderTarget(renderGraph, frameData);
// Insert data to be passed to ApplyDistortionPass.
{
var contextItem = frameData.Create<DistortionContextItem>();
contextItem.DistortedUvTexture = distortedUvTexture;
}
builder.SetRenderAttachment(distortedUvTexture, 0);

RendererListHandle renderList;
{
var renderingData = frameData.Get<UniversalRenderingData>();
var cameraData = frameData.Get<UniversalCameraData>();
var lightData = frameData.Get<UniversalLightData>();

var param = InitRendererListParams(_shaderTagId, renderingData, cameraData, lightData,
SortingCriteria.CommonTransparent, _filteringSettings);
renderList = renderGraph.CreateRendererList(param);
}
builder.UseRendererList(renderList);
passData.RendererList = renderList;

builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
{
context.cmd.DrawRendererList(data.RendererList);
});
}
}

private static TextureHandle CreateRenderTarget(RenderGraph renderGraph, ContextContainer frameData)
{
var resourceData = frameData.Get<UniversalResourceData>();
var desc = renderGraph.GetTextureDesc(resourceData.activeColorTexture);
desc.name = DistortedUvBufferTexName;
desc.depthBufferBits = 0;
desc.clearColor = Color.gray;
if (SystemInfo.IsFormatSupported(GraphicsFormat.R16G16_SFloat, GraphicsFormatUsage.Render))
desc.colorFormat = GraphicsFormat.R16G16_SFloat;
return renderGraph.CreateTexture(desc);
}

private static RendererListParams InitRendererListParams(
ShaderTagId shaderTagId,
UniversalRenderingData renderingData,
UniversalCameraData cameraData,
UniversalLightData lightData,
SortingCriteria sortingCriteria,
FilteringSettings filteringSettings)
{
var drawSettings = RenderingUtils.CreateDrawingSettings(shaderTagId, renderingData, cameraData, lightData,
sortingCriteria);
return new RendererListParams(renderingData.cullResults, drawSettings, filteringSettings);
}

private class PassData
{
internal RendererListHandle RendererList;
}
}
}
#endif

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
@@ -0,0 +1,21 @@
// --------------------------------------------------------------
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

#if UNITY_2023_3_OR_NEWER
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;

namespace Nova.Runtime.Core.Scripts
{
public class DistortionContextItem : ContextItem
{
public TextureHandle DistortedUvTexture;

public override void Reset()
{
DistortedUvTexture = TextureHandle.nullHandle;
}
}
}
#endif

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

8 changes: 4 additions & 4 deletions Assets/Nova/Runtime/Core/Scripts/ScreenSpaceDistortion.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// --------------------------------------------------------------
// Copyright 2024 CyberAgent, Inc.
// Copyright 2025 CyberAgent, Inc.
// --------------------------------------------------------------

using System;
Expand Down Expand Up @@ -27,8 +27,7 @@ public sealed class ScreenSpaceDistortion : ScriptableRendererFeature
public override void Create()
{
_applyDistortionShader = Shader.Find("Hidden/Nova/Particles/ApplyDistortion");
if (_applyDistortionShader == null)
{ return; }
if (_applyDistortionShader == null) return;

_distortedUvBufferPass = new DistortedUvBufferPass(DistortionLightMode);
_applyDistortionPass = new ApplyDistortionPass(_applyToSceneView, _applyDistortionShader);
Expand All @@ -39,7 +38,7 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD
if (_applyDistortionShader == null
|| renderingData.cameraData.cameraType == CameraType.Reflection
|| renderingData.cameraData.cameraType == CameraType.Preview)
{ return; }
return;

var distortedUvBufferFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf)
? RenderTextureFormat.RGHalf
Expand All @@ -63,6 +62,7 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD
#endif
renderer.EnqueuePass(_distortedUvBufferPass);
renderer.EnqueuePass(_applyDistortionPass);

#if !UNITY_2022_1_OR_NEWER
RenderTexture.ReleaseTemporary(distortedUvBuffer);
#endif
Expand Down
Loading