1159 lines
68 KiB
C#
1159 lines
68 KiB
C#
#if SURFACE_CACHE
|
|
|
|
using System;
|
|
using Unity.Mathematics;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.PathTracing.Core;
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
|
using UnityEngine.Rendering.UnifiedRayTracing;
|
|
|
|
namespace UnityEngine.Rendering.Universal
|
|
{
|
|
internal struct SurfaceCacheScreenFilteringParameterSet
|
|
{
|
|
public uint LookupSampleCount;
|
|
public float UpsamplingKernelSize;
|
|
public uint UpsamplingSampleCount;
|
|
}
|
|
|
|
[Serializable]
|
|
[SupportedOnRenderPipeline]
|
|
[Categorization.CategoryInfo(Name = "R: Surface Cache URP Integration", Order = 1000), HideInInspector]
|
|
sealed class SurfaceCacheRenderPipelineResourceSet : IRenderPipelineResources
|
|
{
|
|
[SerializeField, HideInInspector]
|
|
int m_Version = 6;
|
|
|
|
int IRenderPipelineGraphicsSettings.version => m_Version;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/FallbackMaterial.mat")]
|
|
public Material m_FallbackMaterial;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute")]
|
|
public ComputeShader m_AllocationShader;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveLookup.compute")]
|
|
public ComputeShader m_ScreenResolveLookupShader;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveUpsampling.compute")]
|
|
public ComputeShader m_ScreenResolveUpsamplingShader;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/Debug.compute")]
|
|
public ComputeShader m_DebugShader;
|
|
|
|
[ResourcePath("Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/FlatNormalResolution.compute")]
|
|
public ComputeShader m_FlatNormalResolutionShader;
|
|
|
|
public Material fallbackMaterial
|
|
{
|
|
get => m_FallbackMaterial;
|
|
set => this.SetValueAndNotify(ref m_FallbackMaterial, value, nameof(m_FallbackMaterial));
|
|
}
|
|
|
|
public ComputeShader allocationShader
|
|
{
|
|
get => m_AllocationShader;
|
|
set => this.SetValueAndNotify(ref m_AllocationShader, value, nameof(m_AllocationShader));
|
|
}
|
|
|
|
public ComputeShader screenResolveLookupShader
|
|
{
|
|
get => m_ScreenResolveLookupShader;
|
|
set => this.SetValueAndNotify(ref m_ScreenResolveLookupShader, value, nameof(m_ScreenResolveLookupShader));
|
|
}
|
|
|
|
public ComputeShader screenResolveUpsamplingShader
|
|
{
|
|
get => m_ScreenResolveUpsamplingShader;
|
|
set => this.SetValueAndNotify(ref m_ScreenResolveUpsamplingShader, value, nameof(m_ScreenResolveUpsamplingShader));
|
|
}
|
|
|
|
public ComputeShader debugShader
|
|
{
|
|
get => m_DebugShader;
|
|
set => this.SetValueAndNotify(ref m_DebugShader, value, nameof(m_DebugShader));
|
|
}
|
|
|
|
public ComputeShader flatNormalResolutionShader
|
|
{
|
|
get => m_FlatNormalResolutionShader;
|
|
set => this.SetValueAndNotify(ref m_FlatNormalResolutionShader, value, nameof(m_FlatNormalResolutionShader));
|
|
}
|
|
}
|
|
|
|
[DisallowMultipleRendererFeature("Surface Cache Global Illumination")]
|
|
public class SurfaceCacheGIRendererFeature : ScriptableRendererFeature
|
|
{
|
|
public enum DebugViewMode_
|
|
{
|
|
CellIndex,
|
|
StableIrradiance,
|
|
FastIrradiance,
|
|
CoefficientOfVariation,
|
|
Drift,
|
|
StdDev,
|
|
UpdateCount,
|
|
FlatNormal
|
|
}
|
|
|
|
public static readonly string k_StaticBatchingErrorMesssage = "Surface Cache GI cannot run because it is incompatible with Static Batching. You can disable the option in the Player Settings.";
|
|
|
|
private const uint DEFAULT_DEFRAG_COUNT = 2; // Default value for how many patches to defragment per frame.
|
|
private const float DEFAULT_VOLUME_SIZE = 128.0f; // Default value for the size of the volume in world units.
|
|
private const uint DEFAULT_VOLUME_RESOLUTION = 32; // Default value for the voxel resolution of the volume.
|
|
private const uint DEFAULT_VOLUME_CASCADE_COUNT = 4; // Default value for the number of cascades in the volume.
|
|
|
|
// URP currently cannot render motion vectors properly in Scene View, so we disable it.
|
|
// https://jira.unity3d.com/browse/SRP-743
|
|
// When this is fixed, we probably want to enable this always.
|
|
static bool UseMotionVectorPatchSeeding(CameraType camType)
|
|
{
|
|
return camType == CameraType.Game;
|
|
}
|
|
|
|
internal static class ShaderIDs
|
|
{
|
|
public static readonly int _RingConfigBuffer = Shader.PropertyToID("_RingConfigBuffer");
|
|
public static readonly int _PatchIrradiances = Shader.PropertyToID("_PatchIrradiances");
|
|
public static readonly int _PatchStatistics = Shader.PropertyToID("_PatchStatistics");
|
|
public static readonly int _PatchGeometries = Shader.PropertyToID("_PatchGeometries");
|
|
public static readonly int _PatchIrradiances0 = Shader.PropertyToID("_PatchIrradiances0");
|
|
public static readonly int _PatchIrradiances1 = Shader.PropertyToID("_PatchIrradiances1");
|
|
public static readonly int _CellAllocationMarks = Shader.PropertyToID("_CellAllocationMarks");
|
|
public static readonly int _CellPatchIndices = Shader.PropertyToID("_CellPatchIndices");
|
|
public static readonly int _Result = Shader.PropertyToID("_Result");
|
|
public static readonly int _FullResDepths = Shader.PropertyToID("_FullResDepths");
|
|
public static readonly int _FullResIrradiances = Shader.PropertyToID("_FullResIrradiances");
|
|
public static readonly int _FullResFlatNormals = Shader.PropertyToID("_FullResFlatNormals");
|
|
public static readonly int _FullResShadedNormals = Shader.PropertyToID("_FullResShadedNormals");
|
|
public static readonly int _UseMotionVectorSeeding = Shader.PropertyToID("_UseMotionVectorSeeding");
|
|
public static readonly int _ResultL0 = Shader.PropertyToID("_ResultL0");
|
|
public static readonly int _ResultL10 = Shader.PropertyToID("_ResultL10");
|
|
public static readonly int _ResultL11 = Shader.PropertyToID("_ResultL11");
|
|
public static readonly int _ResultL12 = Shader.PropertyToID("_ResultL12");
|
|
public static readonly int _ResultNdcDepths = Shader.PropertyToID("_ResultNdcDepths");
|
|
public static readonly int _ScreenDepths = Shader.PropertyToID("_ScreenDepths");
|
|
public static readonly int _ScreenFlatNormals = Shader.PropertyToID("_ScreenFlatNormals");
|
|
public static readonly int _CurrentFullResScreenDepths = Shader.PropertyToID("_CurrentFullResScreenDepths");
|
|
public static readonly int _CurrentFullResScreenFlatNormals = Shader.PropertyToID("_CurrentFullResScreenFlatNormals");
|
|
public static readonly int _CurrentFullResScreenMotionVectors = Shader.PropertyToID("_CurrentFullResScreenMotionVectors");
|
|
public static readonly int _ScreenShadedNormals = Shader.PropertyToID("_ScreenShadedNormals");
|
|
public static readonly int _LowResIrradiancesL0 = Shader.PropertyToID("_LowResIrradiancesL0");
|
|
public static readonly int _LowResIrradiancesL10 = Shader.PropertyToID("_LowResIrradiancesL10");
|
|
public static readonly int _LowResIrradiancesL11 = Shader.PropertyToID("_LowResIrradiancesL11");
|
|
public static readonly int _LowResIrradiancesL12 = Shader.PropertyToID("_LowResIrradiancesL12");
|
|
public static readonly int _PreviousLowResScreenIrradiancesL0 = Shader.PropertyToID("_PreviousLowResScreenIrradiancesL0");
|
|
public static readonly int _PreviousLowResScreenIrradiancesL10 = Shader.PropertyToID("_PreviousLowResScreenIrradiancesL10");
|
|
public static readonly int _PreviousLowResScreenIrradiancesL11 = Shader.PropertyToID("_PreviousLowResScreenIrradiancesL11");
|
|
public static readonly int _PreviousLowResScreenIrradiancesL12 = Shader.PropertyToID("_PreviousLowResScreenIrradiancesL12");
|
|
public static readonly int _PreviousLowResScreenNdcDepths = Shader.PropertyToID("_PreviousLowResScreenNdcDepths");
|
|
public static readonly int _FilterRadius = Shader.PropertyToID("_FilterRadius");
|
|
public static readonly int _ViewMode = Shader.PropertyToID("_ViewMode");
|
|
public static readonly int _ShowSamplePosition = Shader.PropertyToID("_ShowSamplePosition");
|
|
public static readonly int _SampleCount = Shader.PropertyToID("_SampleCount");
|
|
public static readonly int _ClipToWorldTransform = Shader.PropertyToID("_ClipToWorldTransform");
|
|
public static readonly int _CurrentClipToWorldTransform = Shader.PropertyToID("_CurrentClipToWorldTransform");
|
|
public static readonly int _PreviousClipToWorldTransform = Shader.PropertyToID("_PreviousClipToWorldTransform");
|
|
public static readonly int _FrameIdx = Shader.PropertyToID("_FrameIdx");
|
|
public static readonly int _VolumeSpatialResolution = Shader.PropertyToID("_VolumeSpatialResolution");
|
|
public static readonly int _RingConfigOffset = Shader.PropertyToID("_RingConfigOffset");
|
|
public static readonly int _VolumeTargetPos = Shader.PropertyToID("_VolumeTargetPos");
|
|
public static readonly int _FullResPixelOffset = Shader.PropertyToID("_FullResPixelOffset");
|
|
public static readonly int _LowResScreenSize = Shader.PropertyToID("_LowResScreenSize");
|
|
public static readonly int _VolumeCascadeCount = Shader.PropertyToID("_VolumeCascadeCount");
|
|
public static readonly int _VolumeVoxelMinSize = Shader.PropertyToID("_VolumeVoxelMinSize");
|
|
public static readonly int _VolumeCascadeOffsets = Shader.PropertyToID("_VolumeCascadeOffsets");
|
|
public static readonly int _PatchCellIndices = Shader.PropertyToID("_PatchCellIndices");
|
|
}
|
|
|
|
class SurfaceCachePass : ScriptableRenderPass, IDisposable
|
|
{
|
|
private class WorldUpdatePassData
|
|
{
|
|
internal SurfaceCacheWorld World;
|
|
internal uint EnvCubemapResolution;
|
|
internal Light Sun;
|
|
internal Matrix4x4 RestoreViewMatrix;
|
|
internal Matrix4x4 RestoreProjectionMatrix;
|
|
}
|
|
|
|
private class DebugPassData
|
|
{
|
|
internal ComputeShader Shader;
|
|
internal int KernelIndex;
|
|
internal uint3 ThreadGroupSize;
|
|
internal uint3 ThreadCount;
|
|
internal TextureHandle ScreenDepths;
|
|
internal TextureHandle ScreenShadedNormals;
|
|
internal TextureHandle ScreenFlatNormals;
|
|
internal TextureHandle ScreenIrradiances;
|
|
internal GraphicsBuffer CellPatchIndices;
|
|
internal GraphicsBuffer RingConfigBuffer;
|
|
internal GraphicsBuffer PatchIrradiances;
|
|
internal GraphicsBuffer PatchGeometries;
|
|
internal GraphicsBuffer PatchCellIndices;
|
|
internal GraphicsBuffer PatchStatistics;
|
|
internal DebugViewMode_ ViewMode;
|
|
internal uint FrameIndex;
|
|
internal bool ShowSamplePosition;
|
|
internal uint VolumeSpatialResolution;
|
|
internal float VolumeVoxelMinSize;
|
|
internal uint VolumeCascadeCount;
|
|
internal GraphicsBuffer CascadeOffsets;
|
|
internal uint RingConfigOffset;
|
|
internal Matrix4x4 ClipToWorldTransform;
|
|
internal Vector3 VolumeTargetPos;
|
|
}
|
|
|
|
private class FlatNormalResolutionPassData
|
|
{
|
|
internal ComputeShader Shader;
|
|
internal int KernelIndex;
|
|
internal uint3 ThreadGroupSize;
|
|
internal uint3 ThreadCount;
|
|
internal TextureHandle ScreenDepths;
|
|
internal TextureHandle ScreenFlatNormals;
|
|
internal Matrix4x4 ClipToWorldTransform;
|
|
}
|
|
|
|
private class PatchAllocationPassData
|
|
{
|
|
internal ComputeShader Shader;
|
|
internal int KernelIndex;
|
|
internal uint3 ThreadGroupSize;
|
|
internal uint3 ThreadCount;
|
|
internal TextureHandle ScreenDepths;
|
|
internal TextureHandle ScreenFlatNormals;
|
|
internal TextureHandle ScreenMotionVectors;
|
|
internal TextureHandle LowResScreenIrradiancesL0;
|
|
internal TextureHandle LowResScreenIrradiancesL10;
|
|
internal TextureHandle LowResScreenIrradiancesL11;
|
|
internal TextureHandle LowResScreenIrradiancesL12;
|
|
internal TextureHandle LowResScreenNdcDepths;
|
|
internal GraphicsBuffer CellAllocationMarks;
|
|
internal GraphicsBuffer CellPatchIndices;
|
|
internal GraphicsBuffer RingConfigBuffer;
|
|
internal GraphicsBuffer PatchIrradiances0;
|
|
internal GraphicsBuffer PatchIrradiances1;
|
|
internal GraphicsBuffer PatchGeometries;
|
|
internal GraphicsBuffer PatchCellIndices;
|
|
internal GraphicsBuffer PatchStatistics;
|
|
internal uint FrameIdx;
|
|
internal uint VolumeSpatialResolution;
|
|
internal uint VolumeCascadeCount;
|
|
internal uint RingConfigOffset;
|
|
internal bool UseMotionVectorSeeding;
|
|
internal GraphicsBuffer CascadeOffsets;
|
|
internal float VoxelMinSize;
|
|
internal Matrix4x4 CurrentClipToWorldTransform;
|
|
internal Matrix4x4 PreviousClipToWorldTransform;
|
|
internal Vector3 VolumeTargetPos;
|
|
internal uint2 FullResPixelOffset;
|
|
internal uint2 LowResScreenSize;
|
|
}
|
|
|
|
private class ScreenIrradianceLookupPassData
|
|
{
|
|
internal ComputeShader Shader;
|
|
internal int KernelIndex;
|
|
internal uint3 ThreadGroupSize;
|
|
internal uint3 ThreadCount;
|
|
internal TextureHandle FullResDepths;
|
|
internal TextureHandle FullResFlatNormals;
|
|
internal TextureHandle LowResScreenIrradiancesL0;
|
|
internal TextureHandle LowResScreenIrradiancesL10;
|
|
internal TextureHandle LowResScreenIrradiancesL11;
|
|
internal TextureHandle LowResScreenIrradiancesL12;
|
|
internal TextureHandle LowResScreenNdcDepths;
|
|
internal GraphicsBuffer CellPatchIndices;
|
|
internal GraphicsBuffer PatchIrradiances;
|
|
internal GraphicsBuffer PatchStatistics;
|
|
internal GraphicsBuffer CascadeOffsets;
|
|
internal uint VolumeSpatialResolution;
|
|
internal uint VolumeCascadeCount;
|
|
internal uint SampleCount;
|
|
internal uint FrameIndex;
|
|
internal float VolumeVoxelMinSize;
|
|
internal Matrix4x4 ClipToWorldTransform;
|
|
internal Vector3 VolumeTargetPos;
|
|
}
|
|
|
|
private class ScreenIrradianceUpsamplingPassData
|
|
{
|
|
internal ComputeShader Shader;
|
|
internal int KernelIndex;
|
|
internal uint3 ThreadGroupSize;
|
|
internal uint3 FullResThreadCount;
|
|
internal TextureHandle FullResDepths;
|
|
internal TextureHandle FullResShadedNormals;
|
|
internal TextureHandle FullResFlatNormals;
|
|
internal TextureHandle LowResScreenIrradiancesL0;
|
|
internal TextureHandle LowResScreenIrradiancesL10;
|
|
internal TextureHandle LowResScreenIrradiancesL11;
|
|
internal TextureHandle LowResScreenIrradiancesL12;
|
|
internal TextureHandle FullResIrradiances;
|
|
internal float FilterRadius;
|
|
internal uint SampleCount;
|
|
internal Matrix4x4 ClipToWorldTransform;
|
|
}
|
|
|
|
private RTHandle _fullResScreenIrradiances;
|
|
private RTHandle _fullResScreenFlatNormals;
|
|
private RTHandle _lowResScreenIrradiancesL0;
|
|
private RTHandle _lowResScreenIrradiancesL10;
|
|
private RTHandle _lowResScreenIrradiancesL11;
|
|
private RTHandle _lowResScreenIrradiancesL12;
|
|
private RTHandle _lowResScreenNdcDepths;
|
|
private GraphicsBuffer _worldUpdateScratch;
|
|
|
|
private readonly SurfaceCacheWorldAdapter _worldAdapter;
|
|
private readonly InternalBridge.ObjectDispatcher _objDispatcher;
|
|
|
|
private readonly SurfaceCacheWorld _world;
|
|
|
|
private readonly ComputeShader _screenResolveLookupShader;
|
|
private readonly ComputeShader _screenResolveUpsamplingShader;
|
|
private readonly ComputeShader _patchAllocationShader;
|
|
private readonly ComputeShader _debugShader;
|
|
private readonly ComputeShader _flatNormalResolutionShader;
|
|
|
|
private readonly RayTracingContext _rtContext;
|
|
|
|
private readonly int _screenResolveLookupKernel;
|
|
private readonly int _screenResolveUpsamplingKernel;
|
|
private readonly int _patchAllocationKernel;
|
|
private readonly int _debugKernel;
|
|
private readonly int _flatNormalResolutionKernel;
|
|
|
|
private uint3 _screenResolveLookupKernelGroupSize;
|
|
private uint3 _screenResolveUpsamplingKernelGroupSize;
|
|
private uint3 _patchAllocationKernelGroupSize;
|
|
private uint3 _debugKernelGroupSize;
|
|
private uint3 _flatNormalResolutionKernelGroupSize;
|
|
|
|
private uint _frameIdx;
|
|
|
|
// Debug
|
|
private readonly bool _debugEnabled;
|
|
private readonly DebugViewMode_ _debugViewMode;
|
|
private readonly bool _debugShowSamplePosition;
|
|
|
|
private SurfaceCache _cache;
|
|
|
|
private Matrix4x4 _prevClipToWorldTransform = Matrix4x4.identity;
|
|
|
|
private readonly uint _environmentCubemapResolution = 32;
|
|
private const int k_UpscaleFactor = 4;
|
|
|
|
// Defaults, used as fallback when no volume override is active.
|
|
private const uint DEFAULT_ESTIMATION_SAMPLE_COUNT = 2;
|
|
private const float DEFAULT_TEMPORAL_SMOOTHING = 0.8f;
|
|
private const uint DEFAULT_SPATIAL_FILTER_SAMPLE_COUNT = 4;
|
|
private const float DEFAULT_SPATIAL_FILTER_RADIUS = 1.0f;
|
|
private const uint DEFAULT_LOOKUP_SAMPLE_COUNT = 6;
|
|
private const float DEFAULT_UPSAMPLING_KERNEL_SIZE = 5.0f;
|
|
private const uint DEFAULT_UPSAMPLING_SAMPLE_COUNT = 2;
|
|
|
|
// Stored for runtime cache recreation when resolution or cascade count changes
|
|
private readonly Rendering.SurfaceCacheResourceSet _coreResources;
|
|
|
|
public SurfaceCachePass(
|
|
RayTracingContext rtContext,
|
|
UnityEngine.Rendering.SurfaceCacheResourceSet resourceSet,
|
|
WorldResourceSet worldResources,
|
|
ComputeShader patchAllocationShader,
|
|
ComputeShader screenResolveLookupShader,
|
|
ComputeShader screenResolveUpsamplingShader,
|
|
ComputeShader debugShader,
|
|
ComputeShader flatNormalResolutionShader,
|
|
Material fallbackMaterial,
|
|
bool debugEnabled,
|
|
DebugViewMode_ debugViewMode,
|
|
bool debugShowSamplePosition,
|
|
SurfaceCacheVolumeParameterSet volParams)
|
|
{
|
|
Debug.Assert(volParams.CascadeCount != 0);
|
|
Debug.Assert(volParams.CascadeCount <= SurfaceCache.CascadeMax);
|
|
|
|
_screenResolveLookupShader = screenResolveLookupShader;
|
|
_screenResolveUpsamplingShader = screenResolveUpsamplingShader;
|
|
_debugShader = debugShader;
|
|
_flatNormalResolutionShader = flatNormalResolutionShader;
|
|
_patchAllocationShader = patchAllocationShader;
|
|
_rtContext = rtContext;
|
|
|
|
_screenResolveLookupKernel = _screenResolveLookupShader.FindKernel("Lookup");
|
|
_screenResolveUpsamplingKernel = _screenResolveUpsamplingShader.FindKernel("Upsample");
|
|
_patchAllocationKernel = _patchAllocationShader.FindKernel("Allocate");
|
|
_debugKernel = _debugShader.FindKernel("Visualize");
|
|
_flatNormalResolutionKernel = _flatNormalResolutionShader.FindKernel("ResolveFlatNormals");
|
|
|
|
_screenResolveLookupShader.GetKernelThreadGroupSizes(_screenResolveLookupKernel, out _screenResolveLookupKernelGroupSize.x, out _screenResolveLookupKernelGroupSize.y, out _screenResolveLookupKernelGroupSize.z);
|
|
_screenResolveUpsamplingShader.GetKernelThreadGroupSizes(_screenResolveUpsamplingKernel, out _screenResolveUpsamplingKernelGroupSize.x, out _screenResolveUpsamplingKernelGroupSize.y, out _screenResolveUpsamplingKernelGroupSize.z);
|
|
_patchAllocationShader.GetKernelThreadGroupSizes(_patchAllocationKernel, out _patchAllocationKernelGroupSize.x, out _patchAllocationKernelGroupSize.y, out _patchAllocationKernelGroupSize.z);
|
|
_debugShader.GetKernelThreadGroupSizes(_debugKernel, out _debugKernelGroupSize.x, out _debugKernelGroupSize.y, out _debugKernelGroupSize.z);
|
|
_flatNormalResolutionShader.GetKernelThreadGroupSizes(_flatNormalResolutionKernel, out _flatNormalResolutionKernelGroupSize.x, out _flatNormalResolutionKernelGroupSize.y, out _flatNormalResolutionKernelGroupSize.z);
|
|
|
|
_frameIdx = 0;
|
|
|
|
_debugEnabled = debugEnabled;
|
|
_debugViewMode = debugViewMode;
|
|
_debugShowSamplePosition = debugShowSamplePosition;
|
|
|
|
_coreResources = resourceSet;
|
|
|
|
_cache = new SurfaceCache(resourceSet, volParams);
|
|
_cache.SetEmissiveTriangleIntensityMultiplier(k_EmissiveTriangleIntensityMultiplier);
|
|
|
|
_world = new SurfaceCacheWorld();
|
|
_world.Init(_rtContext, worldResources);
|
|
|
|
_objDispatcher = new();
|
|
_worldAdapter = new SurfaceCacheWorldAdapter(_objDispatcher, _world, fallbackMaterial);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_fullResScreenIrradiances?.Release();
|
|
_fullResScreenFlatNormals?.Release();
|
|
_lowResScreenIrradiancesL0?.Release();
|
|
_lowResScreenIrradiancesL10?.Release();
|
|
_lowResScreenIrradiancesL11?.Release();
|
|
_lowResScreenIrradiancesL12?.Release();
|
|
_lowResScreenNdcDepths?.Release();
|
|
_cache.Dispose();
|
|
_worldAdapter.CleanUp(_world);
|
|
_objDispatcher.Dispose();
|
|
_world.Dispose();
|
|
_worldUpdateScratch?.Dispose();
|
|
}
|
|
|
|
// Historically, GI systems in Unity have, for historical reasons, 1) multiplied punctual light intensity
|
|
// inputs with PI, and 2) divided all GI output with PI. To match this, Surface Cache for now does
|
|
// something mathematically equivalent: It divides environment light and triangle emission by PI.
|
|
// Ideally, we'd get rid of this behavior across all Unity GI systems in the future.
|
|
// Note that this is distinct from the separate issue that URP is generally off by PI in its output.
|
|
private const bool k_ConformToUnityGIFormat = true;
|
|
|
|
private const float k_EmissiveTriangleIntensityMultiplier = k_ConformToUnityGIFormat ? 1.0f / Mathf.PI : 1.0f;
|
|
|
|
private static VolumeParameterSet GetVolumeParametersOrDefaults(SurfaceCacheGIVolumeOverride volume)
|
|
{
|
|
if (volume != null)
|
|
{
|
|
// Use volume parameters
|
|
return new VolumeParameterSet
|
|
{
|
|
EstimationParams = new SurfaceCacheEstimationParameterSet
|
|
{
|
|
MultiBounce = volume.multiBounce.value,
|
|
BouncePatchAllocation = volume.bouncePatchAllocation.value,
|
|
SampleCount = (uint)volume.sampleCount.value,
|
|
},
|
|
PatchFilteringParams = new SurfaceCachePatchFilteringParameterSet
|
|
{
|
|
TemporalSmoothing = volume.temporalSmoothing.value,
|
|
SpatialFilterEnabled = volume.spatialFilterEnabled.value,
|
|
SpatialFilterSampleCount = (uint)volume.spatialSampleCount.value,
|
|
SpatialFilterRadius = volume.spatialRadius.value,
|
|
TemporalPostFilterEnabled = volume.temporalPostFilter.value
|
|
},
|
|
ScreenFilteringParams = new SurfaceCacheScreenFilteringParameterSet
|
|
{
|
|
LookupSampleCount = (uint)volume.lookupSampleCount.value,
|
|
UpsamplingKernelSize = volume.upsamplingKernelSize.value,
|
|
UpsamplingSampleCount = (uint)volume.upsamplingSampleCount.value,
|
|
},
|
|
CascadeMovement = volume.cascadeMovement.value,
|
|
VolumeSize = volume.volumeSize.value,
|
|
VolumeResolution = (uint)volume.volumeResolution.value,
|
|
VolumeCascadeCount = (uint)volume.volumeCascadeCount.value,
|
|
DefragCount = (uint)volume.defragCount.value,
|
|
RenderingLayerMask = volume.renderingLayerMask.value
|
|
};
|
|
}
|
|
else
|
|
{
|
|
// Fallback to defaults.
|
|
return new VolumeParameterSet
|
|
{
|
|
EstimationParams = new SurfaceCacheEstimationParameterSet
|
|
{
|
|
MultiBounce = true,
|
|
BouncePatchAllocation = false,
|
|
SampleCount = DEFAULT_ESTIMATION_SAMPLE_COUNT,
|
|
},
|
|
PatchFilteringParams = new SurfaceCachePatchFilteringParameterSet
|
|
{
|
|
TemporalSmoothing = DEFAULT_TEMPORAL_SMOOTHING,
|
|
SpatialFilterEnabled = true,
|
|
SpatialFilterSampleCount = DEFAULT_SPATIAL_FILTER_SAMPLE_COUNT,
|
|
SpatialFilterRadius = DEFAULT_SPATIAL_FILTER_RADIUS,
|
|
TemporalPostFilterEnabled = true
|
|
},
|
|
ScreenFilteringParams = new SurfaceCacheScreenFilteringParameterSet
|
|
{
|
|
LookupSampleCount = DEFAULT_LOOKUP_SAMPLE_COUNT,
|
|
UpsamplingKernelSize = DEFAULT_UPSAMPLING_KERNEL_SIZE,
|
|
UpsamplingSampleCount = DEFAULT_UPSAMPLING_SAMPLE_COUNT,
|
|
},
|
|
CascadeMovement = true,
|
|
VolumeSize = DEFAULT_VOLUME_SIZE,
|
|
VolumeResolution = DEFAULT_VOLUME_RESOLUTION,
|
|
VolumeCascadeCount = DEFAULT_VOLUME_CASCADE_COUNT,
|
|
DefragCount = DEFAULT_DEFRAG_COUNT,
|
|
RenderingLayerMask = 0xFFFFFFFF
|
|
};
|
|
}
|
|
}
|
|
|
|
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
|
{
|
|
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
|
|
Debug.Assert(resourceData.cameraDepthTexture.IsValid());
|
|
Debug.Assert(resourceData.cameraNormalsTexture.IsValid());
|
|
Debug.Assert(resourceData.motionVectorColor.IsValid());
|
|
|
|
UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
|
|
var worldToViewTransform = cameraData.GetViewMatrix();
|
|
var viewToClipTransform = cameraData.GetGPUProjectionMatrix(true);
|
|
var worldToClipTransform = viewToClipTransform * worldToViewTransform;
|
|
var clipToWorldTransform = worldToClipTransform.inverse;
|
|
|
|
var screenResolution = new int2(cameraData.pixelWidth, cameraData.pixelHeight);
|
|
|
|
// This avoids applying surface cache to e.g. preview cameras.
|
|
if (cameraData.cameraType != CameraType.Game && cameraData.cameraType != CameraType.SceneView)
|
|
return;
|
|
|
|
// Get volume parameters that can change per-frame.
|
|
var stack = VolumeManager.instance.stack;
|
|
var volume = stack.GetComponent<SurfaceCacheGIVolumeOverride>();
|
|
var volumeParams = GetVolumeParametersOrDefaults(volume);
|
|
|
|
// Detect structural changes that require buffer reallocation.
|
|
if (volumeParams.VolumeResolution != _cache.Volume.SpatialResolution || volumeParams.VolumeCascadeCount != _cache.Volume.CascadeCount)
|
|
{
|
|
uint newResolution = volumeParams.VolumeResolution;
|
|
uint newCascadeCount = volumeParams.VolumeCascadeCount;
|
|
Debug.Assert(newCascadeCount != 0 && newCascadeCount <= SurfaceCache.CascadeMax);
|
|
|
|
_cache.Dispose();
|
|
var newVolParams = new SurfaceCacheVolumeParameterSet
|
|
{
|
|
Resolution = newResolution,
|
|
Size = volumeParams.VolumeSize,
|
|
CascadeCount = newCascadeCount
|
|
};
|
|
_cache = new SurfaceCache(_coreResources, newVolParams);
|
|
_cache.SetEmissiveTriangleIntensityMultiplier(k_EmissiveTriangleIntensityMultiplier);
|
|
_frameIdx = 0;
|
|
}
|
|
|
|
_cache.SetEstimationParams(volumeParams.EstimationParams);
|
|
_cache.SetPatchFilteringParams(volumeParams.PatchFilteringParams);
|
|
_cache.SetVolumeSize(volumeParams.VolumeSize);
|
|
_cache.SetDefragCount(volumeParams.DefragCount);
|
|
|
|
bool useMotionVectorPatchSeeding = UseMotionVectorPatchSeeding(cameraData.cameraType);
|
|
|
|
if (_fullResScreenIrradiances == null || _fullResScreenIrradiances.GetScaledSize() != new Vector2Int(screenResolution.x, screenResolution.y))
|
|
{
|
|
int lowResWidth = (screenResolution.x + k_UpscaleFactor - 1) / k_UpscaleFactor;
|
|
int lowResHeight = (screenResolution.y + k_UpscaleFactor - 1) / k_UpscaleFactor;
|
|
|
|
_fullResScreenIrradiances?.Release();
|
|
_fullResScreenIrradiances = RTHandles.Alloc((int)screenResolution.x, (int)screenResolution.y, 1, DepthBits.None, GraphicsFormat.R16G16B16A16_SFloat, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_fullResScreenIrradiances");
|
|
|
|
_fullResScreenFlatNormals?.Release();
|
|
_fullResScreenFlatNormals = RTHandles.Alloc((int)screenResolution.x, (int)screenResolution.y, 1, DepthBits.None, GraphicsFormat.R8G8B8A8_SNorm, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_fullResScreenFlatNormals");
|
|
|
|
var l0Format = GraphicsFormat.R16G16B16A16_SFloat;
|
|
var l1Format = GraphicsFormat.R8G8B8A8_UNorm;
|
|
_lowResScreenIrradiancesL0?.Release();
|
|
_lowResScreenIrradiancesL0 = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, l0Format, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenIrradiancesL0");
|
|
_lowResScreenIrradiancesL10?.Release();
|
|
_lowResScreenIrradiancesL10 = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, l1Format, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenIrradiancesL10");
|
|
_lowResScreenIrradiancesL11?.Release();
|
|
_lowResScreenIrradiancesL11 = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, l1Format, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenIrradiancesL11");
|
|
_lowResScreenIrradiancesL12?.Release();
|
|
_lowResScreenIrradiancesL12 = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, l1Format, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenIrradiancesL12");
|
|
_lowResScreenNdcDepths?.Release();
|
|
_lowResScreenNdcDepths = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, GraphicsFormat.R16_UNorm, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenNdcDepths");
|
|
}
|
|
|
|
if (volumeParams.CascadeMovement || _frameIdx == 0)
|
|
{
|
|
_cache.Volume.TargetPos = cameraData.camera.transform.position;
|
|
}
|
|
|
|
_cache.RecordPreparation(renderGraph, _frameIdx);
|
|
|
|
var fullResScreenIrradiancesHandle = renderGraph.ImportTexture(_fullResScreenIrradiances);
|
|
var fullResScreenFlatNormalsHandle = renderGraph.ImportTexture(_fullResScreenFlatNormals);
|
|
var lowResScreenIrradiancesL0Handle = renderGraph.ImportTexture(_lowResScreenIrradiancesL0);
|
|
var lowResScreenIrradiancesL10Handle = renderGraph.ImportTexture(_lowResScreenIrradiancesL10);
|
|
var lowResScreenIrradiancesL11Handle = renderGraph.ImportTexture(_lowResScreenIrradiancesL11);
|
|
var lowResScreenIrradiancesL12Handle = renderGraph.ImportTexture(_lowResScreenIrradiancesL12);
|
|
var lowResScreenNdcDepthsHandle = renderGraph.ImportTexture(_lowResScreenNdcDepths);
|
|
var cellAllocationMarkHandle = renderGraph.ImportBuffer(_cache.Volume.CellAllocationMarks);
|
|
|
|
using (var builder = renderGraph.AddComputePass("Surface Cache Flat Normal Resolution", out FlatNormalResolutionPassData passData))
|
|
{
|
|
passData.ThreadCount = new uint3((uint)screenResolution.x, (uint)screenResolution.y, 1);
|
|
passData.Shader = _flatNormalResolutionShader;
|
|
passData.KernelIndex = _flatNormalResolutionKernel;
|
|
passData.ThreadGroupSize = _flatNormalResolutionKernelGroupSize;
|
|
passData.ScreenDepths = resourceData.cameraDepthTexture;
|
|
passData.ScreenFlatNormals = fullResScreenFlatNormalsHandle;
|
|
passData.ClipToWorldTransform = clipToWorldTransform;
|
|
|
|
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
|
|
builder.UseTexture(fullResScreenFlatNormalsHandle, AccessFlags.Write);
|
|
builder.SetRenderFunc((FlatNormalResolutionPassData data, ComputeGraphContext cgContext) => ResolveFlatNormals(data, cgContext));
|
|
}
|
|
|
|
using (var builder = renderGraph.AddComputePass("Surface Cache Patch Allocation", out PatchAllocationPassData passData))
|
|
{
|
|
uint2 fullResScreenSize = new uint2((uint)screenResolution.x, (uint)screenResolution.y);
|
|
uint2 lowResScreenSize = DivUp(fullResScreenSize, new uint2(k_UpscaleFactor, k_UpscaleFactor));
|
|
|
|
passData.ThreadCount = new uint3(lowResScreenSize, 1);
|
|
passData.Shader = _patchAllocationShader;
|
|
passData.KernelIndex = _patchAllocationKernel;
|
|
passData.ThreadGroupSize = _patchAllocationKernelGroupSize;
|
|
passData.ScreenDepths = resourceData.cameraDepthTexture;
|
|
passData.ScreenFlatNormals = fullResScreenFlatNormalsHandle;
|
|
passData.ScreenMotionVectors = resourceData.motionVectorColor;
|
|
passData.LowResScreenIrradiancesL0 = lowResScreenIrradiancesL0Handle;
|
|
passData.LowResScreenIrradiancesL10 = lowResScreenIrradiancesL10Handle;
|
|
passData.LowResScreenIrradiancesL11 = lowResScreenIrradiancesL11Handle;
|
|
passData.LowResScreenIrradiancesL12 = lowResScreenIrradiancesL12Handle;
|
|
passData.LowResScreenNdcDepths = lowResScreenNdcDepthsHandle;
|
|
passData.CellAllocationMarks = _cache.Volume.CellAllocationMarks;
|
|
passData.CellPatchIndices = _cache.Volume.CellPatchIndices;
|
|
passData.RingConfigBuffer = _cache.RingConfig.Buffer;
|
|
passData.PatchIrradiances0 = _cache.Patches.Irradiances[0];
|
|
passData.PatchIrradiances1 = _cache.Patches.Irradiances[2];
|
|
passData.PatchGeometries = _cache.Patches.Geometries;
|
|
passData.PatchCellIndices = _cache.Patches.CellIndices;
|
|
passData.PatchStatistics = _cache.Patches.Statistics;
|
|
passData.FrameIdx = _frameIdx;
|
|
passData.VolumeSpatialResolution = _cache.Volume.SpatialResolution;
|
|
passData.VolumeCascadeCount = _cache.Volume.CascadeCount;
|
|
passData.RingConfigOffset = _cache.RingConfig.OffsetA;
|
|
|
|
{
|
|
Debug.Assert(k_UpscaleFactor == 4);
|
|
uint cycleIndex = _frameIdx % 4;
|
|
uint shuffledCycleIndex = cycleIndex * 7 % 16;
|
|
passData.FullResPixelOffset = new uint2(shuffledCycleIndex / 4, shuffledCycleIndex % 4);
|
|
}
|
|
|
|
passData.LowResScreenSize = lowResScreenSize;
|
|
passData.UseMotionVectorSeeding = useMotionVectorPatchSeeding;
|
|
passData.CascadeOffsets = _cache.Volume.CascadeOffsetBuffer;
|
|
passData.VoxelMinSize = _cache.Volume.VoxelMinSize;
|
|
passData.CurrentClipToWorldTransform = clipToWorldTransform;
|
|
passData.PreviousClipToWorldTransform = _prevClipToWorldTransform;
|
|
passData.VolumeTargetPos = _cache.Volume.TargetPos;
|
|
|
|
builder.UseBuffer(cellAllocationMarkHandle, AccessFlags.Write);
|
|
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
|
|
builder.UseTexture(fullResScreenFlatNormalsHandle, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.motionVectorColor, AccessFlags.Read);
|
|
builder.UseTexture(lowResScreenIrradiancesL0Handle, AccessFlags.Read);
|
|
builder.UseTexture(lowResScreenIrradiancesL10Handle, AccessFlags.Read);
|
|
builder.UseTexture(lowResScreenIrradiancesL11Handle, AccessFlags.Read);
|
|
builder.UseTexture(lowResScreenIrradiancesL12Handle, AccessFlags.Read);
|
|
builder.UseTexture(lowResScreenNdcDepthsHandle, AccessFlags.Read);
|
|
|
|
builder.SetRenderFunc((PatchAllocationPassData data, ComputeGraphContext cgContext) => AllocatePatches(data, cgContext));
|
|
}
|
|
|
|
// RenderSettings.ambientIntensity is used directly as a linear value for Surface Cache, which is not currently
|
|
// the case for the standard ambient probe lighting, which is assumed to be in gamma space and then converted to
|
|
// linear space. We will make this more coherent for the ambient probe in the future.
|
|
// Similarly, the ambient colors are all defined in sRGB space and must be converted to linear.
|
|
_worldAdapter.Update(
|
|
_objDispatcher,
|
|
RenderSettings.ambientMode,
|
|
RenderSettings.skybox,
|
|
RenderSettings.ambientSkyColor.linear,
|
|
RenderSettings.ambientEquatorColor.linear,
|
|
RenderSettings.ambientGroundColor.linear,
|
|
RenderSettings.ambientIntensity,
|
|
k_ConformToUnityGIFormat,
|
|
volumeParams.RenderingLayerMask,
|
|
_world);
|
|
|
|
using (var builder = renderGraph.AddUnsafePass("Surface Cache World Update", out WorldUpdatePassData passData))
|
|
{
|
|
passData.World = _world;
|
|
passData.EnvCubemapResolution = _environmentCubemapResolution;
|
|
passData.Sun = RenderSettings.sun;
|
|
passData.RestoreProjectionMatrix = cameraData.GetProjectionMatrix();
|
|
passData.RestoreViewMatrix = worldToViewTransform;
|
|
|
|
builder.AllowGlobalStateModification(true);
|
|
builder.SetRenderFunc((WorldUpdatePassData data, UnsafeGraphContext graphCtx) => UpdateWorld(data, graphCtx, ref _worldUpdateScratch));
|
|
}
|
|
|
|
uint outputIrradianceBufferIdx = _cache.RecordPatchUpdate(renderGraph, _frameIdx, _world);
|
|
|
|
using (var builder = renderGraph.AddComputePass("Surface Cache Screen Lookup", out ScreenIrradianceLookupPassData data))
|
|
{
|
|
data.VolumeTargetPos = _cache.Volume.TargetPos;
|
|
data.ClipToWorldTransform = clipToWorldTransform;
|
|
data.ThreadCount = new uint3((uint)_lowResScreenIrradiancesL0.rt.width, (uint)_lowResScreenIrradiancesL0.rt.height, 1);
|
|
data.Shader = _screenResolveLookupShader;
|
|
data.KernelIndex = _screenResolveLookupKernel;
|
|
data.ThreadGroupSize = _screenResolveLookupKernelGroupSize;
|
|
data.FullResDepths = resourceData.cameraDepthTexture;
|
|
data.FullResFlatNormals = fullResScreenFlatNormalsHandle;
|
|
data.LowResScreenIrradiancesL0 = lowResScreenIrradiancesL0Handle;
|
|
data.LowResScreenIrradiancesL10 = lowResScreenIrradiancesL10Handle;
|
|
data.LowResScreenIrradiancesL11 = lowResScreenIrradiancesL11Handle;
|
|
data.LowResScreenIrradiancesL12 = lowResScreenIrradiancesL12Handle;
|
|
data.LowResScreenNdcDepths = lowResScreenNdcDepthsHandle;
|
|
data.CellPatchIndices = _cache.Volume.CellPatchIndices;
|
|
data.PatchIrradiances = _cache.Patches.Irradiances[outputIrradianceBufferIdx];
|
|
data.PatchStatistics = _cache.Patches.Statistics;
|
|
data.CascadeOffsets = _cache.Volume.CascadeOffsetBuffer;
|
|
data.VolumeSpatialResolution = _cache.Volume.SpatialResolution;
|
|
data.VolumeVoxelMinSize = _cache.Volume.VoxelMinSize;
|
|
data.VolumeCascadeCount = _cache.Volume.CascadeCount;
|
|
data.SampleCount = volumeParams.ScreenFilteringParams.LookupSampleCount;
|
|
data.FrameIndex = _frameIdx;
|
|
|
|
builder.UseBuffer(cellAllocationMarkHandle, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
|
|
builder.UseTexture(fullResScreenFlatNormalsHandle, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.motionVectorColor, AccessFlags.Read);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL0, AccessFlags.Write);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL10, AccessFlags.Write);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL11, AccessFlags.Write);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL12, AccessFlags.Write);
|
|
builder.UseTexture(data.LowResScreenNdcDepths, AccessFlags.Write);
|
|
|
|
builder.SetRenderFunc((ScreenIrradianceLookupPassData data, ComputeGraphContext cgContext) => LookupScreenIrradiance(data, cgContext));
|
|
}
|
|
|
|
if (_debugEnabled)
|
|
{
|
|
using (var builder = renderGraph.AddComputePass("Surface Cache Debug", out DebugPassData passData))
|
|
{
|
|
passData.ThreadCount = new uint3((uint)screenResolution.x, (uint)screenResolution.y, 1);
|
|
passData.Shader = _debugShader;
|
|
passData.KernelIndex = _debugKernel;
|
|
passData.ThreadGroupSize = _debugKernelGroupSize;
|
|
passData.ScreenDepths = resourceData.cameraDepthTexture;
|
|
passData.ScreenShadedNormals = resourceData.cameraNormalsTexture;
|
|
passData.ScreenFlatNormals = fullResScreenFlatNormalsHandle;
|
|
passData.ScreenIrradiances = fullResScreenIrradiancesHandle;
|
|
passData.PatchCellIndices = _cache.Patches.CellIndices;
|
|
passData.CellPatchIndices = _cache.Volume.CellPatchIndices;
|
|
passData.RingConfigBuffer = _cache.RingConfig.Buffer;
|
|
passData.RingConfigOffset = _cache.RingConfig.OffsetA;
|
|
passData.VolumeTargetPos = _cache.Volume.TargetPos;
|
|
passData.PatchIrradiances = _cache.Patches.Irradiances[outputIrradianceBufferIdx];
|
|
passData.PatchGeometries = _cache.Patches.Geometries;
|
|
passData.PatchStatistics = _cache.Patches.Statistics;
|
|
passData.VolumeSpatialResolution = _cache.Volume.SpatialResolution;
|
|
passData.VolumeVoxelMinSize = _cache.Volume.VoxelMinSize;
|
|
passData.VolumeCascadeCount = _cache.Volume.CascadeCount;
|
|
passData.CascadeOffsets = _cache.Volume.CascadeOffsetBuffer;
|
|
passData.ViewMode = _debugViewMode;
|
|
passData.FrameIndex = _frameIdx;
|
|
passData.ShowSamplePosition = _debugShowSamplePosition;
|
|
passData.ClipToWorldTransform = clipToWorldTransform;
|
|
|
|
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.cameraNormalsTexture, AccessFlags.Read);
|
|
builder.UseTexture(fullResScreenFlatNormalsHandle, AccessFlags.Read);
|
|
builder.UseTexture(passData.ScreenIrradiances, AccessFlags.Write);
|
|
|
|
builder.SetRenderFunc((DebugPassData data, ComputeGraphContext cgContext) => RenderDebug(data, cgContext));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (var builder = renderGraph.AddComputePass("Surface Cache Screen Upsampling", out ScreenIrradianceUpsamplingPassData data))
|
|
{
|
|
data.ClipToWorldTransform = clipToWorldTransform;
|
|
data.FullResThreadCount = new uint3((uint)screenResolution.x, (uint)screenResolution.y, 1);
|
|
data.Shader = _screenResolveUpsamplingShader;
|
|
data.KernelIndex = _screenResolveUpsamplingKernel;
|
|
data.ThreadGroupSize = _screenResolveUpsamplingKernelGroupSize;
|
|
data.FullResDepths = resourceData.cameraDepthTexture;
|
|
data.FullResShadedNormals = resourceData.cameraNormalsTexture;
|
|
data.FullResFlatNormals = fullResScreenFlatNormalsHandle;
|
|
data.LowResScreenIrradiancesL0 = lowResScreenIrradiancesL0Handle;
|
|
data.LowResScreenIrradiancesL10 = lowResScreenIrradiancesL10Handle;
|
|
data.LowResScreenIrradiancesL11 = lowResScreenIrradiancesL11Handle;
|
|
data.LowResScreenIrradiancesL12 = lowResScreenIrradiancesL12Handle;
|
|
data.FullResIrradiances = fullResScreenIrradiancesHandle;
|
|
data.FilterRadius = volumeParams.ScreenFilteringParams.UpsamplingKernelSize;
|
|
data.SampleCount = volumeParams.ScreenFilteringParams.UpsamplingSampleCount;
|
|
|
|
builder.UseTexture(data.FullResIrradiances, AccessFlags.Write);
|
|
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.cameraNormalsTexture, AccessFlags.Read);
|
|
builder.UseTexture(fullResScreenFlatNormalsHandle, AccessFlags.Read);
|
|
builder.UseTexture(resourceData.motionVectorColor, AccessFlags.Read);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL0, AccessFlags.Read);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL10, AccessFlags.Read);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL11, AccessFlags.Read);
|
|
builder.UseTexture(data.LowResScreenIrradiancesL12, AccessFlags.Read);
|
|
builder.UseBuffer(cellAllocationMarkHandle, AccessFlags.Read);
|
|
|
|
builder.SetRenderFunc((ScreenIrradianceUpsamplingPassData data, ComputeGraphContext cgContext) => UpsampleScreenIrradiance(data, cgContext));
|
|
}
|
|
}
|
|
|
|
resourceData.irradianceTexture = fullResScreenIrradiancesHandle;
|
|
_frameIdx++;
|
|
_prevClipToWorldTransform = clipToWorldTransform;
|
|
}
|
|
|
|
static void UpdateWorld(WorldUpdatePassData data, UnsafeGraphContext graphCtx, ref GraphicsBuffer scratch)
|
|
{
|
|
var cmd = CommandBufferHelpers.GetNativeCommandBuffer(graphCtx.cmd);
|
|
data.World.Commit(cmd, ref scratch, data.EnvCubemapResolution, data.Sun, out bool viewAndProjectionMatricesChanged);
|
|
if (viewAndProjectionMatricesChanged)
|
|
{
|
|
cmd.SetViewProjectionMatrices(data.RestoreViewMatrix, data.RestoreProjectionMatrix);
|
|
}
|
|
}
|
|
|
|
static void LookupScreenIrradiance(ScreenIrradianceLookupPassData data, ComputeGraphContext cgContext)
|
|
{
|
|
var cmd = cgContext.cmd;
|
|
var shader = data.Shader;
|
|
var kernelIndex = data.KernelIndex;
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ResultL0, data.LowResScreenIrradiancesL0);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ResultL10, data.LowResScreenIrradiancesL10);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ResultL11, data.LowResScreenIrradiancesL11);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ResultL12, data.LowResScreenIrradiancesL12);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ResultNdcDepths, data.LowResScreenNdcDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenDepths, data.FullResDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenFlatNormals, data.FullResFlatNormals);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._CellPatchIndices, data.CellPatchIndices);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchIrradiances, data.PatchIrradiances);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._VolumeCascadeOffsets, data.CascadeOffsets);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchStatistics, data.PatchStatistics);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeSpatialResolution, (int)data.VolumeSpatialResolution);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeCascadeCount, (int)data.VolumeCascadeCount);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._SampleCount, (int)data.SampleCount);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._FrameIdx, (int)data.FrameIndex);
|
|
cmd.SetComputeFloatParam(shader, ShaderIDs._VolumeVoxelMinSize, data.VolumeVoxelMinSize);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._ClipToWorldTransform, data.ClipToWorldTransform);
|
|
cmd.SetComputeVectorParam(shader, ShaderIDs._VolumeTargetPos, data.VolumeTargetPos);
|
|
|
|
uint3 groupCount = DivUp(data.ThreadCount, data.ThreadGroupSize);
|
|
cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1);
|
|
}
|
|
|
|
static void UpsampleScreenIrradiance(ScreenIrradianceUpsamplingPassData passData, ComputeGraphContext cgContext)
|
|
{
|
|
var cmd = cgContext.cmd;
|
|
|
|
var shader = passData.Shader;
|
|
var kernelIndex = passData.KernelIndex;
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._FullResIrradiances, passData.FullResIrradiances);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._FullResDepths, passData.FullResDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._FullResFlatNormals, passData.FullResFlatNormals);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._FullResShadedNormals, passData.FullResShadedNormals);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._LowResIrradiancesL0, passData.LowResScreenIrradiancesL0);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._LowResIrradiancesL10, passData.LowResScreenIrradiancesL10);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._LowResIrradiancesL11, passData.LowResScreenIrradiancesL11);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._LowResIrradiancesL12, passData.LowResScreenIrradiancesL12);
|
|
cmd.SetComputeFloatParam(shader, ShaderIDs._FilterRadius, passData.FilterRadius);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._SampleCount, (int)passData.SampleCount);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._ClipToWorldTransform, passData.ClipToWorldTransform);
|
|
|
|
uint3 groupCount = DivUp(passData.FullResThreadCount, passData.ThreadGroupSize);
|
|
cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1);
|
|
}
|
|
|
|
static void ResolveFlatNormals(FlatNormalResolutionPassData data, ComputeGraphContext cgContext)
|
|
{
|
|
var cmd = cgContext.cmd;
|
|
var shader = data.Shader;
|
|
var kernelIndex = data.KernelIndex;
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenDepths, data.ScreenDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenFlatNormals, data.ScreenFlatNormals);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._ClipToWorldTransform, data.ClipToWorldTransform);
|
|
|
|
uint3 groupCount = DivUp(data.ThreadCount, data.ThreadGroupSize);
|
|
cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1);
|
|
}
|
|
|
|
static void AllocatePatches(PatchAllocationPassData data, ComputeGraphContext cgContext)
|
|
{
|
|
var cmd = cgContext.cmd;
|
|
var shader = data.Shader;
|
|
var kernelIndex = data.KernelIndex;
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._CurrentFullResScreenDepths, data.ScreenDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._CurrentFullResScreenFlatNormals, data.ScreenFlatNormals);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._CurrentFullResScreenMotionVectors, data.ScreenMotionVectors);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._PreviousLowResScreenIrradiancesL0, data.LowResScreenIrradiancesL0);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._PreviousLowResScreenIrradiancesL10, data.LowResScreenIrradiancesL10);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._PreviousLowResScreenIrradiancesL11, data.LowResScreenIrradiancesL11);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._PreviousLowResScreenIrradiancesL12, data.LowResScreenIrradiancesL12);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._PreviousLowResScreenNdcDepths, data.LowResScreenNdcDepths);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._CellAllocationMarks, data.CellAllocationMarks);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._CellPatchIndices, data.CellPatchIndices);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._RingConfigBuffer, data.RingConfigBuffer);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchIrradiances0, data.PatchIrradiances0);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchIrradiances1, data.PatchIrradiances1);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchGeometries, data.PatchGeometries);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchCellIndices, data.PatchCellIndices);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchStatistics, data.PatchStatistics);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._VolumeCascadeOffsets, data.CascadeOffsets);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._FrameIdx, (int)data.FrameIdx);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeSpatialResolution, (int)data.VolumeSpatialResolution);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeCascadeCount, (int)data.VolumeCascadeCount);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._RingConfigOffset, (int)data.RingConfigOffset);
|
|
cmd.SetComputeIntParams(shader, ShaderIDs._FullResPixelOffset, (int)data.FullResPixelOffset.x, (int)data.FullResPixelOffset.y);
|
|
cmd.SetComputeIntParams(shader, ShaderIDs._LowResScreenSize, (int)data.LowResScreenSize.x, (int)data.LowResScreenSize.y);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._UseMotionVectorSeeding, data.UseMotionVectorSeeding ? 1 : 0);
|
|
cmd.SetComputeFloatParam(shader, ShaderIDs._VolumeVoxelMinSize, data.VoxelMinSize);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._CurrentClipToWorldTransform, data.CurrentClipToWorldTransform);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._PreviousClipToWorldTransform, data.PreviousClipToWorldTransform);
|
|
cmd.SetComputeVectorParam(shader, ShaderIDs._VolumeTargetPos, data.VolumeTargetPos);
|
|
|
|
uint3 groupCount = DivUp(data.ThreadCount, data.ThreadGroupSize);
|
|
cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1);
|
|
}
|
|
|
|
static void RenderDebug(DebugPassData data, ComputeGraphContext cgContext)
|
|
{
|
|
var cmd = cgContext.cmd;
|
|
var shader = data.Shader;
|
|
var kernelIndex = data.KernelIndex;
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._Result, data.ScreenIrradiances);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenDepths, data.ScreenDepths);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenShadedNormals, data.ScreenShadedNormals);
|
|
cmd.SetComputeTextureParam(shader, kernelIndex, ShaderIDs._ScreenFlatNormals, data.ScreenFlatNormals);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._CellPatchIndices, data.CellPatchIndices);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._RingConfigBuffer, data.RingConfigBuffer);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchIrradiances, data.PatchIrradiances);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchGeometries, data.PatchGeometries);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._VolumeCascadeOffsets, data.CascadeOffsets);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchCellIndices, data.PatchCellIndices);
|
|
cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchStatistics, data.PatchStatistics);
|
|
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeSpatialResolution, (int)data.VolumeSpatialResolution);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._VolumeCascadeCount, (int)data.VolumeCascadeCount);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._ViewMode, (int)data.ViewMode);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._FrameIdx, (int)data.FrameIndex);
|
|
cmd.SetComputeIntParam(shader, ShaderIDs._ShowSamplePosition, data.ShowSamplePosition ? 1 : 0);
|
|
cmd.SetComputeFloatParam(shader, ShaderIDs._VolumeVoxelMinSize, data.VolumeVoxelMinSize);
|
|
cmd.SetComputeFloatParam(shader, ShaderIDs._RingConfigOffset, data.RingConfigOffset);
|
|
cmd.SetComputeVectorParam(shader, ShaderIDs._VolumeTargetPos, data.VolumeTargetPos);
|
|
cmd.SetComputeMatrixParam(shader, ShaderIDs._ClipToWorldTransform, data.ClipToWorldTransform);
|
|
|
|
uint3 groupCount = DivUp(data.ThreadCount, data.ThreadGroupSize);
|
|
cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1);
|
|
}
|
|
|
|
private static uint3 DivUp(uint3 x, uint3 y) => (x + y - 1) / y;
|
|
|
|
private static uint2 DivUp(uint2 x, uint2 y) => (x + y - 1) / y;
|
|
}
|
|
|
|
private SurfaceCachePass _pass;
|
|
private RayTracingContext _rtContext;
|
|
[SerializeField] private ParameterSet _parameterSet = new ParameterSet();
|
|
|
|
// Main parameter set containing advanced and debug settings.
|
|
[Serializable]
|
|
class ParameterSet
|
|
{
|
|
// Debug settings (will be moved to rendering debugger in the future)
|
|
public bool DebugEnabled = false;
|
|
public DebugViewMode_ DebugViewMode = DebugViewMode_.CellIndex;
|
|
public bool DebugShowSamplePosition = false;
|
|
}
|
|
|
|
void ClearResources()
|
|
{
|
|
_pass?.Dispose();
|
|
_pass = null;
|
|
_rtContext?.Dispose();
|
|
_rtContext = null;
|
|
}
|
|
|
|
// Parameters extracted from Volume override each frame
|
|
private struct VolumeParameterSet
|
|
{
|
|
public SurfaceCacheEstimationParameterSet EstimationParams;
|
|
public SurfaceCachePatchFilteringParameterSet PatchFilteringParams;
|
|
public SurfaceCacheScreenFilteringParameterSet ScreenFilteringParams;
|
|
public bool CascadeMovement;
|
|
public float VolumeSize;
|
|
public uint VolumeResolution;
|
|
public uint VolumeCascadeCount;
|
|
public uint DefragCount;
|
|
public uint RenderingLayerMask;
|
|
}
|
|
|
|
bool ResourcesCreated()
|
|
{
|
|
return _pass != null;
|
|
}
|
|
|
|
public override void Create()
|
|
{
|
|
ClearResources();
|
|
|
|
if (!isActive)
|
|
return;
|
|
|
|
#if UNITY_EDITOR
|
|
if (CheckStaticBatchingStatus())
|
|
return;
|
|
#endif
|
|
|
|
var rtBackend = SystemInfo.supportsRayTracing
|
|
? RayTracingBackend.Hardware
|
|
: RayTracingBackend.Compute;
|
|
|
|
{
|
|
var resources = new RayTracingResources();
|
|
#if UNITY_EDITOR
|
|
resources.Load();
|
|
#else
|
|
resources.LoadFromRenderPipelineResources();
|
|
#endif
|
|
_rtContext = new RayTracingContext(rtBackend, resources);
|
|
}
|
|
|
|
var universalRenderPipelineResources = GraphicsSettings.GetRenderPipelineSettings<SurfaceCacheRenderPipelineResourceSet>();
|
|
Debug.Assert(universalRenderPipelineResources != null);
|
|
|
|
var worldResources = new WorldResourceSet();
|
|
var worldLoadResult = worldResources.LoadFromRenderPipelineResources();
|
|
Debug.Assert(worldLoadResult);
|
|
|
|
var coreRpResources = GraphicsSettings.GetRenderPipelineSettings<Rendering.SurfaceCacheRenderPipelineResourceSet>();
|
|
Debug.Assert(coreRpResources != null);
|
|
|
|
var coreResources = new Rendering.SurfaceCacheResourceSet((uint)SystemInfo.computeSubGroupSize);
|
|
|
|
Object punctualLightSamplingUnifiedObj;
|
|
Object estimationUnifiedObj;
|
|
if (_rtContext.BackendType == RayTracingBackend.Compute)
|
|
{
|
|
punctualLightSamplingUnifiedObj = coreRpResources.punctualLightSamplingComputeShader;
|
|
estimationUnifiedObj = coreRpResources.estimationComputeShader;
|
|
}
|
|
else
|
|
{
|
|
punctualLightSamplingUnifiedObj = coreRpResources.punctualLightSamplingRayTracingShader;
|
|
estimationUnifiedObj = coreRpResources.estimationRayTracingShader;
|
|
}
|
|
IRayTracingShader punctualLightSamplingShader = _rtContext.CreateRayTracingShader(punctualLightSamplingUnifiedObj);
|
|
IRayTracingShader estimationShader = _rtContext.CreateRayTracingShader(estimationUnifiedObj);
|
|
|
|
coreResources.Load(
|
|
coreRpResources.scrollingShader,
|
|
coreRpResources.evictionShader,
|
|
coreRpResources.patchAllocationShader,
|
|
coreRpResources.spatialFilteringShader,
|
|
coreRpResources.temporalFilteringShader,
|
|
coreRpResources.defragShader,
|
|
punctualLightSamplingShader,
|
|
estimationShader);
|
|
|
|
// Use defaults for initial volume configuration; runtime values come from the Volume override per-frame
|
|
var volParams = new SurfaceCacheVolumeParameterSet
|
|
{
|
|
Resolution = DEFAULT_VOLUME_RESOLUTION,
|
|
Size = DEFAULT_VOLUME_SIZE,
|
|
CascadeCount = DEFAULT_VOLUME_CASCADE_COUNT
|
|
};
|
|
|
|
_pass = new SurfaceCachePass(
|
|
_rtContext,
|
|
coreResources,
|
|
worldResources,
|
|
universalRenderPipelineResources.allocationShader,
|
|
universalRenderPipelineResources.screenResolveLookupShader,
|
|
universalRenderPipelineResources.screenResolveUpsamplingShader,
|
|
universalRenderPipelineResources.debugShader,
|
|
universalRenderPipelineResources.flatNormalResolutionShader,
|
|
universalRenderPipelineResources.fallbackMaterial,
|
|
_parameterSet.DebugEnabled,
|
|
_parameterSet.DebugViewMode,
|
|
_parameterSet.DebugShowSamplePosition,
|
|
volParams);
|
|
|
|
_pass.renderPassEvent = RenderPassEvent.AfterRenderingPrePasses + 1;
|
|
}
|
|
|
|
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (CheckStaticBatchingStatus())
|
|
return;
|
|
#endif
|
|
|
|
var cameraType = renderingData.cameraData.cameraType;
|
|
if (cameraType != CameraType.Game && cameraType != CameraType.SceneView)
|
|
return;
|
|
|
|
var surfaceCacheOverride = VolumeManager.instance.stack.GetComponent<SurfaceCacheGIVolumeOverride>();
|
|
bool enabled = surfaceCacheOverride == null || surfaceCacheOverride.enabled.value;
|
|
|
|
if (!enabled)
|
|
{
|
|
if (ResourcesCreated())
|
|
ClearResources();
|
|
}
|
|
else
|
|
{
|
|
// Resources may be absent here after being released while disabled, or after static
|
|
// batching was disabled following feature creation.
|
|
if (!ResourcesCreated())
|
|
Create();
|
|
|
|
// Create() leaves _pass null when the feature is inactive.
|
|
if (!ResourcesCreated())
|
|
return;
|
|
|
|
ScriptableRenderPassInput inputs = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal;
|
|
if (UseMotionVectorPatchSeeding(renderingData.cameraData.cameraType))
|
|
{
|
|
inputs |= ScriptableRenderPassInput.Motion;
|
|
}
|
|
_pass.ConfigureInput(inputs);
|
|
renderer.EnqueuePass(_pass);
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
ClearResources();
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
bool _staticBatchingEnabled;
|
|
bool CheckStaticBatchingStatus()
|
|
{
|
|
bool previousStatus = _staticBatchingEnabled;
|
|
_staticBatchingEnabled = UnityEditor.PlayerSettings.GetStaticBatchingForPlatform(UnityEditor.EditorUserBuildSettings.activeBuildTarget);
|
|
|
|
if (_staticBatchingEnabled && _staticBatchingEnabled != previousStatus)
|
|
Debug.LogError(k_StaticBatchingErrorMesssage);
|
|
|
|
return _staticBatchingEnabled;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#endif
|