diff --git a/UnifiedUniversalBlur/Editor.meta b/Editor.meta similarity index 100% rename from UnifiedUniversalBlur/Editor.meta rename to Editor.meta diff --git a/Editor/Unified.UniversalBlur.Editor.asmdef b/Editor/Unified.UniversalBlur.Editor.asmdef new file mode 100644 index 0000000..8471b3a --- /dev/null +++ b/Editor/Unified.UniversalBlur.Editor.asmdef @@ -0,0 +1,18 @@ +{ + "name": "Unified.UniversalBlur.Editor", + "rootNamespace": "", + "references": [ + "GUID:179652d7da581408b8baeed6637275e9", + "GUID:3eae0364be2026648bf74846acb8a731", + "GUID:15fc0a57446b3144c949da3e2b9737a9" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/UnifiedUniversalBlur/Materials/KawaseBlurMat.mat.meta b/Editor/Unified.UniversalBlur.Editor.asmdef.meta similarity index 52% rename from UnifiedUniversalBlur/Materials/KawaseBlurMat.mat.meta rename to Editor/Unified.UniversalBlur.Editor.asmdef.meta index 67df8ed..9e7ba91 100644 --- a/UnifiedUniversalBlur/Materials/KawaseBlurMat.mat.meta +++ b/Editor/Unified.UniversalBlur.Editor.asmdef.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 9850a4d8fa91d463f97c9078274547d0 -NativeFormatImporter: +guid: 96a53531165ae4f4b92718bcb6991fe4 +AssemblyDefinitionImporter: externalObjects: {} - mainObjectFileID: 2100000 userData: assetBundleName: assetBundleVariant: diff --git a/UnifiedUniversalBlur/Editor/UniversalBlurFeatureEditor.cs b/Editor/UniversalBlurFeatureEditor.cs similarity index 84% rename from UnifiedUniversalBlur/Editor/UniversalBlurFeatureEditor.cs rename to Editor/UniversalBlurFeatureEditor.cs index 69ce51b..7749a50 100644 --- a/UnifiedUniversalBlur/Editor/UniversalBlurFeatureEditor.cs +++ b/Editor/UniversalBlurFeatureEditor.cs @@ -1,10 +1,11 @@ //Credits to: https://github.com/Unity-Technologies/Graphics using System.Collections.Generic; +using Unified.UniversalBlur.Runtime; using UnityEditor; using UnityEditor.Rendering; -namespace Unified.Universal.Blur.Editor +namespace Unified.UniversalBlur.Editor { /// /// Custom editor for FullScreenPassRendererFeature class responsible for drawing unavailable by default properties @@ -47,7 +48,7 @@ public override void OnInspectorGUI() DrawAdditionalProperties(); } - m_AffectedFeature.passIndex = m_PassIndexToUse; + m_AffectedFeature.PassIndex = m_PassIndexToUse; EditorUtility.SetDirty(target); } @@ -55,12 +56,12 @@ public override void OnInspectorGUI() private void DrawAdditionalProperties() { List selectablePasses; - bool isMaterialValid = m_AffectedFeature.passMaterial != null; + bool isMaterialValid = m_AffectedFeature.PassMaterial != null; selectablePasses = isMaterialValid ? GetPassIndexStringEntries(m_AffectedFeature) : new List() { "No material" }; // If material is invalid 0'th index is selected automatically, so it stays on "No material" entry // It is invalid index, but FullScreenPassRendererFeature wont execute until material is valid - var choiceIndex = EditorGUILayout.Popup("Pass Index", m_AffectedFeature.passIndex, selectablePasses.ToArray()); + var choiceIndex = EditorGUILayout.Popup("Pass Index", m_AffectedFeature.PassIndex, selectablePasses.ToArray()); m_PassIndexToUse = choiceIndex; @@ -69,10 +70,10 @@ private void DrawAdditionalProperties() private List GetPassIndexStringEntries(UniversalBlurFeature component) { List passIndexEntries = new List(); - for (int i = 0; i < component.passMaterial.passCount; ++i) + for (int i = 0; i < component.PassMaterial.passCount; ++i) { // "Name of a pass (index)" - "PassAlpha (1)" - string entry = $"{component.passMaterial.GetPassName(i)} ({i})"; + string entry = $"{component.PassMaterial.GetPassName(i)} ({i})"; passIndexEntries.Add(entry); } diff --git a/UnifiedUniversalBlur/Editor/UniversalBlurFeatureEditor.cs.meta b/Editor/UniversalBlurFeatureEditor.cs.meta similarity index 100% rename from UnifiedUniversalBlur/Editor/UniversalBlurFeatureEditor.cs.meta rename to Editor/UniversalBlurFeatureEditor.cs.meta diff --git a/UnifiedUniversalBlur/Materials.meta b/Materials.meta similarity index 100% rename from UnifiedUniversalBlur/Materials.meta rename to Materials.meta diff --git a/UnifiedUniversalBlur/Materials/UniversalBlurForUI.mat b/Materials/UniversalBlurForUI.mat similarity index 100% rename from UnifiedUniversalBlur/Materials/UniversalBlurForUI.mat rename to Materials/UniversalBlurForUI.mat diff --git a/UnifiedUniversalBlur/Materials/UniversalBlurForUI.mat.meta b/Materials/UniversalBlurForUI.mat.meta similarity index 100% rename from UnifiedUniversalBlur/Materials/UniversalBlurForUI.mat.meta rename to Materials/UniversalBlurForUI.mat.meta diff --git a/UnifiedUniversalBlur/Scripts.meta b/Runtime.meta similarity index 77% rename from UnifiedUniversalBlur/Scripts.meta rename to Runtime.meta index 9a6b6ea..64b4063 100644 --- a/UnifiedUniversalBlur/Scripts.meta +++ b/Runtime.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e30f3b43cb2f647e894a66a1d60fee76 +guid: f7cb317776574417e95b66d7a53c045e folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/BlurPassData.cs b/Runtime/BlurPassData.cs new file mode 100644 index 0000000..ef9da63 --- /dev/null +++ b/Runtime/BlurPassData.cs @@ -0,0 +1,35 @@ +using System; +using UnityEngine; + +namespace Unified.UniversalBlur.Runtime +{ + internal struct BlurPassData : IDisposable + { + internal Material EffectMaterial; + internal int PassIndex; + + public float Downsample; + public float Intensity; + public float Scale; + public int Iterations; + + public RenderTextureDescriptor Descriptor; + + public + // #if UNITY_2022_1_OR_NEWER + // RTHandle + // #else + RenderTexture + // #endif + RT1, RT2; + + public void Dispose() + { + if (RT1 != null) + RT1.Release(); + + if (RT2 != null) + RT2.Release(); + } + } +} \ No newline at end of file diff --git a/Runtime/BlurPassData.cs.meta b/Runtime/BlurPassData.cs.meta new file mode 100644 index 0000000..a5e1e56 --- /dev/null +++ b/Runtime/BlurPassData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ad80cc02763446ef89d7bb553408bc47 +timeCreated: 1717257817 \ No newline at end of file diff --git a/Runtime/Helpers.cs b/Runtime/Helpers.cs new file mode 100644 index 0000000..822b5f7 --- /dev/null +++ b/Runtime/Helpers.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; + +namespace Unified.UniversalBlur.Runtime +{ + public static class Helpers + { + // Derived from RenderingUtils.RTHandleNeedsReAlloc + public static bool HasDescriptorChanged(RenderTextureDescriptor descriptorA, RenderTextureDescriptor descriptorB, bool scaled) + { + if (descriptorA.useDynamicScale != scaled) + return true; + if (!scaled && (descriptorA.width != descriptorB.width || descriptorA.height != descriptorB.height)) + return true; + return + descriptorA.depthBufferBits != descriptorB.depthBufferBits || + (descriptorA.depthBufferBits == (int)DepthBits.None && + descriptorA.graphicsFormat != (GraphicsFormat)descriptorB.colorFormat) || + descriptorA.dimension != descriptorB.dimension || + descriptorA.enableRandomWrite != descriptorB.enableRandomWrite || + descriptorA.useMipMap != descriptorB.useMipMap || + descriptorA.autoGenerateMips != descriptorB.autoGenerateMips || + descriptorA.msaaSamples != descriptorB.msaaSamples || + descriptorA.bindMS != descriptorB.bindMS || + descriptorA.useDynamicScale != descriptorB.useDynamicScale || + descriptorA.memoryless != descriptorB.memoryless; + } + } +} \ No newline at end of file diff --git a/Runtime/Helpers.cs.meta b/Runtime/Helpers.cs.meta new file mode 100644 index 0000000..06ced2b --- /dev/null +++ b/Runtime/Helpers.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3b6a9ed246ef4df088d2a3ca74792795 +timeCreated: 1717253973 \ No newline at end of file diff --git a/Runtime/ScaleBlurWith.cs b/Runtime/ScaleBlurWith.cs new file mode 100644 index 0000000..292939b --- /dev/null +++ b/Runtime/ScaleBlurWith.cs @@ -0,0 +1,9 @@ +namespace Unified.UniversalBlur.Runtime +{ + public enum ScaleBlurWith + { + Disabled, + ScreenHeight, + ScreenWidth, + } +} \ No newline at end of file diff --git a/Runtime/ScaleBlurWith.cs.meta b/Runtime/ScaleBlurWith.cs.meta new file mode 100644 index 0000000..e087e1c --- /dev/null +++ b/Runtime/ScaleBlurWith.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a2e639b8a1dd4056b87fb57894a2d5e1 +timeCreated: 1717259993 \ No newline at end of file diff --git a/UnifiedUniversalBlur/Scripts/Unified.Universal.Blur.asmdef b/Runtime/Unified.UniversalBlur.Runtime.asmdef similarity index 100% rename from UnifiedUniversalBlur/Scripts/Unified.Universal.Blur.asmdef rename to Runtime/Unified.UniversalBlur.Runtime.asmdef diff --git a/UnifiedUniversalBlur/Scripts/Unified.Universal.Blur.asmdef.meta b/Runtime/Unified.UniversalBlur.Runtime.asmdef.meta similarity index 100% rename from UnifiedUniversalBlur/Scripts/Unified.Universal.Blur.asmdef.meta rename to Runtime/Unified.UniversalBlur.Runtime.asmdef.meta diff --git a/Runtime/UniversalBlurFeature.cs b/Runtime/UniversalBlurFeature.cs new file mode 100644 index 0000000..39e077a --- /dev/null +++ b/Runtime/UniversalBlurFeature.cs @@ -0,0 +1,120 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace Unified.UniversalBlur.Runtime +{ + public class UniversalBlurFeature : ScriptableRendererFeature + { + private enum InjectionPoint + { + BeforeRenderingTransparents = RenderPassEvent.BeforeRenderingTransparents, + BeforeRenderingPostProcessing = RenderPassEvent.BeforeRenderingPostProcessing, + AfterRenderingPostProcessing = RenderPassEvent.AfterRenderingPostProcessing + } + + [field: SerializeField, HideInInspector] public int PassIndex { get; set; } = 0; + + [field: Header("Blur Settings")] + [field: SerializeField] private InjectionPoint injectionPoint = InjectionPoint.AfterRenderingPostProcessing; + + [field: Space] + [field: Range(0f, 1f)] [field: SerializeField] public float Intensity { get; set; } = 1.0f; + + [Range(1f, 10f)] [SerializeField] private float downsample = 2.0f; + [Range(1, 20)] [SerializeField] private int iterations = 6; + [Range(0f, 5f)] [SerializeField] private float scale = .5f; + [SerializeField] private ScaleBlurWith scaleBlurWith; + [SerializeField] private float scaleReferenceSize = 1080f; + + [SerializeField] + [HideInInspector] + [Reload("Shaders/KawaseBlur.shader")] + private Shader shader; + + private readonly ScriptableRenderPassInput _requirements = ScriptableRenderPassInput.Color; + + public Material PassMaterial => _material; + + // Hidden by scope because of incorrect behaviour in the editor + private bool disableInSceneView = true; + + private Material _material; + private UniversalBlurPass _fullScreenPass; + private bool _injectedBeforeTransparents; + + /// + public override void Create() + { + _fullScreenPass = new UniversalBlurPass(); + _fullScreenPass.renderPassEvent = (RenderPassEvent)injectionPoint; + + ScriptableRenderPassInput modifiedRequirements = _requirements; + + var requiresColor = (_requirements & ScriptableRenderPassInput.Color) != 0; + _injectedBeforeTransparents = injectionPoint <= InjectionPoint.BeforeRenderingTransparents; + + if (requiresColor && !_injectedBeforeTransparents) + { + modifiedRequirements ^= ScriptableRenderPassInput.Color; + } + + _fullScreenPass.ConfigureInput(modifiedRequirements); + } + + /// + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + if (!TrySetShadersAndMaterials()) + { + Debug.LogErrorFormat("{0}.AddRenderPasses(): Missing material. {1} render pass will not be added.", GetType().Name, name); + return; + } + + var passData = GetBlurPassData(); + + _fullScreenPass.Setup(passData, renderingData); + + renderer.EnqueuePass(_fullScreenPass); + } + + /// + protected override void Dispose(bool disposing) + { + _fullScreenPass?.Dispose(); + CoreUtils.Destroy(_material); + } + + private bool TrySetShadersAndMaterials() + { + if (shader == null) + { + shader = Shader.Find("Unified/KawaseBlur"); + } + + if (_material == null && shader != null) + _material = CoreUtils.CreateEngineMaterial(shader); + return _material != null; + } + + private float CalculateScale() => scaleBlurWith switch + { + ScaleBlurWith.ScreenHeight => scale * (Screen.height / scaleReferenceSize), + ScaleBlurWith.ScreenWidth => scale * (Screen.width / scaleReferenceSize), + _ => scale + }; + + private BlurPassData GetBlurPassData() + { + return new BlurPassData() + { + EffectMaterial = _material, + Downsample = downsample, + Intensity = Intensity, + PassIndex = PassIndex, + Scale = CalculateScale(), + Iterations = iterations, + }; + } + } +} \ No newline at end of file diff --git a/UnifiedUniversalBlur/Scripts/UniversalBlurFeature.cs.meta b/Runtime/UniversalBlurFeature.cs.meta similarity index 100% rename from UnifiedUniversalBlur/Scripts/UniversalBlurFeature.cs.meta rename to Runtime/UniversalBlurFeature.cs.meta diff --git a/Runtime/UniversalBlurPass.cs b/Runtime/UniversalBlurPass.cs new file mode 100644 index 0000000..080de66 --- /dev/null +++ b/Runtime/UniversalBlurPass.cs @@ -0,0 +1,137 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace Unified.UniversalBlur.Runtime +{ + internal class UniversalBlurPass : ScriptableRenderPass + { + private const string k_PassName = "Unified Universal Blur"; + + private static readonly int m_KawaseOffsetID = Shader.PropertyToID("_KawaseOffset"); + private static readonly int m_globalFullScreenBlurTexture = Shader.PropertyToID("_GlobalFullScreenBlurTexture"); + + private ProfilingSampler m_ProfilingSampler = new(k_PassName); + + private BlurPassData _blurPassData; + + public void Setup(BlurPassData blurPassData, in RenderingData renderingData) + { + _blurPassData = blurPassData; + + _blurPassData.Descriptor = renderingData.cameraData.cameraTargetDescriptor; + _blurPassData.Descriptor.depthBufferBits = (int)DepthBits.None; + + _blurPassData.Descriptor.width = + Mathf.RoundToInt(_blurPassData.Descriptor.width / _blurPassData.Downsample); + _blurPassData.Descriptor.height = + Mathf.RoundToInt(_blurPassData.Descriptor.height / _blurPassData.Downsample); + + + if ((_blurPassData.RT1 == null || _blurPassData.RT2 == null) + || Helpers.HasDescriptorChanged(_blurPassData.RT1.descriptor, _blurPassData.Descriptor, false)) + { + _blurPassData.RT1 = new RenderTexture(_blurPassData.Descriptor); + _blurPassData.RT2 = new RenderTexture(_blurPassData.Descriptor); + } + } + + public void Dispose() + { + if (_blurPassData.RT1 != null) + _blurPassData.RT1.Release(); + + if (_blurPassData.RT2 != null) + _blurPassData.RT2.Release(); + } + + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + ExecutePass(_blurPassData, ref renderingData, ref context); + } + + private void ExecutePass(BlurPassData blurPassData, ref RenderingData renderingData, + ref ScriptableRenderContext context) + { + var passMaterial = blurPassData.EffectMaterial; + var rt1 = blurPassData.RT1; + var rt2 = blurPassData.RT2; + var scale = blurPassData.Scale; + + // should not happen as we check it in feature + if (passMaterial == null) + return; + + if (renderingData.cameraData.isPreviewCamera) + return; + + if (renderingData.cameraData.isSceneViewCamera) + { +#if UNITY_EDITOR + // For better preview experience in editor, we just use a gray texture + Shader.SetGlobalTexture(m_globalFullScreenBlurTexture, Texture2D.linearGrayTexture); +#endif + return; + } + + CommandBuffer cmd = CommandBufferPool.Get(k_PassName); + + var cameraData = renderingData.cameraData; + + using (new ProfilingScope(cmd, m_ProfilingSampler)) + { + ProcessEffect(ref context); + } + + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + + // End of function + + void ProcessEffect(ref ScriptableRenderContext context) + { + var source = +#if UNITY_2022_1_OR_NEWER + cameraData.renderer.cameraColorTargetHandle; +#else + cameraData.renderer.cameraColorTarget; +#endif + + // Setup + cmd.Blit(source, rt1); + + SetBlurOffset(1.5f); + Blit1To2(); + + if (blurPassData.Intensity > 0f) + { + for (int i = 1; i <= blurPassData.Iterations; i++) + { + var offset = (0.5f + i * scale) * (blurPassData.Intensity / blurPassData.Downsample); + + SetBlurOffset(offset); + Blit1To2(); + SwapRTs(); + } + } + + cmd.SetGlobalTexture(m_globalFullScreenBlurTexture, rt2); + } + + void Blit1To2() + { + cmd.Blit(rt1, rt2, passMaterial, blurPassData.PassIndex); + } + + void SetBlurOffset(float offset) + { + cmd.SetGlobalFloat(m_KawaseOffsetID, offset); + } + + void SwapRTs() + { + (rt1, rt2) = (rt2, rt1); + } + } + } +} \ No newline at end of file diff --git a/UnifiedUniversalBlur/Scripts/UniversalBlurPass.cs.meta b/Runtime/UniversalBlurPass.cs.meta similarity index 100% rename from UnifiedUniversalBlur/Scripts/UniversalBlurPass.cs.meta rename to Runtime/UniversalBlurPass.cs.meta diff --git a/UnifiedUniversalBlur/Shaders.meta b/Shaders.meta similarity index 100% rename from UnifiedUniversalBlur/Shaders.meta rename to Shaders.meta diff --git a/UnifiedUniversalBlur/Shaders/KawaseBlur.shader b/Shaders/KawaseBlur.shader similarity index 100% rename from UnifiedUniversalBlur/Shaders/KawaseBlur.shader rename to Shaders/KawaseBlur.shader diff --git a/UnifiedUniversalBlur/Shaders/KawaseBlur.shader.meta b/Shaders/KawaseBlur.shader.meta similarity index 100% rename from UnifiedUniversalBlur/Shaders/KawaseBlur.shader.meta rename to Shaders/KawaseBlur.shader.meta diff --git a/UnifiedUniversalBlur/Shaders/UniversalBlurForUI.shader b/Shaders/UniversalBlurForUI.shader similarity index 100% rename from UnifiedUniversalBlur/Shaders/UniversalBlurForUI.shader rename to Shaders/UniversalBlurForUI.shader diff --git a/UnifiedUniversalBlur/Shaders/UniversalBlurForUI.shader.meta b/Shaders/UniversalBlurForUI.shader.meta similarity index 100% rename from UnifiedUniversalBlur/Shaders/UniversalBlurForUI.shader.meta rename to Shaders/UniversalBlurForUI.shader.meta diff --git a/UnifiedUniversalBlur.meta b/UnifiedUniversalBlur.meta deleted file mode 100644 index f01c86e..0000000 --- a/UnifiedUniversalBlur.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f736b04824ef491881b6e3c1e254017f -timeCreated: 1675544969 \ No newline at end of file diff --git a/UnifiedUniversalBlur/Materials/KawaseBlurMat.mat b/UnifiedUniversalBlur/Materials/KawaseBlurMat.mat deleted file mode 100644 index 78dbe7c..0000000 --- a/UnifiedUniversalBlur/Materials/KawaseBlurMat.mat +++ /dev/null @@ -1,43 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: KawaseBlurMat - m_Shader: {fileID: 4800000, guid: bb11bdc2e8aaf4c80b5315f3778d7ad4, type: 3} - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _BlurScale: -8.53 - m_Colors: [] - m_BuildTextureStacks: [] diff --git a/UnifiedUniversalBlur/Scripts/UniversalBlurFeature.cs b/UnifiedUniversalBlur/Scripts/UniversalBlurFeature.cs deleted file mode 100644 index 06de210..0000000 --- a/UnifiedUniversalBlur/Scripts/UniversalBlurFeature.cs +++ /dev/null @@ -1,95 +0,0 @@ -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace Unified.Universal.Blur -{ - public class UniversalBlurFeature : ScriptableRendererFeature - { - public enum InjectionPoint - { - BeforeRenderingTransparents = RenderPassEvent.BeforeRenderingTransparents, - BeforeRenderingPostProcessing = RenderPassEvent.BeforeRenderingPostProcessing, - AfterRenderingPostProcessing = RenderPassEvent.AfterRenderingPostProcessing - } - - public Material passMaterial; - [HideInInspector] public int passIndex = 0; - - [Header("Blur Settings")] - public InjectionPoint injectionPoint = InjectionPoint.AfterRenderingPostProcessing; - - [Space] - [Range(0f, 1f)] public float intensity = 1.0f; - [Range(1f, 10f)] public float downsample = 2.0f; - [Range(0f, 5f)] public float scale = .5f; - [Range(1, 20)] public int iterations = 6; - - - // Hidden by scope because of no need - private ScriptableRenderPassInput _requirements = ScriptableRenderPassInput.Color; - - // Hidden by scope because of incorrect behaviour in the editor - private bool disableInSceneView = true; - - private UniversalBlurPass _fullScreenPass; - private bool _requiresColor; - private bool _injectedBeforeTransparents; - - private UniversalBlurPass.PassData _PassData; - - - /// - public override void Create() - { - _fullScreenPass = new UniversalBlurPass(); - _fullScreenPass.renderPassEvent = (RenderPassEvent)injectionPoint; - - ScriptableRenderPassInput modifiedRequirements = _requirements; - - _requiresColor = (_requirements & ScriptableRenderPassInput.Color) != 0; - _injectedBeforeTransparents = injectionPoint <= InjectionPoint.BeforeRenderingTransparents; - - if (_requiresColor && !_injectedBeforeTransparents) - { - modifiedRequirements ^= ScriptableRenderPassInput.Color; - } - - _fullScreenPass.ConfigureInput(modifiedRequirements); - - _PassData = new (); - } - - /// - public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) - { - if (passMaterial == null) - { - Debug.LogWarningFormat("Missing Post Processing effect Material. {0} Fullscreen pass will not execute. Check for missing reference in the assigned renderer.", GetType().Name); - return; - } - - SetupPassData(_PassData); - _fullScreenPass.Setup(_PassData, downsample, renderingData); - - renderer.EnqueuePass(_fullScreenPass); - } - - /// - protected override void Dispose(bool disposing) - { - _fullScreenPass.Dispose(); - } - - void SetupPassData(UniversalBlurPass.PassData passData) - { - passData.effectMaterial = passMaterial; - passData.intensity = intensity; - passData.passIndex = passIndex; - passData.requiresColor = _requiresColor; - passData.scale = scale; - passData.iterations = iterations; - } - } - -} \ No newline at end of file diff --git a/UnifiedUniversalBlur/Scripts/UniversalBlurPass.cs b/UnifiedUniversalBlur/Scripts/UniversalBlurPass.cs deleted file mode 100644 index 1203dbf..0000000 --- a/UnifiedUniversalBlur/Scripts/UniversalBlurPass.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace Unified.Universal.Blur -{ - class UniversalBlurPass : ScriptableRenderPass - { - - private const string k_PassName = "Unified Universal Blur"; - - private static readonly int m_KawaseOffsetID = Shader.PropertyToID("_KawaseOffset"); - private static readonly int m_globalFullScreenBlurTexture = Shader.PropertyToID("_GlobalFullScreenBlurTexture"); - - private ProfilingSampler m_ProfilingSampler = new(k_PassName); - - private PassData m_PassData; - - public void Setup(PassData passData, float downsample, in RenderingData renderingData) - { - m_PassData = passData; - - m_PassData.rtDesc = renderingData.cameraData.cameraTargetDescriptor; - m_PassData.rtDesc.depthBufferBits = (int)DepthBits.None; - - m_PassData.rtDesc.width = Mathf.RoundToInt(m_PassData.rtDesc.width / downsample); - m_PassData.rtDesc.height = Mathf.RoundToInt(m_PassData.rtDesc.height / downsample); - - #if UNITY_2022_1_OR_NEWER - RenderingUtils.ReAllocateIfNeeded(ref m_PassData.tmpRT1, m_PassData.rtDesc, name: "_PassRT1", wrapMode: TextureWrapMode.Clamp, filterMode: FilterMode.Bilinear); - RenderingUtils.ReAllocateIfNeeded(ref m_PassData.tmpRT2, m_PassData.rtDesc, name: "_PassRT2", wrapMode: TextureWrapMode.Clamp, filterMode: FilterMode.Bilinear); - #else - m_PassData.tmpRT1 ??= new RenderTexture(m_PassData.rtDesc); - m_PassData.tmpRT2 ??= new RenderTexture(m_PassData.rtDesc); - #endif - } - - public void Dispose() - { - if (m_PassData == null) - return; - - if (m_PassData.tmpRT1 != null) - m_PassData.tmpRT1.Release(); - - if (m_PassData.tmpRT2 != null) - m_PassData.tmpRT2.Release(); - } - - - // public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) - // { } - - public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) - { - ExecutePass(m_PassData, ref renderingData, ref context); - } - - private void ExecutePass(PassData passData, ref RenderingData renderingData, ref ScriptableRenderContext context) - { - var passMaterial = passData.effectMaterial; - var tmpRT1 = passData.tmpRT1; - var tmpRT2 = passData.tmpRT2; - var scale = passData.scale; - - // should not happen as we check it in feature - if (passMaterial == null) - return; - - if (renderingData.cameraData.isPreviewCamera) - return; - - if (renderingData.cameraData.isSceneViewCamera) - { - #if UNITY_EDITOR - // For better preview experience in editor, we just use a gray texture - Shader.SetGlobalTexture(m_globalFullScreenBlurTexture, Texture2D.linearGrayTexture); - #endif - return; - } - - CommandBuffer cmd = CommandBufferPool.Get(k_PassName); - - var cameraData = renderingData.cameraData; - - using (new ProfilingScope(cmd, m_ProfilingSampler)) { - ProcessEffect(ref context); - } - - context.ExecuteCommandBuffer(cmd); - CommandBufferPool.Release(cmd); - - // End of function - - void ProcessEffect(ref ScriptableRenderContext context) - { - if (passData.requiresColor) - { - var source = - #if UNITY_2022_1_OR_NEWER - cameraData.renderer.cameraColorTargetHandle; - #else - cameraData.renderer.cameraColorTarget; - #endif - - // Setup - cmd.Blit(source, tmpRT1); - - SetBlurOffset(1.5f); - Blit1To2(); - - if (passData.intensity > 0f) - { - for (int i = 1; i <= passData.iterations; i++) - { - var offset = (0.5f + i * scale) * passData.intensity; - - SetBlurOffset(offset); - Blit1To2(); - SwapRTs(); - } - } - - cmd.SetGlobalTexture(m_globalFullScreenBlurTexture, tmpRT2); - } - } - - void Blit1To2() - { - cmd.Blit(tmpRT1, tmpRT2, passMaterial, passData.passIndex); - } - - void SetBlurOffset(float offset) - { - cmd.SetGlobalFloat(m_KawaseOffsetID, offset); - } - - void SwapRTs() - { - (tmpRT1, tmpRT2) = (tmpRT2, tmpRT1); - } - } - - internal class PassData - { - internal Material effectMaterial; - internal int passIndex; - internal bool requiresColor; - - public float intensity; - public float scale; - public int iterations; - - public RenderTextureDescriptor rtDesc; - - public - #if UNITY_2022_1_OR_NEWER - RTHandle - #else - RenderTexture - #endif - tmpRT1, tmpRT2; - } - } -} diff --git a/package.json b/package.json index 3ce8d42..d7ebc23 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "com.unify.unified-universal-blur", "displayName": "Unified Universal Blur", "description": "Unified Universal Blur is a package that allows you to use the blur effect in URP.", - "version": "0.2.4", + "version": "0.3.0", "unity": "2020.3", "license": "MIT", "repository": {