├── Blur ├── BokehBlur.meta ├── BokehBlur │ ├── BokehBlur.cs │ ├── BokehBlur.cs.meta │ ├── BokehBlur.shader │ ├── BokehBlur.shader.meta │ ├── BokehBlurRenderFeature.cs │ └── BokehBlurRenderFeature.cs.meta ├── BoxBlur.meta ├── BoxBlur │ ├── BoxBlur.cs │ ├── BoxBlur.cs.meta │ ├── BoxBlur.shader │ ├── BoxBlur.shader.meta │ ├── BoxBlurRenderFeature.cs │ └── BoxBlurRenderFeature.cs.meta ├── DirectionalBlur.meta ├── DirectionalBlur │ ├── DirectionalBlur.cs │ ├── DirectionalBlur.cs.meta │ ├── DirectionalBlur.shader │ ├── DirectionalBlur.shader.meta │ ├── DirectionalBlurRenderFeature.cs │ └── DirectionalBlurRenderFeature.cs.meta ├── DualBoxBlur.meta ├── DualBoxBlur │ ├── DualBoxBlur.cs │ ├── DualBoxBlur.cs.meta │ ├── DualBoxBlur.shader │ ├── DualBoxBlur.shader.meta │ ├── DualBoxBlurRenderFeature.cs │ └── DualBoxBlurRenderFeature.cs.meta ├── DualGaussianBlur.meta ├── DualGaussianBlur │ ├── DualGaussianBlur.cs │ ├── DualGaussianBlur.cs.meta │ ├── DualGaussianBlur.shader │ ├── DualGaussianBlur.shader.meta │ ├── DualGaussianBlurRenderFeature.cs │ └── DualGaussianBlurRenderFeature.cs.meta ├── DualKawaseBlur.meta ├── DualKawaseBlur │ ├── DualKawaseBlur.cs │ ├── DualKawaseBlur.cs.meta │ ├── DualKawaseBlur.shader │ ├── DualKawaseBlur.shader.meta │ ├── DualKawaseBlurRenderFeature.cs │ └── DualKawaseBlurRenderFeature.cs.meta ├── DualTentBlur.meta ├── DualTentBlur │ ├── DualTentBlur.cs │ ├── DualTentBlur.cs.meta │ ├── DualTentBlur.shader │ ├── DualTentBlur.shader.meta │ ├── DualTentBlurRenderFeature.cs │ └── DualTentBlurRenderFeature.cs.meta ├── GaussianBlur.meta ├── GaussianBlur │ ├── GaussianBlur.cs │ ├── GaussianBlur.cs.meta │ ├── GaussianBlur.shader │ ├── GaussianBlur.shader.meta │ ├── GaussianBlurRenderFeature.cs │ └── GaussianBlurRenderFeature.cs.meta ├── GrainyBlur.meta ├── GrainyBlur │ ├── GrainyBlur.cs │ ├── GrainyBlur.cs.meta │ ├── GrainyBlur.shader │ ├── GrainyBlur.shader.meta │ ├── GrainyBlurRenderFeature.cs │ └── GrainyBlurRenderFeature.cs.meta ├── IrisBlur.meta ├── IrisBlur │ ├── IrisBlur.cs │ ├── IrisBlur.cs.meta │ ├── IrisBlur.shader │ ├── IrisBlur.shader.meta │ ├── IrisBlurRenderFeature.cs │ └── IrisBlurRenderFeature.cs.meta ├── KawaseBlur.meta ├── KawaseBlur │ ├── KawaseBlur.cs │ ├── KawaseBlur.cs.meta │ ├── KawaseBlur.shader │ ├── KawaseBlur.shader.meta │ ├── KawaseBlurRenderFeature.cs │ └── KawaseBlurRenderFeature.cs.meta ├── RadialBlur.meta ├── RadialBlur │ ├── RadialBlur.cs │ ├── RadialBlur.cs.meta │ ├── RadialBlur.shader │ ├── RadialBlur.shader.meta │ ├── RadialBlurRenderFeature.cs │ └── RadialBlurRenderFeature.cs.meta ├── TiltShiftBlur.meta └── TiltShiftBlur │ ├── TiltShiftBlur.cs │ ├── TiltShiftBlur.cs.meta │ ├── TiltShiftBlur.shader │ ├── TiltShiftBlur.shader.meta │ ├── TiltShiftBlurRenderFeature.cs │ └── TiltShiftBlurRenderFeature.cs.meta └── README.md /Blur/BokehBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1731a5a7d965954468a892675ed0de1b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using AmplifyShaderEditor; 5 | using UnityEngine; 6 | using UnityEngine.Rendering; 7 | using UnityEngine.Rendering.Universal; 8 | 9 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/BokehBlur")] 10 | public class BokehBlur : VolumeComponent, IPostProcessComponent 11 | { 12 | public BoolParameter EnableBokehBlur = new BoolParameter(false); 13 | 14 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter(1f,0,3); 15 | 16 | public ClampedIntParameter Iteration = new ClampedIntParameter(32,8,128); 17 | 18 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter(2,1,10); 19 | 20 | public bool IsActive() 21 | { 22 | return EnableBokehBlur.value; 23 | } 24 | 25 | public bool IsTileCompatible() 26 | { 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 318679ac061a7f24cbbc8c623070d3af 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/BokehBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct v2f 18 | { 19 | float2 uv: TEXCOORD0; 20 | float4 vertex: SV_POSITION; 21 | }; 22 | 23 | half4 _GoldenRot; 24 | half4 _Params; 25 | sampler2D _MainTex; 26 | #define _Iteration _Params.x 27 | #define _Radius _Params.y 28 | #define _PixelSize _Params.zw 29 | 30 | v2f Vert(appdata v) 31 | { 32 | v2f o; 33 | o.vertex = TransformObjectToHClip(v.vertex.xyz); 34 | o.uv = v.uv; 35 | return o; 36 | } 37 | 38 | half4 Frag(v2f i): SV_Target 39 | { 40 | half2x2 rot = half2x2(_GoldenRot); 41 | half4 accumulator = 0.0; 42 | half4 divisor = 0.0; 43 | 44 | half r = 1.0; 45 | half2 angle = half2(0.0, _Radius); 46 | 47 | for (int j = 0; j < _Iteration; j++) 48 | { 49 | r += 1.0 / r; 50 | angle = mul(rot, angle); 51 | half4 bokeh = tex2D(_MainTex, float2(i.uv + _PixelSize * (r - 1.0) * angle)); 52 | accumulator += bokeh * bokeh; 53 | divisor += bokeh; 54 | } 55 | return accumulator / divisor; 56 | } 57 | 58 | ENDHLSL 59 | 60 | SubShader 61 | { 62 | Cull Off ZWrite Off ZTest Always 63 | 64 | Pass 65 | { 66 | HLSLPROGRAM 67 | 68 | #pragma vertex Vert 69 | #pragma fragment Frag 70 | 71 | ENDHLSL 72 | 73 | } 74 | } 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 827cc5a917a909f469ad621f4b03b036 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class BokehBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | 10 | public class BokehBlurPass : ScriptableRenderPass 11 | { 12 | internal static readonly int GoldenRot = Shader.PropertyToID("_GoldenRot"); 13 | internal static readonly int Params = Shader.PropertyToID("_Params"); 14 | internal static readonly int TempTargetId = Shader.PropertyToID("_TempTargetBokehBlur"); 15 | 16 | private const string PROFILER_TAG = "BokehBlur"; 17 | private Vector4 mGoldenRot = new Vector4(); 18 | 19 | private BokehBlur _bokehBlur; 20 | private Material bokehBlurMat; 21 | RenderTargetIdentifier currentTarget; 22 | public BokehBlurPass(RenderPassEvent evt) 23 | { 24 | renderPassEvent = evt; 25 | Shader bokehBlurShader=Shader.Find("Hidden/CustomPostEffect/BokehBlur"); 26 | if (bokehBlurShader) 27 | { 28 | bokehBlurMat = CoreUtils.CreateEngineMaterial(bokehBlurShader); 29 | } 30 | float c = Mathf.Cos(2.39996323f); 31 | float s = Mathf.Sin(2.39996323f); 32 | mGoldenRot.Set(c, s, -s, c); 33 | } 34 | 35 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 36 | { 37 | if (bokehBlurMat == null) return; 38 | if (!renderingData.cameraData.postProcessEnabled) return; 39 | var stack = VolumeManager.instance.stack; 40 | _bokehBlur = stack.GetComponent(); 41 | if (_bokehBlur == null) return; 42 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 43 | Render(cmd, ref renderingData); 44 | context.ExecuteCommandBuffer(cmd); 45 | CommandBufferPool.Release(cmd); 46 | } 47 | 48 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 49 | { 50 | if (_bokehBlur.IsActive()) 51 | { 52 | var cameraData = renderingData.cameraData; 53 | var source = currentTarget; 54 | int destination = TempTargetId; 55 | 56 | int RTWidth = (int)(cameraData.camera.scaledPixelWidth / _bokehBlur.RTDownScaling.value); 57 | int RTHeight = (int)(cameraData.camera.scaledPixelHeight / _bokehBlur.RTDownScaling.value); 58 | cmd.GetTemporaryRT(destination, RTWidth, RTHeight, 0, FilterMode.Bilinear); 59 | bokehBlurMat.SetVector(GoldenRot, mGoldenRot); 60 | bokehBlurMat.SetVector(Params, new Vector4(_bokehBlur.Iteration.value, _bokehBlur.BlurRadius.value, 1f / cameraData.camera.scaledPixelWidth, 1f / cameraData.camera.scaledPixelHeight)); 61 | cmd.Blit(source,destination, bokehBlurMat, 0); 62 | cmd.Blit(destination,source); 63 | cmd.ReleaseTemporaryRT(destination); 64 | } 65 | } 66 | 67 | public void Setup(in RenderTargetIdentifier currentTarget) 68 | { 69 | this.currentTarget = currentTarget; 70 | } 71 | 72 | public override void FrameCleanup(CommandBuffer cmd) 73 | { 74 | base.FrameCleanup(cmd); 75 | } 76 | } 77 | 78 | private BokehBlurPass _bokehBlurPass; 79 | 80 | public override void Create() 81 | { 82 | _bokehBlurPass = new BokehBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 83 | } 84 | 85 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 86 | { 87 | _bokehBlurPass.Setup(renderer.cameraColorTarget); 88 | renderer.EnqueuePass(_bokehBlurPass); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Blur/BokehBlur/BokehBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 35993524f7d1b0640828cd823f9a17dc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/BoxBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e4150d3131e51c45b5821e0e5fbdcfe 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/BoxBlur")] 9 | public class BoxBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter(0, 0, 5); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,20); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,8); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8cc6cab98b27ee444a024734c307cb6a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/BoxBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct v2f 18 | { 19 | float2 uv: TEXCOORD0; 20 | float4 vertex: SV_POSITION; 21 | }; 22 | 23 | sampler2D _MainTex; 24 | half4 _BlurOffset; 25 | 26 | v2f Vert(appdata v) 27 | { 28 | v2f o; 29 | o.vertex = TransformObjectToHClip(v.vertex.xyz); 30 | o.uv = v.uv; 31 | return o; 32 | } 33 | 34 | half4 BoxFilter_4Tap(sampler2D _MainTex, float2 uv, float2 texelSize) 35 | { 36 | float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0); 37 | 38 | half4 s = 0; 39 | s = tex2D(_MainTex, uv + d.xy) * 0.25h; 40 | s += tex2D(_MainTex, uv + d.zy) * 0.25h; 41 | s += tex2D(_MainTex, uv + d.xw) * 0.25h; 42 | s += tex2D(_MainTex, uv + d.zw) * 0.25h; 43 | return s; 44 | } 45 | 46 | 47 | float4 FragBoxBlur(v2f i): SV_Target 48 | { 49 | return BoxFilter_4Tap(_MainTex, i.uv, _BlurOffset.xy).rgba; 50 | } 51 | 52 | float4 FragCombine(v2f i): SV_Target 53 | { 54 | return tex2D(_MainTex, i.uv); 55 | } 56 | 57 | ENDHLSL 58 | 59 | SubShader 60 | { 61 | Cull Off ZWrite Off ZTest Always 62 | 63 | Pass 64 | { 65 | HLSLPROGRAM 66 | 67 | #pragma vertex Vert 68 | #pragma fragment FragBoxBlur 69 | 70 | ENDHLSL 71 | 72 | } 73 | 74 | Pass 75 | { 76 | HLSLPROGRAM 77 | 78 | #pragma vertex Vert 79 | #pragma fragment FragCombine 80 | 81 | ENDHLSL 82 | 83 | } 84 | } 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3c52af0a601d4444bbf989e86653ae9 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class BoxBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | private BoxBlurPass _boxBlurPass; 10 | 11 | public class BoxBlurPass : ScriptableRenderPass 12 | { 13 | internal static readonly int BlurRadius = Shader.PropertyToID("_BlurOffset"); 14 | internal static readonly int BufferRT1 = Shader.PropertyToID("_BufferRT1"); 15 | internal static readonly int BufferRT2 = Shader.PropertyToID("_BufferRT2"); 16 | internal static readonly int TempTargetId = Shader.PropertyToID("_TempTargetBoxBlur"); 17 | 18 | private const string PROFILER_TAG = "BoxBlur"; 19 | 20 | private BoxBlur _boxBlur; 21 | private Material _boxBlurMat; 22 | RenderTargetIdentifier currentTarget; 23 | 24 | public BoxBlurPass(RenderPassEvent evt) 25 | { 26 | renderPassEvent = evt; 27 | Shader boxBlurShader = Shader.Find("Hidden/CustomPostEffect/BoxBlur"); 28 | if (boxBlurShader) 29 | { 30 | _boxBlurMat = CoreUtils.CreateEngineMaterial(boxBlurShader); 31 | } 32 | } 33 | 34 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 35 | { 36 | if (_boxBlurMat == null) return; 37 | if (!renderingData.cameraData.postProcessEnabled) return; 38 | var stack = VolumeManager.instance.stack; 39 | _boxBlur = stack.GetComponent(); 40 | if (_boxBlur == null) return; 41 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 42 | Render(cmd, ref renderingData); 43 | context.ExecuteCommandBuffer(cmd); 44 | CommandBufferPool.Release(cmd); 45 | } 46 | 47 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 48 | { 49 | Camera camera = renderingData.cameraData.camera; 50 | var source = currentTarget; 51 | int destination = TempTargetId; 52 | 53 | if (_boxBlur.IsActive()) 54 | { 55 | cmd.BeginSample(PROFILER_TAG); 56 | 57 | int RTWidth = (int) (camera.pixelWidth / _boxBlur.RTDownScaling.value); 58 | int RTHeight = (int) (camera.pixelHeight / _boxBlur.RTDownScaling.value); 59 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 60 | cmd.GetTemporaryRT(destination, RTWidth, RTHeight, 0, FilterMode.Bilinear); 61 | 62 | cmd.Blit(source, BufferRT1); 63 | 64 | for (int i = 0; i < _boxBlur.Iteration.value; i++) 65 | { 66 | if (_boxBlur.Iteration.value > 20) 67 | { 68 | return; 69 | } 70 | 71 | Vector4 BlurRadiusValue = new Vector4(_boxBlur.BlurRadius.value / camera.pixelWidth, 72 | _boxBlur.BlurRadius.value / camera.pixelHeight, 0, 0); 73 | 74 | _boxBlurMat.SetVector(BlurRadius, BlurRadiusValue); 75 | cmd.Blit(BufferRT1, destination, _boxBlurMat, 0); 76 | 77 | _boxBlurMat.SetVector(BlurRadius, BlurRadiusValue); 78 | cmd.Blit(destination, BufferRT1, _boxBlurMat, 0); 79 | } 80 | 81 | cmd.Blit(BufferRT1, destination, _boxBlurMat, 1); 82 | cmd.Blit(destination,source); 83 | 84 | cmd.ReleaseTemporaryRT(BufferRT1); 85 | cmd.ReleaseTemporaryRT(BufferRT2); 86 | cmd.EndSample(PROFILER_TAG); 87 | } 88 | } 89 | 90 | public void Setup(in RenderTargetIdentifier currentTarget) 91 | { 92 | this.currentTarget = currentTarget; 93 | } 94 | } 95 | 96 | 97 | public override void Create() 98 | { 99 | _boxBlurPass = new BoxBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 100 | } 101 | 102 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 103 | { 104 | _boxBlurPass.Setup(renderer.cameraColorTarget); 105 | renderer.EnqueuePass(_boxBlurPass); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Blur/BoxBlur/BoxBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64a0cd67e5db5fe4ca0d6ab6b787af5e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d30ba480237d9d440ba2fd6d28f735b6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/DirectionalBlur")] 9 | public class DirectionalBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,5); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (12,1,30); 14 | 15 | public ClampedFloatParameter Angle = new ClampedFloatParameter (0.5f,0,6); 16 | 17 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (1,1,10); 18 | 19 | public bool IsActive() 20 | { 21 | return BlurRadius.value > 0; 22 | } 23 | 24 | public bool IsTileCompatible() 25 | { 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 947ec1453b3baf047a0ab8b73f5bae81 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/DirectionalBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct v2f 18 | { 19 | float2 uv: TEXCOORD0; 20 | float4 vertex: SV_POSITION; 21 | }; 22 | 23 | sampler2D _MainTex; 24 | half3 _Params; 25 | 26 | #define _Iteration _Params.x 27 | #define _Direction _Params.yz 28 | 29 | v2f Vert(appdata v) 30 | { 31 | v2f o; 32 | o.vertex = TransformObjectToHClip(v.vertex.xyz); 33 | o.uv = v.uv; 34 | return o; 35 | } 36 | 37 | half4 DirectionalBlur(v2f i) 38 | { 39 | half4 color = half4(0.0, 0.0, 0.0, 0.0); 40 | 41 | for (int k = -_Iteration; k < _Iteration; k++) 42 | { 43 | color += tex2D(_MainTex, i.uv - _Direction * k); 44 | } 45 | half4 finalColor = color / (_Iteration * 2.0); 46 | 47 | return finalColor; 48 | } 49 | 50 | half4 Frag(v2f i): SV_Target 51 | { 52 | return DirectionalBlur(i); 53 | } 54 | 55 | ENDHLSL 56 | 57 | 58 | SubShader 59 | { 60 | Cull Off ZWrite Off ZTest Always 61 | 62 | Pass 63 | { 64 | HLSLPROGRAM 65 | 66 | #pragma vertex Vert 67 | #pragma fragment Frag 68 | 69 | ENDHLSL 70 | 71 | } 72 | } 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfcf6216628f2814da6917cc02c4b63c 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class DirectionalBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | private DirectionalBlurPass _directionalBlurPass; 10 | 11 | public class DirectionalBlurPass : ScriptableRenderPass 12 | { 13 | internal static readonly int Params = Shader.PropertyToID("_Params"); 14 | internal static readonly int BufferRT = Shader.PropertyToID("_BufferRT"); 15 | 16 | private const string PROFILER_TAG = "DirectionalBlur"; 17 | 18 | private DirectionalBlur _directionalBlur; 19 | private Material directionalBlurMat; 20 | 21 | RenderTargetIdentifier currentTarget; 22 | 23 | public DirectionalBlurPass(RenderPassEvent evt) 24 | { 25 | renderPassEvent = evt; 26 | Shader directionalBlurShader=Shader.Find("Hidden/CustomPostEffect/DirectionalBlur"); 27 | if (directionalBlurShader) 28 | { 29 | directionalBlurMat = CoreUtils.CreateEngineMaterial(directionalBlurShader); 30 | } 31 | } 32 | 33 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 34 | { 35 | if (directionalBlurMat == null) return; 36 | if (!renderingData.cameraData.postProcessEnabled) return; 37 | var stack = VolumeManager.instance.stack; 38 | _directionalBlur = stack.GetComponent(); 39 | if (_directionalBlur == null) return; 40 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 41 | Render(cmd, ref renderingData); 42 | context.ExecuteCommandBuffer(cmd); 43 | CommandBufferPool.Release(cmd); 44 | } 45 | 46 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 47 | { 48 | if (_directionalBlur.IsActive()) 49 | { 50 | var source = currentTarget; 51 | int RTWidth = (int)(renderingData.cameraData.camera.pixelWidth / _directionalBlur.RTDownScaling.value); 52 | int RTHeight = (int)(renderingData.cameraData.camera.pixelHeight / _directionalBlur.RTDownScaling.value); 53 | cmd.GetTemporaryRT(BufferRT, RTWidth, RTHeight, 0, FilterMode.Bilinear); 54 | cmd.Blit(source, BufferRT); 55 | 56 | float sinVal = (Mathf.Sin(_directionalBlur.Angle.value) * _directionalBlur.BlurRadius.value * 0.05f) / _directionalBlur.Iteration.value; 57 | float cosVal = (Mathf.Cos(_directionalBlur.Angle.value) * _directionalBlur.BlurRadius.value * 0.05f) / _directionalBlur.Iteration.value; 58 | directionalBlurMat.SetVector(Params, new Vector3(_directionalBlur.Iteration.value, sinVal, cosVal)); 59 | cmd.Blit(BufferRT, source, directionalBlurMat, 0); 60 | cmd.ReleaseTemporaryRT(BufferRT); 61 | } 62 | } 63 | 64 | public void Setup(in RenderTargetIdentifier currentTarget) 65 | { 66 | this.currentTarget = currentTarget; 67 | } 68 | 69 | public override void FrameCleanup(CommandBuffer cmd) 70 | { 71 | base.FrameCleanup(cmd); 72 | } 73 | } 74 | 75 | public override void Create() 76 | { 77 | _directionalBlurPass = new DirectionalBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 78 | } 79 | 80 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 81 | { 82 | _directionalBlurPass.Setup(renderer.cameraColorTarget); 83 | renderer.EnqueuePass(_directionalBlurPass); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Blur/DirectionalBlur/DirectionalBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d90c82fd5dfc8c14f8792f679b012cdc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23a6e10c00824b84d9665ceb0d2571da 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/DualBoxBlur")] 9 | public class DualBoxBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,15); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,8); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,10); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8555ada62d3c82e45907587ce6f746ec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/DualBoxBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct v2f 18 | { 19 | float2 uv: TEXCOORD0; 20 | float4 vertex: SV_POSITION; 21 | }; 22 | 23 | sampler2D _MainTex; 24 | half4 _BlurOffset; 25 | 26 | v2f Vert(appdata v) 27 | { 28 | v2f o; 29 | o.vertex = TransformObjectToHClip(v.vertex.xyz); 30 | o.uv = v.uv; 31 | return o; 32 | } 33 | 34 | half4 BoxFilter_4Tap(sampler2D _MainTex, float2 uv, float2 texelSize) 35 | { 36 | float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0); 37 | 38 | half4 s = 0; 39 | s = tex2D(_MainTex, uv + d.xy) * 0.25h; 40 | s += tex2D(_MainTex, uv + d.zy) * 0.25h; 41 | s += tex2D(_MainTex, uv + d.xw) * 0.25h; 42 | s += tex2D(_MainTex, uv + d.zw) * 0.25h; 43 | return s; 44 | } 45 | 46 | 47 | float4 FragBoxBlur(v2f i): SV_Target 48 | { 49 | return BoxFilter_4Tap(_MainTex, i.uv, _BlurOffset.xy).rgba; 50 | } 51 | 52 | float4 FragCombine(v2f i): SV_Target 53 | { 54 | return tex2D(_MainTex, i.uv); 55 | } 56 | 57 | ENDHLSL 58 | 59 | SubShader 60 | { 61 | Cull Off ZWrite Off ZTest Always 62 | 63 | Pass 64 | { 65 | HLSLPROGRAM 66 | 67 | #pragma vertex Vert 68 | #pragma fragment FragBoxBlur 69 | 70 | ENDHLSL 71 | 72 | } 73 | 74 | Pass 75 | { 76 | HLSLPROGRAM 77 | 78 | #pragma vertex Vert 79 | #pragma fragment FragCombine 80 | 81 | ENDHLSL 82 | 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e801a6cc5322f54aa1de3550972be40 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class DualBoxBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class DualBoxBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int BlurOffset = Shader.PropertyToID("_BlurOffset"); 12 | 13 | private const string PROFILER_TAG = "DualBoxBlur"; 14 | 15 | private DualBoxBlur _dualBoxBlur; 16 | private Material _dualBoxBlurMat; 17 | RenderTargetIdentifier currentTarget; 18 | 19 | Level[] m_Pyramid; 20 | const int k_MaxPyramidSize = 16; 21 | 22 | public DualBoxBlurPass(RenderPassEvent evt) 23 | { 24 | renderPassEvent = evt; 25 | Shader dualBoxBlurShader=Shader.Find("Hidden/CustomPostEffect/DualBoxBlur"); 26 | if (dualBoxBlurShader) 27 | { 28 | _dualBoxBlurMat = CoreUtils.CreateEngineMaterial(dualBoxBlurShader); 29 | } 30 | 31 | m_Pyramid = new Level[k_MaxPyramidSize]; 32 | 33 | for (int i = 0; i < k_MaxPyramidSize; i++) 34 | { 35 | m_Pyramid[i] = new Level 36 | { 37 | down = Shader.PropertyToID("_BlurMipDown" + i), 38 | up = Shader.PropertyToID("_BlurMipUp" + i) 39 | }; 40 | } 41 | } 42 | 43 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 44 | { 45 | if (_dualBoxBlurMat == null) return; 46 | if (!renderingData.cameraData.postProcessEnabled) return; 47 | var stack = VolumeManager.instance.stack; 48 | _dualBoxBlur = stack.GetComponent(); 49 | if (_dualBoxBlur == null) return; 50 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 51 | Render(cmd, ref renderingData); 52 | context.ExecuteCommandBuffer(cmd); 53 | CommandBufferPool.Release(cmd); 54 | } 55 | 56 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 57 | { 58 | if (_dualBoxBlur.IsActive()) 59 | { 60 | var source = currentTarget; 61 | Camera camera = renderingData.cameraData.camera; 62 | cmd.BeginSample(PROFILER_TAG); 63 | 64 | int tw = (int) (camera.pixelWidth / _dualBoxBlur.RTDownScaling.value); 65 | int th = (int) (camera.pixelHeight / _dualBoxBlur.RTDownScaling.value); 66 | 67 | Vector4 BlurOffsetValue = new Vector4(_dualBoxBlur.BlurRadius.value / camera.pixelWidth, 68 | _dualBoxBlur.BlurRadius.value / camera.pixelHeight, 0, 0); 69 | _dualBoxBlurMat.SetVector(BlurOffset, BlurOffsetValue); 70 | // Downsample 71 | RenderTargetIdentifier lastDown = source; 72 | for (int i = 0; i < _dualBoxBlur.Iteration.value; i++) 73 | { 74 | int mipDown = m_Pyramid[i].down; 75 | int mipUp = m_Pyramid[i].up; 76 | cmd.GetTemporaryRT(mipDown, tw, th, 0, FilterMode.Bilinear); 77 | cmd.GetTemporaryRT(mipUp, tw, th, 0, FilterMode.Bilinear); 78 | cmd.Blit(lastDown, mipDown, _dualBoxBlurMat, 0); 79 | 80 | lastDown = mipDown; 81 | tw = Mathf.Max(tw / 2, 1); 82 | th = Mathf.Max(th / 2, 1); 83 | } 84 | 85 | // Upsample 86 | int lastUp = m_Pyramid[_dualBoxBlur.Iteration.value - 1].down; 87 | for (int i = _dualBoxBlur.Iteration.value - 2; i >= 0; i--) 88 | { 89 | int mipUp = m_Pyramid[i].up; 90 | cmd.Blit(lastUp, mipUp, _dualBoxBlurMat, 0); 91 | lastUp = mipUp; 92 | } 93 | 94 | 95 | // Render blurred texture in blend pass 96 | cmd.Blit(lastUp, source, _dualBoxBlurMat, 1); 97 | 98 | // Cleanup 99 | for (int i = 0; i < _dualBoxBlur.Iteration.value; i++) 100 | { 101 | if (m_Pyramid[i].down != lastUp) 102 | cmd.ReleaseTemporaryRT(m_Pyramid[i].down); 103 | if (m_Pyramid[i].up != lastUp) 104 | cmd.ReleaseTemporaryRT(m_Pyramid[i].up); 105 | } 106 | 107 | cmd.EndSample(PROFILER_TAG); 108 | } 109 | } 110 | 111 | public void Setup(in RenderTargetIdentifier currentTarget) 112 | { 113 | this.currentTarget = currentTarget; 114 | } 115 | 116 | public override void FrameCleanup(CommandBuffer cmd) 117 | { 118 | base.FrameCleanup(cmd); 119 | } 120 | 121 | struct Level 122 | { 123 | internal int down; 124 | internal int up; 125 | } 126 | } 127 | 128 | private DualBoxBlurPass _dualBoxBlurPass; 129 | 130 | public override void Create() 131 | { 132 | _dualBoxBlurPass = new DualBoxBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 133 | } 134 | 135 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 136 | { 137 | _dualBoxBlurPass.Setup(renderer.cameraColorTarget); 138 | renderer.EnqueuePass(_dualBoxBlurPass); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Blur/DualBoxBlur/DualBoxBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff418e2978b4ad84899e1e16d8a2a426 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa1029e6327657649a2271c4849acc52 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/DualGaussianBlur")] 9 | public class DualGaussianBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,15); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,8); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,10); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ef3804f4e1653664aa789112e48631b5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/DualGaussianBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | 8 | HLSLINCLUDE 9 | 10 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 11 | 12 | TEXTURE2D (_MainTex); 13 | SAMPLER(sampler_MainTex); 14 | 15 | half4 _BlurOffset; 16 | 17 | struct appdata 18 | { 19 | float4 vertex: POSITION; 20 | float2 uv: TEXCOORD0; 21 | }; 22 | 23 | struct v2f 24 | { 25 | float4 pos: SV_POSITION; 26 | float2 uv: TEXCOORD0; 27 | 28 | float4 uv01: TEXCOORD1; 29 | float4 uv23: TEXCOORD2; 30 | float4 uv45: TEXCOORD3; 31 | }; 32 | 33 | v2f VertGaussianBlur(appdata v) 34 | { 35 | v2f o; 36 | o.pos = TransformObjectToHClip(v.vertex.xyz); 37 | o.uv = v.uv; 38 | 39 | o.uv01 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1); 40 | o.uv23 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1) * 2.0; 41 | o.uv45 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1) * 6.0; 42 | 43 | return o; 44 | } 45 | 46 | v2f Vert(appdata v) 47 | { 48 | v2f o; 49 | o.pos = TransformObjectToHClip(v.vertex.xyz); 50 | o.uv = v.uv; 51 | return o; 52 | } 53 | 54 | float4 FragGaussianBlur(v2f i): SV_Target 55 | { 56 | half4 color = float4(0, 0, 0, 0); 57 | 58 | color += 0.40 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 59 | color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy); 60 | color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw); 61 | color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy); 62 | color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw); 63 | color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.xy); 64 | color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.zw); 65 | 66 | return color; 67 | } 68 | 69 | 70 | float4 FragCombine(v2f i): SV_Target 71 | { 72 | return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 73 | } 74 | 75 | 76 | ENDHLSL 77 | 78 | SubShader 79 | { 80 | Cull Off ZWrite Off ZTest Always 81 | 82 | Pass 83 | { 84 | HLSLPROGRAM 85 | 86 | #pragma vertex VertGaussianBlur 87 | #pragma fragment FragGaussianBlur 88 | 89 | ENDHLSL 90 | 91 | } 92 | 93 | Pass 94 | { 95 | HLSLPROGRAM 96 | 97 | #pragma vertex Vert 98 | #pragma fragment FragCombine 99 | 100 | ENDHLSL 101 | 102 | } 103 | } 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 590c5f13d6564f54480cab983a21102e 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class DualGaussianBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | private DualGaussianBlurPass _dualGaussianBlurPass; 10 | 11 | public class DualGaussianBlurPass : ScriptableRenderPass 12 | { 13 | internal static readonly int BlurOffset = Shader.PropertyToID("_BlurOffset"); 14 | 15 | Level[] m_Pyramid; 16 | const int k_MaxPyramidSize = 16; 17 | 18 | private const string PROFILER_TAG = "DualGaussianBlur"; 19 | 20 | private DualGaussianBlur _dualGaussianBlur; 21 | private Material dualGaussianBlurMat; 22 | RenderTargetIdentifier currentTarget; 23 | 24 | public DualGaussianBlurPass(RenderPassEvent evt) 25 | { 26 | renderPassEvent = evt; 27 | Shader dualGaussianBlurShader = Shader.Find("Hidden/CustomPostEffect/DualGaussianBlur"); 28 | if (dualGaussianBlurShader) 29 | { 30 | dualGaussianBlurMat = CoreUtils.CreateEngineMaterial(dualGaussianBlurShader); 31 | } 32 | 33 | m_Pyramid = new Level[k_MaxPyramidSize]; 34 | 35 | for (int i = 0; i < k_MaxPyramidSize; i++) 36 | { 37 | m_Pyramid[i] = new Level 38 | { 39 | down_vertical = Shader.PropertyToID("_BlurMipDownV" + i), 40 | down_horizontal = Shader.PropertyToID("_BlurMipDownH" + i), 41 | up_vertical = Shader.PropertyToID("_BlurMipUpV" + i), 42 | up_horizontal = Shader.PropertyToID("_BlurMipUpH" + i), 43 | 44 | }; 45 | } 46 | } 47 | 48 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 49 | { 50 | if (dualGaussianBlurMat == null) return; 51 | if (!renderingData.cameraData.postProcessEnabled) return; 52 | var stack = VolumeManager.instance.stack; 53 | _dualGaussianBlur = stack.GetComponent(); 54 | if (_dualGaussianBlur == null) return; 55 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 56 | Render(cmd, ref renderingData); 57 | context.ExecuteCommandBuffer(cmd); 58 | CommandBufferPool.Release(cmd); 59 | } 60 | 61 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 62 | { 63 | if (_dualGaussianBlur.IsActive()) 64 | { 65 | var source = currentTarget; 66 | Camera camera = renderingData.cameraData.camera; 67 | cmd.BeginSample(PROFILER_TAG); 68 | 69 | 70 | int tw = (int) (camera.pixelWidth / _dualGaussianBlur.RTDownScaling.value); 71 | int th = (int) (camera.pixelHeight / _dualGaussianBlur.RTDownScaling.value); 72 | 73 | Vector4 BlurOffsetValue = new Vector4(_dualGaussianBlur.BlurRadius.value / (float) camera.pixelWidth, 74 | _dualGaussianBlur.BlurRadius.value / (float) camera.pixelHeight, 0, 0); 75 | dualGaussianBlurMat.SetVector(BlurOffset, BlurOffsetValue); 76 | // Downsample 77 | RenderTargetIdentifier lastDown = source; 78 | for (int i = 0; i < _dualGaussianBlur.Iteration.value; i++) 79 | { 80 | int mipDownV = m_Pyramid[i].down_vertical; 81 | int mipDowH = m_Pyramid[i].down_horizontal; 82 | int mipUpV = m_Pyramid[i].up_vertical; 83 | int mipUpH = m_Pyramid[i].up_horizontal; 84 | 85 | cmd.GetTemporaryRT(mipDownV, tw, th, 0, FilterMode.Bilinear); 86 | cmd.GetTemporaryRT(mipDowH, tw, th, 0, FilterMode.Bilinear); 87 | cmd.GetTemporaryRT(mipUpV, tw, th, 0, FilterMode.Bilinear); 88 | cmd.GetTemporaryRT(mipUpH, tw, th, 0, FilterMode.Bilinear); 89 | 90 | // horizontal blur 91 | dualGaussianBlurMat.SetVector(BlurOffset, 92 | new Vector4(_dualGaussianBlur.BlurRadius.value / camera.pixelWidth, 0, 0, 0)); 93 | cmd.Blit(lastDown, mipDowH, dualGaussianBlurMat, 0); 94 | 95 | // vertical blur 96 | dualGaussianBlurMat.SetVector(BlurOffset, 97 | new Vector4(0, _dualGaussianBlur.BlurRadius.value / camera.pixelHeight, 0, 0)); 98 | cmd.Blit(mipDowH, mipDownV, dualGaussianBlurMat, 0); 99 | 100 | lastDown = mipDownV; 101 | tw = Mathf.Max(tw / 2, 1); 102 | th = Mathf.Max(th / 2, 1); 103 | } 104 | 105 | // Upsample 106 | int lastUp = m_Pyramid[_dualGaussianBlur.Iteration.value - 1].down_vertical; 107 | for (int i = _dualGaussianBlur.Iteration.value - 2; i >= 0; i--) 108 | { 109 | 110 | int mipUpV = m_Pyramid[i].up_vertical; 111 | int mipUpH = m_Pyramid[i].up_horizontal; 112 | 113 | // horizontal blur 114 | dualGaussianBlurMat.SetVector(BlurOffset, 115 | new Vector4(_dualGaussianBlur.BlurRadius.value / camera.pixelWidth, 0, 0, 0)); 116 | cmd.Blit(lastUp, mipUpH, dualGaussianBlurMat, 0); 117 | 118 | // vertical blur 119 | dualGaussianBlurMat.SetVector(BlurOffset, 120 | new Vector4(0, _dualGaussianBlur.BlurRadius.value / camera.pixelHeight, 0, 0)); 121 | cmd.Blit(mipUpH, mipUpV, dualGaussianBlurMat, 0); 122 | 123 | lastUp = mipUpV; 124 | } 125 | 126 | 127 | // Render blurred texture in blend pass 128 | cmd.Blit(lastUp, source, dualGaussianBlurMat, 1); 129 | 130 | // Cleanup 131 | for (int i = 0; i < _dualGaussianBlur.Iteration.value; i++) 132 | { 133 | if (m_Pyramid[i].down_vertical != lastUp) 134 | cmd.ReleaseTemporaryRT(m_Pyramid[i].down_vertical); 135 | if (m_Pyramid[i].down_horizontal != lastUp) 136 | cmd.ReleaseTemporaryRT(m_Pyramid[i].down_horizontal); 137 | if (m_Pyramid[i].up_horizontal != lastUp) 138 | cmd.ReleaseTemporaryRT(m_Pyramid[i].up_horizontal); 139 | if (m_Pyramid[i].up_vertical != lastUp) 140 | cmd.ReleaseTemporaryRT(m_Pyramid[i].up_vertical); 141 | } 142 | 143 | cmd.EndSample(PROFILER_TAG); 144 | } 145 | } 146 | 147 | public void Setup(in RenderTargetIdentifier currentTarget) 148 | { 149 | this.currentTarget = currentTarget; 150 | } 151 | 152 | public override void FrameCleanup(CommandBuffer cmd) 153 | { 154 | base.FrameCleanup(cmd); 155 | } 156 | 157 | struct Level 158 | { 159 | internal int down_vertical; 160 | internal int down_horizontal; 161 | internal int up_horizontal; 162 | internal int up_vertical; 163 | } 164 | } 165 | 166 | public override void Create() 167 | { 168 | _dualGaussianBlurPass = new DualGaussianBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 169 | } 170 | 171 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 172 | { 173 | _dualGaussianBlurPass.Setup(renderer.cameraColorTarget); 174 | renderer.EnqueuePass(_dualGaussianBlurPass); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Blur/DualGaussianBlur/DualGaussianBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b1ae3b471fc57e4890a45c2304ed430 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07e2677f6fb7fc64b8bf178c78c5adf3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/DualKawaseBlur")] 9 | public class DualKawaseBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,15); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,10); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,10); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a25c89454ee47db42bbb6a81ec2d6d8c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/DualKawaseBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | 8 | HLSLINCLUDE 9 | 10 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 11 | 12 | TEXTURE2D (_MainTex); 13 | SAMPLER(sampler_MainTex); 14 | float4 _MainTex_TexelSize; 15 | uniform half _Offset; 16 | 17 | struct appdata 18 | { 19 | float4 vertex: POSITION; 20 | float2 uv: TEXCOORD0; 21 | }; 22 | 23 | struct v2f 24 | { 25 | float4 pos: SV_POSITION; 26 | float2 uv: TEXCOORD0; 27 | }; 28 | 29 | struct v2f_DownSample 30 | { 31 | float4 vertex: SV_POSITION; 32 | float2 texcoord: TEXCOORD0; 33 | float2 uv: TEXCOORD1; 34 | float4 uv01: TEXCOORD2; 35 | float4 uv23: TEXCOORD3; 36 | }; 37 | 38 | 39 | struct v2f_UpSample 40 | { 41 | float4 vertex: SV_POSITION; 42 | float2 texcoord: TEXCOORD0; 43 | float4 uv01: TEXCOORD1; 44 | float4 uv23: TEXCOORD2; 45 | float4 uv45: TEXCOORD3; 46 | float4 uv67: TEXCOORD4; 47 | }; 48 | 49 | 50 | v2f_DownSample Vert_DownSample(v2f v) 51 | { 52 | v2f_DownSample o = (v2f_DownSample)0; 53 | o.vertex = TransformObjectToHClip(v.pos.xyz); 54 | float2 uv = v.uv; 55 | 56 | _MainTex_TexelSize *= 0.5; 57 | o.uv = uv; 58 | o.uv01.xy = uv - _MainTex_TexelSize * float2(1 + _Offset, 1 + _Offset);//top right 59 | o.uv01.zw = uv + _MainTex_TexelSize * float2(1 + _Offset, 1 + _Offset);//bottom left 60 | o.uv23.xy = uv - float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * float2(1 + _Offset, 1 + _Offset);//top left 61 | o.uv23.zw = uv + float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * float2(1 + _Offset, 1 + _Offset);//bottom right 62 | 63 | return o; 64 | } 65 | 66 | half4 Frag_DownSample(v2f_DownSample i): SV_Target 67 | { 68 | half4 sum = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv) * 4; 69 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy); 70 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw); 71 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy); 72 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw); 73 | 74 | return sum * 0.125; 75 | } 76 | 77 | 78 | v2f_UpSample Vert_UpSample(v2f v) 79 | { 80 | v2f_UpSample o; 81 | o.vertex = TransformObjectToHClip(v.pos.xyz); 82 | float2 uv = v.uv; 83 | 84 | _MainTex_TexelSize *= 0.5; 85 | _Offset = float2(1 + _Offset, 1 + _Offset); 86 | 87 | o.uv01.xy = uv + float2(-_MainTex_TexelSize.x * 2, 0) * _Offset; 88 | o.uv01.zw = uv + float2(-_MainTex_TexelSize.x, _MainTex_TexelSize.y) * _Offset; 89 | o.uv23.xy = uv + float2(0, _MainTex_TexelSize.y * 2) * _Offset; 90 | o.uv23.zw = uv + _MainTex_TexelSize * _Offset; 91 | o.uv45.xy = uv + float2(_MainTex_TexelSize.x * 2, 0) * _Offset; 92 | o.uv45.zw = uv + float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _Offset; 93 | o.uv67.xy = uv + float2(0, -_MainTex_TexelSize.y * 2) * _Offset; 94 | o.uv67.zw = uv - _MainTex_TexelSize * _Offset; 95 | 96 | return o; 97 | } 98 | 99 | half4 Frag_UpSample(v2f_UpSample i): SV_Target 100 | { 101 | half4 sum = 0; 102 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy); 103 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw) * 2; 104 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy); 105 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw) * 2; 106 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.xy); 107 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.zw) * 2; 108 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv67.xy); 109 | sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv67.zw) * 2; 110 | 111 | return sum * 0.0833; 112 | } 113 | 114 | ENDHLSL 115 | 116 | SubShader 117 | { 118 | Cull Off ZWrite Off ZTest Always 119 | 120 | Pass 121 | { 122 | HLSLPROGRAM 123 | 124 | #pragma vertex Vert_DownSample 125 | #pragma fragment Frag_DownSample 126 | 127 | ENDHLSL 128 | 129 | } 130 | 131 | Pass 132 | { 133 | HLSLPROGRAM 134 | 135 | #pragma vertex Vert_UpSample 136 | #pragma fragment Frag_UpSample 137 | 138 | ENDHLSL 139 | 140 | } 141 | } 142 | } 143 | 144 | 145 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3dbeb9658a9789b47b65dc8717a9ed9a 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class DualKawaseBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class DualKawaseBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int BlurOffset = Shader.PropertyToID("_Offset"); 12 | 13 | Level[] m_Pyramid; 14 | const int k_MaxPyramidSize = 16; 15 | 16 | private const string PROFILER_TAG = "DualKawaseBlur"; 17 | private DualKawaseBlur _dualKawaseBlur; 18 | private Material dualKawaseBlurMat; 19 | RenderTargetIdentifier currentTarget; 20 | 21 | public DualKawaseBlurPass(RenderPassEvent evt) 22 | { 23 | renderPassEvent = evt; 24 | Shader dualKawaseBlurShader = Shader.Find("Hidden/CustomPostEffect/DualKawaseBlur"); 25 | if (dualKawaseBlurShader) 26 | { 27 | dualKawaseBlurMat = CoreUtils.CreateEngineMaterial(dualKawaseBlurShader); 28 | } 29 | 30 | m_Pyramid = new Level[k_MaxPyramidSize]; 31 | 32 | for (int i = 0; i < k_MaxPyramidSize; i++) 33 | { 34 | m_Pyramid[i] = new Level 35 | { 36 | down = Shader.PropertyToID("_BlurMipDown" + i), 37 | up = Shader.PropertyToID("_BlurMipUp" + i) 38 | }; 39 | } 40 | } 41 | 42 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 43 | { 44 | if (dualKawaseBlurMat == null) return; 45 | if (!renderingData.cameraData.postProcessEnabled) return; 46 | var stack = VolumeManager.instance.stack; 47 | _dualKawaseBlur = stack.GetComponent(); 48 | if (_dualKawaseBlur == null) return; 49 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 50 | Render(cmd, ref renderingData); 51 | context.ExecuteCommandBuffer(cmd); 52 | CommandBufferPool.Release(cmd); 53 | } 54 | 55 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 56 | { 57 | if (_dualKawaseBlur.IsActive()) 58 | { 59 | var source = currentTarget; 60 | Camera camera = renderingData.cameraData.camera; 61 | cmd.BeginSample(PROFILER_TAG); 62 | 63 | int tw = (int) (camera.pixelWidth / _dualKawaseBlur.RTDownScaling.value); 64 | int th = (int) (camera.pixelHeight / _dualKawaseBlur.RTDownScaling.value); 65 | 66 | dualKawaseBlurMat.SetFloat(BlurOffset, _dualKawaseBlur.BlurRadius.value); 67 | 68 | 69 | // Downsample 70 | RenderTargetIdentifier lastDown = source; 71 | for (int i = 0; i < _dualKawaseBlur.Iteration.value; i++) 72 | { 73 | int mipDown = m_Pyramid[i].down; 74 | int mipUp = m_Pyramid[i].up; 75 | cmd.GetTemporaryRT(mipDown, tw, th, 0, FilterMode.Bilinear); 76 | cmd.GetTemporaryRT(mipUp, tw, th, 0, FilterMode.Bilinear); 77 | cmd.Blit(lastDown, mipDown, dualKawaseBlurMat, 0); 78 | 79 | lastDown = mipDown; 80 | tw = Mathf.Max(tw / 2, 1); 81 | th = Mathf.Max(th / 2, 1); 82 | } 83 | 84 | // Upsample 85 | int lastUp = m_Pyramid[_dualKawaseBlur.Iteration.value - 1].down; 86 | for (int i = _dualKawaseBlur.Iteration .value- 2; i >= 0; i--) 87 | { 88 | int mipUp = m_Pyramid[i].up; 89 | 90 | cmd.Blit(lastUp, mipUp, dualKawaseBlurMat, 1); 91 | lastUp = mipUp; 92 | } 93 | 94 | 95 | // Render blurred texture in blend pass 96 | cmd.Blit(lastUp, source, dualKawaseBlurMat, 1); 97 | 98 | // Cleanup 99 | for (int i = 0; i < _dualKawaseBlur.Iteration.value; i++) 100 | { 101 | if (m_Pyramid[i].down != lastUp) 102 | cmd.ReleaseTemporaryRT(m_Pyramid[i].down); 103 | if (m_Pyramid[i].up != lastUp) 104 | cmd.ReleaseTemporaryRT(m_Pyramid[i].up); 105 | } 106 | 107 | cmd.EndSample(PROFILER_TAG); 108 | } 109 | } 110 | 111 | public void Setup(in RenderTargetIdentifier currentTarget) 112 | { 113 | this.currentTarget = currentTarget; 114 | } 115 | 116 | public override void FrameCleanup(CommandBuffer cmd) 117 | { 118 | base.FrameCleanup(cmd); 119 | } 120 | 121 | struct Level 122 | { 123 | internal int down; 124 | internal int up; 125 | } 126 | } 127 | 128 | private DualKawaseBlurPass _dualKawaseBlurPass; 129 | 130 | public override void Create() 131 | { 132 | _dualKawaseBlurPass = new DualKawaseBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 133 | } 134 | 135 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 136 | { 137 | _dualKawaseBlurPass.Setup(renderer.cameraColorTarget); 138 | renderer.EnqueuePass(_dualKawaseBlurPass); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Blur/DualKawaseBlur/DualKawaseBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e11fe2087d35df14bb8e8ed40fe7b38b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualTentBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 895d2b7544200b649ac37f5fc5ca428d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/DualTentBlur")] 9 | public class DualTentBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,15); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,8); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,10); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1227c91f6fec444d8173f1110ac2a4c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/DualTentBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct v2f 18 | { 19 | float4 pos: SV_POSITION; 20 | float2 uv: TEXCOORD0; 21 | }; 22 | 23 | v2f Vert(appdata v) 24 | { 25 | v2f o; 26 | o.pos = TransformObjectToHClip(v.vertex.xyz); 27 | o.uv = v.uv; 28 | return o; 29 | } 30 | 31 | sampler2D _MainTex; 32 | half4 _BlurOffset; 33 | 34 | // 9-tap tent filter 35 | half4 TentFilter_9Tap(sampler2D tex, float2 uv, float2 texelSize) 36 | { 37 | float4 d = texelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0); 38 | 39 | half4 s; 40 | s = tex2D(tex, uv - d.xy); 41 | s += tex2D(tex, uv - d.wy) * 2.0; // 1 MAD 42 | s += tex2D(tex, uv - d.zy); // 1 MAD 43 | 44 | s += tex2D(tex, uv + d.zw) * 2.0; // 1 MAD 45 | s += tex2D(tex, uv) * 4.0; // 1 MAD 46 | s += tex2D(tex, uv + d.xw) * 2.0; // 1 MAD 47 | 48 | s += tex2D(tex, uv + d.zy); 49 | s += tex2D(tex, uv + d.wy) * 2.0; // 1 MAD 50 | s += tex2D(tex, uv + d.xy); 51 | 52 | return s * (1.0 / 16.0); 53 | } 54 | 55 | float4 FragTentBlur(v2f i): SV_Target 56 | { 57 | return TentFilter_9Tap(_MainTex, i.uv, _BlurOffset.xy).rgba; 58 | } 59 | 60 | float4 FragCombine(v2f i): SV_Target 61 | { 62 | return tex2D(_MainTex, i.uv); 63 | } 64 | 65 | ENDHLSL 66 | 67 | SubShader 68 | { 69 | Cull Off ZWrite Off ZTest Always 70 | 71 | Pass 72 | { 73 | HLSLPROGRAM 74 | 75 | #pragma vertex Vert 76 | #pragma fragment FragTentBlur 77 | 78 | ENDHLSL 79 | 80 | } 81 | 82 | Pass 83 | { 84 | HLSLPROGRAM 85 | 86 | #pragma vertex Vert 87 | #pragma fragment FragCombine 88 | 89 | ENDHLSL 90 | 91 | } 92 | } 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3239ef5becc12644e877b9bfa184b660 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class DualTentBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class DualTentBlurPass : ScriptableRenderPass 10 | { 11 | private const string PROFILER_TAG = "DualTentBlur"; 12 | RenderTargetIdentifier currentTarget; 13 | private DualTentBlur _dualTentBlur; 14 | 15 | Level[] m_Pyramid; 16 | const int k_MaxPyramidSize = 16; 17 | 18 | internal static readonly int BlurOffset = Shader.PropertyToID("_BlurOffset"); 19 | private Material dualKawaseBlurMat; 20 | 21 | public DualTentBlurPass(RenderPassEvent evt) 22 | { 23 | renderPassEvent = evt; 24 | Shader dualTentBlurShader = Shader.Find("Hidden/CustomPostEffect/DualTentBlur"); 25 | if (dualTentBlurShader) 26 | { 27 | dualKawaseBlurMat = CoreUtils.CreateEngineMaterial(dualTentBlurShader); 28 | } 29 | 30 | m_Pyramid = new Level[k_MaxPyramidSize]; 31 | 32 | for (int i = 0; i < k_MaxPyramidSize; i++) 33 | { 34 | m_Pyramid[i] = new Level 35 | { 36 | down = Shader.PropertyToID("_BlurMipDown" + i), 37 | up = Shader.PropertyToID("_BlurMipUp" + i) 38 | }; 39 | } 40 | } 41 | 42 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 43 | { 44 | if (dualKawaseBlurMat == null) return; 45 | if (!renderingData.cameraData.postProcessEnabled) return; 46 | var stack = VolumeManager.instance.stack; 47 | _dualTentBlur = stack.GetComponent(); 48 | if (_dualTentBlur == null) return; 49 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 50 | Render(cmd, ref renderingData); 51 | context.ExecuteCommandBuffer(cmd); 52 | CommandBufferPool.Release(cmd); 53 | } 54 | 55 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 56 | { 57 | if (_dualTentBlur.IsActive()) 58 | { 59 | var source = currentTarget; 60 | Camera camera = renderingData.cameraData.camera; 61 | cmd.BeginSample(PROFILER_TAG); 62 | 63 | int tw = (int) (camera.pixelWidth / _dualTentBlur.RTDownScaling.value); 64 | int th = (int) (camera.pixelHeight / _dualTentBlur.RTDownScaling.value); 65 | 66 | Vector4 BlurOffsetValue = new Vector4(_dualTentBlur.BlurRadius.value / (float) camera.pixelWidth, 67 | _dualTentBlur.BlurRadius.value / (float) camera.pixelHeight, 0, 0); 68 | dualKawaseBlurMat.SetVector(BlurOffset, BlurOffsetValue); 69 | // Downsample 70 | RenderTargetIdentifier lastDown = source; 71 | for (int i = 0; i < _dualTentBlur.Iteration.value; i++) 72 | { 73 | int mipDown = m_Pyramid[i].down; 74 | int mipUp = m_Pyramid[i].up; 75 | cmd.GetTemporaryRT(mipDown, tw, th, 0, FilterMode.Bilinear); 76 | cmd.GetTemporaryRT(mipUp, tw, th, 0, FilterMode.Bilinear); 77 | cmd.Blit(lastDown, mipDown, dualKawaseBlurMat, 0); 78 | 79 | lastDown = mipDown; 80 | tw = Mathf.Max(tw / 2, 1); 81 | th = Mathf.Max(th / 2, 1); 82 | } 83 | 84 | // Upsample 85 | int lastUp = m_Pyramid[_dualTentBlur.Iteration.value - 1].down; 86 | for (int i = _dualTentBlur.Iteration.value - 2; i >= 0; i--) 87 | { 88 | int mipUp = m_Pyramid[i].up; 89 | cmd.Blit(lastUp, mipUp, dualKawaseBlurMat, 0); 90 | lastUp = mipUp; 91 | } 92 | 93 | 94 | // Render blurred texture in blend pass 95 | cmd.Blit(lastUp, source, dualKawaseBlurMat, 1); 96 | 97 | // Cleanup 98 | for (int i = 0; i < _dualTentBlur.Iteration.value; i++) 99 | { 100 | if (m_Pyramid[i].down != lastUp) 101 | cmd.ReleaseTemporaryRT(m_Pyramid[i].down); 102 | if (m_Pyramid[i].up != lastUp) 103 | cmd.ReleaseTemporaryRT(m_Pyramid[i].up); 104 | } 105 | 106 | cmd.EndSample(PROFILER_TAG); 107 | } 108 | } 109 | 110 | public void Setup(in RenderTargetIdentifier currentTarget) 111 | { 112 | this.currentTarget = currentTarget; 113 | } 114 | 115 | public override void FrameCleanup(CommandBuffer cmd) 116 | { 117 | base.FrameCleanup(cmd); 118 | } 119 | 120 | struct Level 121 | { 122 | internal int down; 123 | internal int up; 124 | } 125 | } 126 | 127 | private DualTentBlurPass _dualTentBlurPass; 128 | 129 | public override void Create() 130 | { 131 | _dualTentBlurPass = new DualTentBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 132 | } 133 | 134 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 135 | { 136 | _dualTentBlurPass.Setup(renderer.cameraColorTarget); 137 | renderer.EnqueuePass(_dualTentBlurPass); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Blur/DualTentBlur/DualTentBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1950d4f36000df4409c4572217982fa2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/GaussianBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb91345ab3db364083de1e6d6b09d65 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/GaussianBlur")] 9 | public class GaussianBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,5); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (6,1,15); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,8); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f79c4f324983804995f6e0071ecb38f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/GaussianBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | TEXTURE2D (_MainTex); 12 | SAMPLER(sampler_MainTex); 13 | half4 _BlurOffset; 14 | 15 | struct appdata 16 | { 17 | float4 vertex: POSITION; 18 | float2 uv: TEXCOORD0; 19 | }; 20 | 21 | struct VaryingsDefault 22 | { 23 | float4 pos: SV_POSITION; 24 | float2 uv: TEXCOORD0; 25 | }; 26 | 27 | 28 | struct v2f 29 | { 30 | float4 pos: SV_POSITION; 31 | float2 uv: TEXCOORD0; 32 | float4 uv01: TEXCOORD1; 33 | float4 uv23: TEXCOORD2; 34 | float4 uv45: TEXCOORD3; 35 | }; 36 | 37 | VaryingsDefault Vert(appdata v) 38 | { 39 | VaryingsDefault o; 40 | o.pos = TransformObjectToHClip(v.vertex.xyz); 41 | o.uv = v.uv; 42 | return o; 43 | } 44 | 45 | v2f VertGaussianBlur(appdata v) 46 | { 47 | v2f o; 48 | o.pos = TransformObjectToHClip(v.vertex.xyz); 49 | o.uv = v.uv; 50 | 51 | o.uv01 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1); 52 | o.uv23 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1) * 2.0; 53 | o.uv45 = o.uv.xyxy + _BlurOffset.xyxy * float4(1, 1, -1, -1) * 6.0; 54 | 55 | return o; 56 | } 57 | 58 | float4 FragGaussianBlur(v2f i): SV_Target 59 | { 60 | half4 color = float4(0, 0, 0, 0); 61 | 62 | color += 0.40 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 63 | color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy); 64 | color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw); 65 | color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy); 66 | color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw); 67 | color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.xy); 68 | color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.zw); 69 | 70 | return color; 71 | } 72 | 73 | half4 Tex2DBlurring(sampler2D tex, half2 texcood, half2 blur) 74 | { 75 | //快速模糊 76 | //const int KERNEL_SIZE = 3; 77 | //const float KERNEL_[3] = { 0.4566, 1.0, 0.4566 }; 78 | 79 | //中等模糊 80 | const int KERNEL_SIZE = 5; 81 | const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486 }; 82 | 83 | //高级模糊 84 | //const int KERNEL_SIZE = 7; 85 | //const float KERNEL_[7] = { 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719 }; 86 | float4 o = 0; 87 | float sum = 0; 88 | float2 shift = 0; 89 | for (int x = 0; x < KERNEL_SIZE; x++) 90 | { 91 | shift.x = blur.x * (float(x) - KERNEL_SIZE / 2); 92 | for (int y = 0; y < KERNEL_SIZE; y++) 93 | { 94 | shift.y = blur.y * (float(y) - KERNEL_SIZE / 2); 95 | float2 uv = texcood + shift; 96 | float weight = KERNEL_[x] * KERNEL_[y]; 97 | sum += weight; 98 | o += tex2D(tex, uv) * weight; 99 | } 100 | } 101 | return o / sum; 102 | } 103 | 104 | 105 | float4 FragCombine(VaryingsDefault i): SV_Target 106 | { 107 | return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 108 | } 109 | 110 | 111 | ENDHLSL 112 | 113 | SubShader 114 | { 115 | Cull Off ZWrite Off ZTest Always 116 | 117 | Pass 118 | { 119 | HLSLPROGRAM 120 | 121 | #pragma vertex VertGaussianBlur 122 | #pragma fragment FragGaussianBlur 123 | 124 | ENDHLSL 125 | 126 | } 127 | 128 | Pass 129 | { 130 | HLSLPROGRAM 131 | 132 | #pragma vertex Vert 133 | #pragma fragment FragCombine 134 | 135 | ENDHLSL 136 | 137 | } 138 | } 139 | } 140 | 141 | 142 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66aa70b12ee8d9e4fb126486c87c0f17 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class GaussianBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class GaussianBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int BlurRadius = Shader.PropertyToID("_BlurOffset"); 12 | internal static readonly int BufferRT1 = Shader.PropertyToID("_BufferRT1"); 13 | internal static readonly int BufferRT2 = Shader.PropertyToID("_BufferRT2"); 14 | 15 | private const string PROFILER_TAG = "GaussianBlur"; 16 | RenderTargetIdentifier currentTarget; 17 | private GaussianBlur _gaussianBlur; 18 | 19 | const int k_MaxPyramidSize = 16; 20 | 21 | internal static readonly int BlurOffset = Shader.PropertyToID("_BlurOffset"); 22 | private Material gaussianBlurMat; 23 | 24 | public GaussianBlurPass(RenderPassEvent evt) 25 | { 26 | renderPassEvent = evt; 27 | Shader gaussianBlurShader = Shader.Find("Hidden/CustomPostEffect/GaussianBlur"); 28 | if (gaussianBlurShader) 29 | { 30 | gaussianBlurMat = CoreUtils.CreateEngineMaterial(gaussianBlurShader); 31 | } 32 | } 33 | 34 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 35 | { 36 | if (gaussianBlurMat == null) return; 37 | if (!renderingData.cameraData.postProcessEnabled) return; 38 | var stack = VolumeManager.instance.stack; 39 | _gaussianBlur = stack.GetComponent(); 40 | if (_gaussianBlur == null) return; 41 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 42 | Render(cmd, ref renderingData); 43 | context.ExecuteCommandBuffer(cmd); 44 | CommandBufferPool.Release(cmd); 45 | } 46 | 47 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 48 | { 49 | if (_gaussianBlur.IsActive()) 50 | { 51 | var source = currentTarget; 52 | Camera camera = renderingData.cameraData.camera; 53 | 54 | cmd.BeginSample(PROFILER_TAG); 55 | 56 | int RTWidth = (int) (camera.pixelWidth / _gaussianBlur.RTDownScaling.value); 57 | int RTHeight = (int) (camera.pixelHeight / _gaussianBlur.RTDownScaling.value); 58 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 59 | cmd.GetTemporaryRT(BufferRT2, RTWidth, RTHeight, 0, FilterMode.Bilinear); 60 | 61 | // downsample screen copy into smaller RT 62 | cmd.Blit(source, BufferRT1); 63 | 64 | 65 | for (int i = 0; i < _gaussianBlur.Iteration.value; i++) 66 | { 67 | // horizontal blur 68 | gaussianBlurMat.SetVector(BlurRadius, 69 | new Vector4(_gaussianBlur.BlurRadius.value / camera.pixelWidth, 0, 0, 0)); 70 | cmd.Blit(BufferRT1, BufferRT2, gaussianBlurMat, 0); 71 | 72 | // vertical blur 73 | gaussianBlurMat.SetVector(BlurRadius, 74 | new Vector4(0, _gaussianBlur.BlurRadius.value / camera.pixelHeight, 0, 0)); 75 | cmd.Blit(BufferRT2, BufferRT1, gaussianBlurMat, 0); 76 | } 77 | 78 | // Render blurred texture in blend pass 79 | cmd.Blit(BufferRT1, source, gaussianBlurMat, 1); 80 | 81 | // release 82 | cmd.ReleaseTemporaryRT(BufferRT1); 83 | cmd.ReleaseTemporaryRT(BufferRT2); 84 | 85 | cmd.EndSample(PROFILER_TAG); 86 | } 87 | } 88 | 89 | public void Setup(in RenderTargetIdentifier currentTarget) 90 | { 91 | this.currentTarget = currentTarget; 92 | } 93 | 94 | public override void FrameCleanup(CommandBuffer cmd) 95 | { 96 | base.FrameCleanup(cmd); 97 | } 98 | } 99 | 100 | private GaussianBlurPass _gaussianBlurPass; 101 | 102 | public override void Create() 103 | { 104 | _gaussianBlurPass = new GaussianBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 105 | } 106 | 107 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 108 | { 109 | _gaussianBlurPass.Setup(renderer.cameraColorTarget); 110 | renderer.EnqueuePass(_gaussianBlurPass); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Blur/GaussianBlur/GaussianBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fd49267eb6983f40b4be576509c42c5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/GrainyBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6be78e5615488654a805f4f4f60fe951 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/GrainyBlur")] 9 | public class GrainyBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,50); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (4,1,8); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (1,1,10); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b332fffb77c1ca149b20668920ddf03a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/GrainyBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | TEXTURE2D (_MainTex); 12 | SAMPLER(sampler_MainTex); 13 | half2 _Params; 14 | half _MainTex_ST; 15 | 16 | #define _BlurRadius _Params.x 17 | #define _Iteration _Params.y 18 | 19 | struct appdata 20 | { 21 | float4 vertex: POSITION; 22 | float2 uv: TEXCOORD0; 23 | }; 24 | 25 | struct VaryingsDefault 26 | { 27 | float4 pos: SV_POSITION; 28 | float2 uv: TEXCOORD0; 29 | }; 30 | 31 | 32 | VaryingsDefault Vert(appdata v) 33 | { 34 | VaryingsDefault o; 35 | o.pos = TransformObjectToHClip(v.vertex.xyz); 36 | o.uv = v.uv; 37 | return o; 38 | } 39 | 40 | float Rand(float2 n) 41 | { 42 | return sin(dot(n, half2(1233.224, 1743.335))); 43 | } 44 | 45 | half4 GrainyBlur(VaryingsDefault i) 46 | { 47 | half2 randomOffset = float2(0.0, 0.0); 48 | half4 finalColor = half4(0.0, 0.0, 0.0, 0.0); 49 | float random = Rand(i.uv); 50 | 51 | for (int k = 0; k < int(_Iteration); k ++) 52 | { 53 | random = frac(43758.5453 * random + 0.61432);; 54 | randomOffset.x = (random - 0.5) * 2.0; 55 | random = frac(43758.5453 * random + 0.61432); 56 | randomOffset.y = (random - 0.5) * 2.0; 57 | 58 | finalColor += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, half2(i.uv + randomOffset * _BlurRadius)); 59 | } 60 | return finalColor / _Iteration; 61 | } 62 | 63 | half4 Frag(VaryingsDefault i): SV_Target 64 | { 65 | return GrainyBlur(i); 66 | } 67 | 68 | ENDHLSL 69 | 70 | SubShader 71 | { 72 | Cull Off ZWrite Off ZTest Always 73 | 74 | Pass 75 | { 76 | HLSLPROGRAM 77 | 78 | #pragma vertex Vert 79 | #pragma fragment Frag 80 | 81 | ENDHLSL 82 | 83 | } 84 | } 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8f8a8000dd7c9747aed3dfd9c0ff669 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class GrainyBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class GrainyBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int Params = Shader.PropertyToID("_Params"); 12 | internal static readonly int BufferRT = Shader.PropertyToID("_BufferRT"); 13 | 14 | private const string PROFILER_TAG = "GrainyBlur"; 15 | RenderTargetIdentifier currentTarget; 16 | private GrainyBlur _grainyBlur; 17 | private Material grainyBlurMat; 18 | 19 | public GrainyBlurPass(RenderPassEvent evet) 20 | { 21 | renderPassEvent = evet; 22 | Shader grainyBlurShader = Shader.Find("Hidden/CustomPostEffect/GrainyBlur"); 23 | if (grainyBlurShader) 24 | { 25 | grainyBlurMat = CoreUtils.CreateEngineMaterial(grainyBlurShader); 26 | } 27 | } 28 | 29 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 30 | { 31 | if (grainyBlurMat == null) return; 32 | if (!renderingData.cameraData.postProcessEnabled) return; 33 | var stack = VolumeManager.instance.stack; 34 | _grainyBlur = stack.GetComponent(); 35 | if (_grainyBlur == null) return; 36 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 37 | Render(cmd, ref renderingData); 38 | context.ExecuteCommandBuffer(cmd); 39 | CommandBufferPool.Release(cmd); 40 | } 41 | 42 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 43 | { 44 | if (_grainyBlur.IsActive()) 45 | { 46 | var source = currentTarget; 47 | Camera camera = renderingData.cameraData.camera; 48 | 49 | cmd.BeginSample(PROFILER_TAG); 50 | 51 | int RTWidth = (int) (camera.pixelWidth / _grainyBlur.RTDownScaling.value); 52 | int RTHeight = (int) (camera.pixelHeight / _grainyBlur.RTDownScaling.value); 53 | cmd.GetTemporaryRT(BufferRT, RTWidth, RTHeight, 0, FilterMode.Bilinear); 54 | // downsample screen copy into smaller RT 55 | cmd.Blit(source, BufferRT); 56 | 57 | grainyBlurMat.SetVector(Params, 58 | new Vector2(_grainyBlur.BlurRadius.value / camera.pixelHeight, _grainyBlur.Iteration.value)); 59 | 60 | cmd.Blit(BufferRT, source, grainyBlurMat, 0); 61 | 62 | cmd.ReleaseTemporaryRT(BufferRT); 63 | cmd.EndSample(PROFILER_TAG); 64 | } 65 | } 66 | 67 | public void Setup(in RenderTargetIdentifier currentTarget) 68 | { 69 | this.currentTarget = currentTarget; 70 | } 71 | 72 | public override void FrameCleanup(CommandBuffer cmd) 73 | { 74 | base.FrameCleanup(cmd); 75 | } 76 | } 77 | 78 | private GrainyBlurPass _grainyBlurPass; 79 | 80 | public override void Create() 81 | { 82 | _grainyBlurPass = new GrainyBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 83 | } 84 | 85 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 86 | { 87 | _grainyBlurPass.Setup(renderer.cameraColorTarget); 88 | renderer.EnqueuePass(_grainyBlurPass); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Blur/GrainyBlur/GrainyBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c5b0d968fdef6045bcf133d24344591 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/IrisBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c190a3d64fb176a4f878029b2399c81d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | public enum IrisBlurQualityLevel 9 | { 10 | High_Quality = 0, 11 | Normal_Quality = 1, 12 | } 13 | 14 | [Serializable] 15 | public sealed class IrisBlurQualityLevelParameter : VolumeParameter { } 16 | 17 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/IrisBlur")] 18 | public class IrisBlur : VolumeComponent, IPostProcessComponent 19 | { 20 | public IrisBlurQualityLevelParameter QualityLevel = new IrisBlurQualityLevelParameter { value = IrisBlurQualityLevel.High_Quality }; 21 | 22 | public ClampedFloatParameter AreaSize = new ClampedFloatParameter (0.5f,0,1); 23 | 24 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,1); 25 | 26 | public ClampedIntParameter Iteration = new ClampedIntParameter (2,1,8); 27 | 28 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (1,1,2); 29 | 30 | public bool IsActive() 31 | { 32 | return BlurRadius.value > 0; 33 | } 34 | 35 | public bool IsTileCompatible() 36 | { 37 | return false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 226316d83b0bee241988dfc3952c4812 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/IrisBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | TEXTURE2D (_BlurredTex); 12 | SAMPLER(sampler_BlurredTex); 13 | TEXTURE2D (_MainTex); 14 | SAMPLER(sampler_MainTex); 15 | float4 _BlurredTex_TexelSize; 16 | half2 _Params; 17 | 18 | #define _BluSize _Params.x 19 | #define _BlurRadius _Params.y 20 | 21 | struct appdata 22 | { 23 | float4 vertex: POSITION; 24 | float2 uv: TEXCOORD0; 25 | }; 26 | 27 | struct VaryingsDefault 28 | { 29 | float4 pos: SV_POSITION; 30 | float2 uv: TEXCOORD0; 31 | }; 32 | 33 | 34 | VaryingsDefault VertDefault(appdata v) 35 | { 36 | VaryingsDefault o; 37 | o.pos = TransformObjectToHClip(v.vertex.xyz); 38 | o.uv = v.uv; 39 | return o; 40 | } 41 | 42 | static const int DiscKernelSampleNum_LQ = 12; 43 | static const float2 DiscKernel_LQ[DiscKernelSampleNum_LQ] = 44 | { 45 | float2(-0.326212, -0.40581), 46 | float2(-0.840144, -0.07358), 47 | float2(-0.695914, 0.457137), 48 | float2(-0.203345, 0.620716), 49 | float2(0.96234, -0.194983), 50 | float2(0.473434, -0.480026), 51 | float2(0.519456, 0.767022), 52 | float2(0.185461, -0.893124), 53 | float2(0.507431, 0.064425), 54 | float2(0.89642, 0.412458), 55 | float2(-0.32194, -0.932615), 56 | float2(-0.791559, -0.59771) 57 | }; 58 | 59 | static const int DiscKernelSampleNum_HQ = 28; 60 | static const float3 DiscKernel_HQ[DiscKernelSampleNum_HQ] = 61 | { 62 | float3(0.62463, 0.54337, 0.82790), 63 | float3(-0.13414, -0.94488, 0.95435), 64 | float3(0.38772, -0.43475, 0.58253), 65 | float3(0.12126, -0.19282, 0.22778), 66 | float3(-0.20388, 0.11133, 0.23230), 67 | float3(0.83114, -0.29218, 0.88100), 68 | float3(0.10759, -0.57839, 0.58831), 69 | float3(0.28285, 0.79036, 0.83945), 70 | float3(-0.36622, 0.39516, 0.53876), 71 | float3(0.75591, 0.21916, 0.78704), 72 | float3(-0.52610, 0.02386, 0.52664), 73 | float3(-0.88216, -0.24471, 0.91547), 74 | float3(-0.48888, -0.29330, 0.57011), 75 | float3(0.44014, -0.08558, 0.44838), 76 | float3(0.21179, 0.51373, 0.55567), 77 | float3(0.05483, 0.95701, 0.95858), 78 | float3(-0.59001, -0.70509, 0.91938), 79 | float3(-0.80065, 0.24631, 0.83768), 80 | float3(-0.19424, -0.18402, 0.26757), 81 | float3(-0.43667, 0.76751, 0.88304), 82 | float3(0.21666, 0.11602, 0.24577), 83 | float3(0.15696, -0.85600, 0.87027), 84 | float3(-0.75821, 0.58363, 0.95682), 85 | float3(0.99284, -0.02904, 0.99327), 86 | float3(-0.22234, -0.57907, 0.62029), 87 | float3(0.55052, -0.66984, 0.86704), 88 | float3(0.46431, 0.28115, 0.54280), 89 | float3(-0.07214, 0.60554, 0.60982), 90 | }; 91 | 92 | 93 | float IrisMask(float2 uv) 94 | { 95 | float2 center = uv * 2 - 1; 96 | return dot(center, center) * (_BluSize * 0.001); 97 | } 98 | 99 | float4 FragIrisLQ(VaryingsDefault i): SV_Target 100 | { 101 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 102 | float3 sum = screenColor.rgb; 103 | 104 | float mask = IrisMask(i.uv.xy); 105 | 106 | float4 poissonScale = (_BlurRadius * 30) * mask; 107 | 108 | for (int l = 0; l < DiscKernelSampleNum_LQ; l ++) 109 | { 110 | float2 sampleUV = i.uv.xy + DiscKernel_LQ[l].xy * poissonScale.xy; 111 | float3 sample0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 112 | float3 sample1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 113 | 114 | sum += sample0 + sample1; 115 | } 116 | 117 | return float4(sum.rgb / (1.0 + 2.0 * DiscKernelSampleNum_LQ), mask); 118 | } 119 | 120 | float4 FragIrisHQ(VaryingsDefault i): SV_Target 121 | { 122 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 123 | float3 sum = screenColor.rgb; 124 | 125 | float mask = IrisMask(i.uv.xy); 126 | 127 | float4 poissonScale = (_BlurRadius * 30) * mask; 128 | 129 | for (int l = 0; l < DiscKernelSampleNum_HQ; l ++) 130 | { 131 | float2 sampleUV = i.uv.xy + DiscKernel_HQ[l].xy * poissonScale.xy; 132 | float3 sample0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 133 | float3 sample1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 134 | 135 | sum += sample0 + sample1; 136 | } 137 | 138 | return float4(sum.rgb / (1.0 + 2.0 * DiscKernelSampleNum_HQ), mask); 139 | } 140 | 141 | float4 FragBlend(VaryingsDefault i): SV_Target 142 | { 143 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 144 | float4 blurredColor = SAMPLE_TEXTURE2D(_BlurredTex, sampler_BlurredTex, i.uv); 145 | 146 | float3 result = lerp(blurredColor.rgb, screenColor.rgb, saturate(blurredColor.a)); 147 | 148 | return float4(result.rgb, screenColor.a); 149 | } 150 | 151 | 152 | ENDHLSL 153 | 154 | SubShader 155 | { 156 | Cull Off ZWrite Off ZTest Always 157 | 158 | //Pass 0 - Iris Blur High Quality 159 | Pass 160 | { 161 | HLSLPROGRAM 162 | 163 | #pragma vertex VertDefault 164 | #pragma fragment FragIrisHQ 165 | 166 | ENDHLSL 167 | 168 | } 169 | 170 | //Pass 1 - Iris Blur Low Quality 171 | Pass 172 | { 173 | HLSLPROGRAM 174 | 175 | #pragma vertex VertDefault 176 | #pragma fragment FragIrisLQ 177 | 178 | ENDHLSL 179 | 180 | } 181 | 182 | //Pass 2 - Blend 183 | Pass 184 | { 185 | HLSLPROGRAM 186 | 187 | #pragma vertex VertDefault 188 | #pragma fragment FragBlend 189 | 190 | ENDHLSL 191 | 192 | } 193 | } 194 | } 195 | 196 | 197 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46e81ccc88ff1f743a3dabf6f39c7afd 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class IrisBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class IrisBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int Params = Shader.PropertyToID("_Params"); 12 | internal static readonly int BlurredTex = Shader.PropertyToID("_BlurredTex"); 13 | internal static readonly int BufferRT1 = Shader.PropertyToID("_BufferRT1"); 14 | internal static readonly int BufferRT2 = Shader.PropertyToID("_BufferRT2"); 15 | 16 | private const string PROFILER_TAG = "IrisBlur"; 17 | RenderTargetIdentifier currentTarget; 18 | private IrisBlur _irisBlur; 19 | private Material _irisBlurMat; 20 | 21 | public IrisBlurPass(RenderPassEvent evet) 22 | { 23 | renderPassEvent = evet; 24 | Shader irisBlurShader=Shader.Find("Hidden/CustomPostEffect/IrisBlur"); 25 | if (irisBlurShader) 26 | { 27 | _irisBlurMat = CoreUtils.CreateEngineMaterial(irisBlurShader); 28 | } 29 | } 30 | 31 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 32 | { 33 | if (_irisBlurMat == null) return; 34 | if (!renderingData.cameraData.postProcessEnabled) return; 35 | var stack = VolumeManager.instance.stack; 36 | _irisBlur = stack.GetComponent(); 37 | if (_irisBlur == null) return; 38 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 39 | Render(cmd, ref renderingData); 40 | context.ExecuteCommandBuffer(cmd); 41 | CommandBufferPool.Release(cmd); 42 | } 43 | 44 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 45 | { 46 | if (_irisBlur.IsActive()) 47 | { 48 | var source = currentTarget; 49 | Camera camera = renderingData.cameraData.camera; 50 | 51 | cmd.BeginSample(PROFILER_TAG); 52 | 53 | if (_irisBlur.Iteration.value ==1) 54 | { 55 | // Get RT 56 | int RTWidth = (int)(camera.pixelWidth / _irisBlur.RTDownScaling.value); 57 | int RTHeight = (int)(camera.pixelHeight / _irisBlur.RTDownScaling.value); 58 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 59 | 60 | // Set Property 61 | _irisBlurMat.SetVector(Params, new Vector4(_irisBlur.AreaSize.value, _irisBlur.BlurRadius.value)); 62 | 63 | // Do Blit 64 | cmd.Blit(source, BufferRT1, _irisBlurMat, (int)_irisBlur.QualityLevel.value); 65 | 66 | // Final Blit 67 | cmd.SetGlobalTexture(BlurredTex, BufferRT1); 68 | cmd.Blit(BufferRT1, source, _irisBlurMat, 2); 69 | 70 | // Release 71 | cmd.ReleaseTemporaryRT(BufferRT1); 72 | } 73 | else 74 | { 75 | // Get RT 76 | int RTWidth = (int)(camera.pixelWidth / _irisBlur.RTDownScaling.value); 77 | int RTHeight = (int)(camera.pixelHeight / _irisBlur.RTDownScaling.value); 78 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 79 | cmd.GetTemporaryRT(BufferRT2, RTWidth, RTHeight, 0, FilterMode.Bilinear); 80 | 81 | // Set Property 82 | _irisBlurMat.SetVector(Params,new Vector2(_irisBlur.AreaSize.value, _irisBlur.BlurRadius.value)); 83 | 84 | RenderTargetIdentifier finalBlurID = BufferRT1; 85 | RenderTargetIdentifier firstID = source; 86 | RenderTargetIdentifier secondID = BufferRT1; 87 | for (int i = 0; i < _irisBlur.Iteration.value; i++) 88 | { 89 | // Do Blit 90 | cmd.Blit(firstID, secondID, _irisBlurMat, (int)_irisBlur.QualityLevel.value); 91 | 92 | finalBlurID = secondID; 93 | firstID = secondID; 94 | secondID = (secondID == BufferRT1) ? BufferRT2 : BufferRT1; 95 | } 96 | 97 | // Final Blit 98 | cmd.SetGlobalTexture(BlurredTex, finalBlurID); 99 | cmd.Blit(BlurredTex, source, _irisBlurMat, 2); 100 | 101 | // Release 102 | cmd.ReleaseTemporaryRT(BufferRT1); 103 | cmd.ReleaseTemporaryRT(BufferRT2); 104 | } 105 | 106 | cmd.EndSample(PROFILER_TAG); 107 | } 108 | } 109 | 110 | public void Setup(in RenderTargetIdentifier currentTarget) 111 | { 112 | this.currentTarget = currentTarget; 113 | } 114 | 115 | public override void FrameCleanup(CommandBuffer cmd) 116 | { 117 | base.FrameCleanup(cmd); 118 | } 119 | } 120 | 121 | private IrisBlurPass _irisBlurPass; 122 | 123 | public override void Create() 124 | { 125 | _irisBlurPass = new IrisBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 126 | } 127 | 128 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 129 | { 130 | _irisBlurPass.Setup(renderer.cameraColorTarget); 131 | renderer.EnqueuePass(_irisBlurPass); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Blur/IrisBlur/IrisBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 610e7d8898457e94c9141c570c6e5188 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/KawaseBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bba54b0e9a380ef428a44b1919f82d49 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/KawaseBlur")] 9 | public class KawaseBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,5); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (6,1,10); 14 | 15 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (2,1,8); 16 | 17 | public bool IsActive() 18 | { 19 | return BlurRadius.value > 0; 20 | } 21 | 22 | public bool IsTileCompatible() 23 | { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82b14624a0d7e3046b4e550dd744e9d8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/KawaseBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | struct appdata 12 | { 13 | float4 vertex: POSITION; 14 | float2 uv: TEXCOORD0; 15 | }; 16 | 17 | struct VaryingsDefault 18 | { 19 | float4 pos: SV_POSITION; 20 | float2 uv: TEXCOORD0; 21 | }; 22 | 23 | VaryingsDefault VertDefault(appdata v) 24 | { 25 | VaryingsDefault o; 26 | o.pos = TransformObjectToHClip(v.vertex.xyz); 27 | o.uv = v.uv; 28 | return o; 29 | } 30 | 31 | uniform half _Offset; 32 | 33 | sampler2D _MainTex; 34 | float4 _MainTex_TexelSize; 35 | 36 | half4 KawaseBlur(sampler2D tex, float2 uv, float2 texelSize, half pixelOffset) 37 | { 38 | half4 o = 0; 39 | o += tex2D(tex, uv + float2(pixelOffset +0.5, pixelOffset +0.5) * texelSize); 40 | o += tex2D(tex, uv + float2(-pixelOffset -0.5, pixelOffset +0.5) * texelSize); 41 | o += tex2D(tex, uv + float2(-pixelOffset -0.5, -pixelOffset -0.5) * texelSize); 42 | o += tex2D(tex, uv + float2(pixelOffset +0.5, -pixelOffset -0.5) * texelSize); 43 | return o * 0.25; 44 | } 45 | 46 | half4 Frag(VaryingsDefault i): SV_Target 47 | { 48 | return KawaseBlur(_MainTex, i.uv, _MainTex_TexelSize.xy, _Offset); 49 | } 50 | 51 | ENDHLSL 52 | 53 | SubShader 54 | { 55 | Cull Off ZWrite Off ZTest Always 56 | 57 | Pass 58 | { 59 | HLSLPROGRAM 60 | 61 | #pragma vertex VertDefault 62 | #pragma fragment Frag 63 | 64 | ENDHLSL 65 | 66 | } 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d1835bd65afc49409eae03b7ee8308f 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class KawaseBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class KawaseBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int BlurRadius = Shader.PropertyToID("_Offset"); 12 | internal static readonly int BufferRT1 = Shader.PropertyToID("_BufferRT1"); 13 | internal static readonly int BufferRT2 = Shader.PropertyToID("_BufferRT2"); 14 | 15 | private const string PROFILER_TAG = "KawaseBlur"; 16 | 17 | private Material kawaseBlurMat; 18 | private KawaseBlur _kawaseBlur; 19 | RenderTargetIdentifier currentTarget; 20 | 21 | public KawaseBlurPass(RenderPassEvent evet) 22 | { 23 | renderPassEvent = evet; 24 | Shader KkwaseBlurShader = Shader.Find("Hidden/CustomPostEffect/KawaseBlur"); 25 | if (KkwaseBlurShader) 26 | { 27 | kawaseBlurMat = CoreUtils.CreateEngineMaterial(KkwaseBlurShader); 28 | } 29 | } 30 | 31 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 32 | { 33 | if (kawaseBlurMat == null) return; 34 | if (!renderingData.cameraData.postProcessEnabled) return; 35 | var stack = VolumeManager.instance.stack; 36 | _kawaseBlur = stack.GetComponent(); 37 | if (_kawaseBlur == null) return; 38 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 39 | Render(cmd, ref renderingData); 40 | context.ExecuteCommandBuffer(cmd); 41 | CommandBufferPool.Release(cmd); 42 | } 43 | 44 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 45 | { 46 | if (_kawaseBlur.IsActive()) 47 | { 48 | var source = currentTarget; 49 | Camera camera = renderingData.cameraData.camera; 50 | cmd.BeginSample(PROFILER_TAG); 51 | 52 | 53 | int RTWidth = (int) (camera.pixelWidth / _kawaseBlur.RTDownScaling.value); 54 | int RTHeight = (int) (camera.pixelHeight / _kawaseBlur.RTDownScaling.value); 55 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 56 | cmd.GetTemporaryRT(BufferRT2, RTWidth, RTHeight, 0, FilterMode.Bilinear); 57 | 58 | cmd.Blit(source, BufferRT1); 59 | 60 | bool needSwitch = true; 61 | for (int i = 0; i < _kawaseBlur.Iteration.value; i++) 62 | { 63 | kawaseBlurMat.SetFloat(BlurRadius, 64 | i / _kawaseBlur.RTDownScaling.value + _kawaseBlur.BlurRadius.value); 65 | cmd.Blit(needSwitch ? BufferRT1 : BufferRT2, needSwitch ? BufferRT2 : BufferRT1, kawaseBlurMat, 0); 66 | needSwitch = !needSwitch; 67 | } 68 | 69 | 70 | kawaseBlurMat.SetFloat(BlurRadius, 71 | _kawaseBlur.Iteration.value / _kawaseBlur.RTDownScaling.value + _kawaseBlur.BlurRadius.value); 72 | cmd.Blit(needSwitch ? BufferRT1 : BufferRT2, source, kawaseBlurMat, 0); 73 | 74 | // release 75 | cmd.ReleaseTemporaryRT(BufferRT1); 76 | cmd.ReleaseTemporaryRT(BufferRT2); 77 | cmd.EndSample(PROFILER_TAG); 78 | } 79 | } 80 | 81 | public void Setup(in RenderTargetIdentifier currentTarget) 82 | { 83 | this.currentTarget = currentTarget; 84 | } 85 | 86 | public override void FrameCleanup(CommandBuffer cmd) 87 | { 88 | base.FrameCleanup(cmd); 89 | } 90 | } 91 | 92 | private KawaseBlurPass _kawaseBlurPass; 93 | 94 | public override void Create() 95 | { 96 | _kawaseBlurPass = new KawaseBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 97 | } 98 | 99 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 100 | { 101 | _kawaseBlurPass.Setup(renderer.cameraColorTarget); 102 | renderer.EnqueuePass(_kawaseBlurPass); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Blur/KawaseBlur/KawaseBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7dab3a07919dd5a4695c2869046eeaa1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/RadialBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6fa80d4dcff10e840aeef99d3f163295 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/RadialBlur")] 9 | public class RadialBlur : VolumeComponent, IPostProcessComponent 10 | { 11 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,1); 12 | 13 | public ClampedIntParameter Iteration = new ClampedIntParameter (10,2,30); 14 | 15 | public ClampedFloatParameter RadialCenterX = new ClampedFloatParameter (0.5f,0,1); 16 | 17 | public ClampedFloatParameter RadialCenterY = new ClampedFloatParameter (0.5f,0,1); 18 | 19 | public bool IsActive() 20 | { 21 | return BlurRadius.value > 0; 22 | } 23 | 24 | public bool IsTileCompatible() 25 | { 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5898f24c82fbc7f4d9bca122c99df1ae 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/RadialBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | uniform half4 _Params; 12 | 13 | #define _BlurRadius _Params.x 14 | #define _Iteration _Params.y 15 | #define _RadialCenter _Params.zw 16 | 17 | TEXTURE2D (_MainTex); 18 | SAMPLER(sampler_MainTex); 19 | 20 | struct appdata 21 | { 22 | float4 vertex: POSITION; 23 | float2 uv: TEXCOORD0; 24 | }; 25 | 26 | struct VaryingsDefault 27 | { 28 | float4 pos: SV_POSITION; 29 | float2 uv: TEXCOORD0; 30 | }; 31 | 32 | VaryingsDefault VertDefault(appdata v) 33 | { 34 | VaryingsDefault o; 35 | o.pos = TransformObjectToHClip(v.vertex.xyz); 36 | o.uv = v.uv; 37 | return o; 38 | } 39 | 40 | half4 RadialBlur(VaryingsDefault i) 41 | { 42 | float2 blurVector = (_RadialCenter - i.uv.xy) * _BlurRadius; 43 | 44 | half4 acumulateColor = half4(0, 0, 0, 0); 45 | 46 | [unroll(30)] 47 | for (int j = 0; j < _Iteration; j ++) 48 | { 49 | acumulateColor += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 50 | i.uv.xy += blurVector; 51 | } 52 | 53 | return acumulateColor / _Iteration; 54 | } 55 | 56 | half4 Frag(VaryingsDefault i): SV_Target 57 | { 58 | return RadialBlur(i); 59 | } 60 | 61 | ENDHLSL 62 | 63 | SubShader 64 | { 65 | Cull Off ZWrite Off ZTest Always 66 | 67 | Pass 68 | { 69 | HLSLPROGRAM 70 | 71 | #pragma vertex VertDefault 72 | #pragma fragment Frag 73 | 74 | ENDHLSL 75 | } 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6dbb2a3db4979e44fbfc4f26cdaaf8b7 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class RadialBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class RadialBlurPass :ScriptableRenderPass 10 | { 11 | internal static readonly int Params = Shader.PropertyToID("_Params"); 12 | internal static readonly int TempID = Shader.PropertyToID("_Temp"); 13 | private const string PROFILER_TAG = "RadialBlur"; 14 | private Material radialBlurMat; 15 | private RadialBlur radialBlur; 16 | RenderTargetIdentifier currentTarget; 17 | 18 | public RadialBlurPass(RenderPassEvent evet) 19 | { 20 | renderPassEvent = evet; 21 | Shader radialBlurShader=Shader.Find("Hidden/CustomPostEffect/RadialBlur"); 22 | if (radialBlurShader) 23 | { 24 | radialBlurMat = CoreUtils.CreateEngineMaterial(radialBlurShader); 25 | } 26 | } 27 | 28 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 29 | { 30 | if (radialBlurMat == null) return; 31 | if (!renderingData.cameraData.postProcessEnabled) return; 32 | var stack = VolumeManager.instance.stack; 33 | radialBlur = stack.GetComponent(); 34 | if (radialBlur == null) return; 35 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 36 | Render(cmd, ref renderingData); 37 | context.ExecuteCommandBuffer(cmd); 38 | CommandBufferPool.Release(cmd); 39 | } 40 | 41 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 42 | { 43 | if (radialBlur.IsActive()) 44 | { 45 | var source = currentTarget; 46 | Camera camera = renderingData.cameraData.camera; 47 | cmd.BeginSample(PROFILER_TAG); 48 | cmd.GetTemporaryRT(TempID,camera.pixelWidth,camera.pixelHeight,0,FilterMode.Bilinear); 49 | cmd.Blit(source,TempID); 50 | radialBlurMat.SetVector(Params , new Vector4(radialBlur.BlurRadius.value * 0.02f, radialBlur.Iteration.value, radialBlur.RadialCenterX.value, radialBlur.RadialCenterY.value)); 51 | cmd.Blit(TempID, source, radialBlurMat, 0); 52 | cmd.EndSample(PROFILER_TAG); 53 | } 54 | } 55 | 56 | public void Setup(in RenderTargetIdentifier currentTarget) 57 | { 58 | this.currentTarget = currentTarget; 59 | } 60 | 61 | public override void FrameCleanup(CommandBuffer cmd) 62 | { 63 | base.FrameCleanup(cmd); 64 | } 65 | } 66 | 67 | private RadialBlurPass _RadialBlurPass; 68 | 69 | public override void Create() 70 | { 71 | _RadialBlurPass = new RadialBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 72 | } 73 | 74 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 75 | { 76 | _RadialBlurPass.Setup(renderer.cameraColorTarget); 77 | renderer.EnqueuePass(_RadialBlurPass); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Blur/RadialBlur/RadialBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0fb8697ce57e18b41957527686c10515 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0936d6d665c5df440ac17ca3d4666d49 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlur.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using UnityEngine.Rendering.Universal; 7 | 8 | public enum TiltShiftBlurQualityLevel 9 | { 10 | High_Quality = 0, 11 | Normal_Quality = 1, 12 | } 13 | 14 | [Serializable] 15 | public sealed class TiltShiftBlurQualityLevelParameter : VolumeParameter { } 16 | 17 | [Serializable,VolumeComponentMenu("CustomPostprocess/Blur/TiltShiftBlur")] 18 | public class TiltShiftBlur : VolumeComponent, IPostProcessComponent 19 | { 20 | public TiltShiftBlurQualityLevelParameter QualityLevel = new TiltShiftBlurQualityLevelParameter { value = TiltShiftBlurQualityLevel.High_Quality }; 21 | 22 | public ClampedFloatParameter AreaSize = new ClampedFloatParameter (0.5f,0,1); 23 | 24 | public ClampedFloatParameter BlurRadius = new ClampedFloatParameter (0,0,1); 25 | 26 | public ClampedIntParameter Iteration = new ClampedIntParameter (2,1,8); 27 | 28 | public ClampedFloatParameter RTDownScaling = new ClampedFloatParameter (1,1,2); 29 | 30 | public bool IsActive() 31 | { 32 | return BlurRadius.value > 0; 33 | } 34 | 35 | public bool IsTileCompatible() 36 | { 37 | return false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlur.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 020cea735ba7b8b4ba0bc7ca83e74f54 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlur.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomPostEffect/TiltShiftBlur" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" { } 6 | } 7 | HLSLINCLUDE 8 | 9 | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 10 | 11 | float4 _BlurredTex_TexelSize; 12 | half2 _Params; 13 | 14 | #define _BlurSize _Params.x 15 | #define _BlurRadius _Params.y 16 | 17 | TEXTURE2D (_MainTex); 18 | SAMPLER(sampler_MainTex); 19 | TEXTURE2D (_BlurredTex); 20 | SAMPLER(sampler_BlurredTex); 21 | 22 | struct appdata 23 | { 24 | float4 vertex: POSITION; 25 | float2 uv: TEXCOORD0; 26 | }; 27 | 28 | struct VaryingsDefault 29 | { 30 | float4 pos: SV_POSITION; 31 | float2 uv: TEXCOORD0; 32 | }; 33 | 34 | VaryingsDefault VertDefault(appdata v) 35 | { 36 | VaryingsDefault o; 37 | o.pos = TransformObjectToHClip(v.vertex.xyz); 38 | o.uv = v.uv; 39 | return o; 40 | } 41 | 42 | static const int DiscKernelSampleNum_LQ = 12; 43 | static const float2 DiscKernel_LQ[DiscKernelSampleNum_LQ] = 44 | { 45 | float2(-0.326212, -0.40581), 46 | float2(-0.840144, -0.07358), 47 | float2(-0.695914, 0.457137), 48 | float2(-0.203345, 0.620716), 49 | float2(0.96234, -0.194983), 50 | float2(0.473434, -0.480026), 51 | float2(0.519456, 0.767022), 52 | float2(0.185461, -0.893124), 53 | float2(0.507431, 0.064425), 54 | float2(0.89642, 0.412458), 55 | float2(-0.32194, -0.932615), 56 | float2(-0.791559, -0.59771) 57 | }; 58 | 59 | static const int DiscKernelSampleNum_HQ = 28; 60 | static const float3 DiscKernel_HQ[DiscKernelSampleNum_HQ] = 61 | { 62 | float3(0.62463, 0.54337, 0.82790), 63 | float3(-0.13414, -0.94488, 0.95435), 64 | float3(0.38772, -0.43475, 0.58253), 65 | float3(0.12126, -0.19282, 0.22778), 66 | float3(-0.20388, 0.11133, 0.23230), 67 | float3(0.83114, -0.29218, 0.88100), 68 | float3(0.10759, -0.57839, 0.58831), 69 | float3(0.28285, 0.79036, 0.83945), 70 | float3(-0.36622, 0.39516, 0.53876), 71 | float3(0.75591, 0.21916, 0.78704), 72 | float3(-0.52610, 0.02386, 0.52664), 73 | float3(-0.88216, -0.24471, 0.91547), 74 | float3(-0.48888, -0.29330, 0.57011), 75 | float3(0.44014, -0.08558, 0.44838), 76 | float3(0.21179, 0.51373, 0.55567), 77 | float3(0.05483, 0.95701, 0.95858), 78 | float3(-0.59001, -0.70509, 0.91938), 79 | float3(-0.80065, 0.24631, 0.83768), 80 | float3(-0.19424, -0.18402, 0.26757), 81 | float3(-0.43667, 0.76751, 0.88304), 82 | float3(0.21666, 0.11602, 0.24577), 83 | float3(0.15696, -0.85600, 0.87027), 84 | float3(-0.75821, 0.58363, 0.95682), 85 | float3(0.99284, -0.02904, 0.99327), 86 | float3(-0.22234, -0.57907, 0.62029), 87 | float3(0.55052, -0.66984, 0.86704), 88 | float3(0.46431, 0.28115, 0.54280), 89 | float3(-0.07214, 0.60554, 0.60982), 90 | }; 91 | 92 | 93 | float TiltShiftMask(float2 uv) 94 | { 95 | float centerY = uv.y * 2.0 - 1.0; 96 | return(abs(centerY * _BlurSize * 0.001)); 97 | } 98 | 99 | float4 FragTiltShiftLQ(VaryingsDefault i): SV_Target 100 | { 101 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 102 | float3 sum = screenColor.rgb; 103 | 104 | float mask = TiltShiftMask(i.uv.xy); 105 | 106 | float4 poissonScale = (_BlurRadius * 30) * mask; 107 | 108 | for (int l = 0; l < DiscKernelSampleNum_LQ; l ++) 109 | { 110 | float2 sampleUV = i.uv.xy + DiscKernel_LQ[l].xy * poissonScale.xy; 111 | float3 sample0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 112 | float3 sample1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 113 | 114 | sum += sample0 + sample1; 115 | } 116 | 117 | return float4(sum.rgb / (1.0 + 2.0 * DiscKernelSampleNum_LQ), mask); 118 | } 119 | 120 | float4 FragTiltShiftHQ(VaryingsDefault i): SV_Target 121 | { 122 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 123 | float3 sum = screenColor.rgb; 124 | 125 | float mask = TiltShiftMask(i.uv.xy); 126 | float4 poissonScale = (_BlurRadius * 30) * mask; 127 | 128 | for (int l = 0; l < DiscKernelSampleNum_HQ; l ++) 129 | { 130 | float2 sampleUV = i.uv.xy + DiscKernel_HQ[l].xy * poissonScale.xy; 131 | float3 sample0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 132 | float3 sample1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, sampleUV.xy).rgb; 133 | 134 | sum += sample0 + sample1; 135 | } 136 | return float4(sum.rgb / (1.0 + 2.0 * DiscKernelSampleNum_HQ), mask); 137 | } 138 | 139 | float4 FragBlend(VaryingsDefault i): SV_Target 140 | { 141 | float4 screenColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); 142 | float4 blurredColor = SAMPLE_TEXTURE2D(_BlurredTex, sampler_BlurredTex, i.uv); 143 | 144 | float3 result = lerp(blurredColor.rgb, screenColor.rgb, saturate(blurredColor.a)); 145 | 146 | return float4(result.rgb, screenColor.a); 147 | } 148 | 149 | 150 | ENDHLSL 151 | 152 | SubShader 153 | { 154 | Cull Off ZWrite Off ZTest Always 155 | 156 | //Pass 0 - Tilt Shift Blur High Quality 157 | Pass 158 | { 159 | HLSLPROGRAM 160 | 161 | #pragma vertex VertDefault 162 | #pragma fragment FragTiltShiftHQ 163 | 164 | ENDHLSL 165 | 166 | } 167 | 168 | //Pass 1 - Tilt Shift Blur Low Quality 169 | Pass 170 | { 171 | HLSLPROGRAM 172 | 173 | #pragma vertex VertDefault 174 | #pragma fragment FragTiltShiftLQ 175 | 176 | ENDHLSL 177 | 178 | } 179 | 180 | //Pass 2 - Blend 181 | Pass 182 | { 183 | HLSLPROGRAM 184 | 185 | #pragma vertex VertDefault 186 | #pragma fragment FragBlend 187 | 188 | ENDHLSL 189 | 190 | } 191 | } 192 | } 193 | 194 | 195 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlur.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 45d769914e192a449a3a7fc01f8f73fa 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | preprocessorOverride: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlurRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.Universal; 6 | 7 | public class TiltShiftBlurRenderFeature : ScriptableRendererFeature 8 | { 9 | public class TiltShiftBlurPass : ScriptableRenderPass 10 | { 11 | internal static readonly int Params = Shader.PropertyToID("_Params"); 12 | internal static readonly int BlurredTex = Shader.PropertyToID("_BlurredTex"); 13 | internal static readonly int BufferRT1 = Shader.PropertyToID("_BufferRT1"); 14 | internal static readonly int BufferRT2 = Shader.PropertyToID("_BufferRT2"); 15 | 16 | private const string PROFILER_TAG = "TiltShiftBlur"; 17 | private Material tiltShiftBlurMat; 18 | private TiltShiftBlur tiltShiftBlur; 19 | RenderTargetIdentifier currentTarget; 20 | 21 | public TiltShiftBlurPass(RenderPassEvent evet) 22 | { 23 | renderPassEvent = evet; 24 | Shader tiltShiftBlurShader=Shader.Find("Hidden/CustomPostEffect/TiltShiftBlur"); 25 | if (tiltShiftBlurShader) 26 | { 27 | tiltShiftBlurMat = CoreUtils.CreateEngineMaterial(tiltShiftBlurShader); 28 | } 29 | } 30 | 31 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 32 | { 33 | if (tiltShiftBlurMat == null) return; 34 | if (!renderingData.cameraData.postProcessEnabled) return; 35 | var stack = VolumeManager.instance.stack; 36 | tiltShiftBlur = stack.GetComponent(); 37 | if (tiltShiftBlur == null) return; 38 | var cmd = CommandBufferPool.Get(PROFILER_TAG); 39 | Render(cmd, ref renderingData); 40 | context.ExecuteCommandBuffer(cmd); 41 | CommandBufferPool.Release(cmd); 42 | } 43 | 44 | private void Render(CommandBuffer cmd, ref RenderingData renderingData) 45 | { 46 | if (tiltShiftBlur.IsActive()) 47 | { 48 | var source = currentTarget; 49 | Camera camera = renderingData.cameraData.camera; 50 | cmd.BeginSample(PROFILER_TAG); 51 | 52 | if (tiltShiftBlur.Iteration.value == 1) 53 | { 54 | // Get RT 55 | int RTWidth = (int)(camera.pixelWidth / tiltShiftBlur.RTDownScaling.value); 56 | int RTHeight = (int)(camera.pixelHeight / tiltShiftBlur.RTDownScaling.value); 57 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 58 | // Set Property 59 | tiltShiftBlurMat.SetVector(Params, new Vector2(tiltShiftBlur.AreaSize.value, tiltShiftBlur.BlurRadius.value)); 60 | 61 | // Do Blit 62 | cmd.Blit(source, BufferRT1, tiltShiftBlurMat, (int)tiltShiftBlur.QualityLevel.value); 63 | 64 | // Final Blit 65 | cmd.SetGlobalTexture(BlurredTex, BufferRT1); 66 | cmd.Blit(BufferRT1, source, tiltShiftBlurMat, 2); 67 | 68 | // Release 69 | cmd.ReleaseTemporaryRT(BufferRT1); 70 | } 71 | else 72 | { 73 | // Get RT 74 | int RTWidth = (int)(camera.pixelWidth / tiltShiftBlur.RTDownScaling.value); 75 | int RTHeight = (int)(camera.pixelHeight / tiltShiftBlur.RTDownScaling.value); 76 | cmd.GetTemporaryRT(BufferRT1, RTWidth, RTHeight, 0, FilterMode.Bilinear); 77 | cmd.GetTemporaryRT(BufferRT2, RTWidth, RTHeight, 0, FilterMode.Bilinear); 78 | 79 | // Set Property 80 | tiltShiftBlurMat.SetVector(Params, new Vector2(tiltShiftBlur.AreaSize.value, tiltShiftBlur.BlurRadius.value)); 81 | 82 | RenderTargetIdentifier finalBlurID = BufferRT1; 83 | RenderTargetIdentifier firstID = source; 84 | RenderTargetIdentifier secondID = BufferRT1; 85 | for (int i = 0; i < tiltShiftBlur.Iteration.value; i++) 86 | { 87 | // Do Blit 88 | cmd.Blit(firstID, secondID, tiltShiftBlurMat, (int)tiltShiftBlur.QualityLevel.value); 89 | 90 | finalBlurID = secondID; 91 | firstID = secondID; 92 | secondID = (secondID == BufferRT1) ? BufferRT2 : BufferRT1; 93 | } 94 | 95 | // Final Blit 96 | cmd.SetGlobalTexture(BlurredTex, finalBlurID); 97 | cmd.Blit(finalBlurID,source, tiltShiftBlurMat, 2); 98 | 99 | // Release 100 | cmd.ReleaseTemporaryRT(BufferRT1); 101 | cmd.ReleaseTemporaryRT(BufferRT2); 102 | } 103 | 104 | cmd.EndSample(PROFILER_TAG); 105 | } 106 | } 107 | 108 | public void Setup(in RenderTargetIdentifier currentTarget) 109 | { 110 | this.currentTarget = currentTarget; 111 | } 112 | 113 | public override void FrameCleanup(CommandBuffer cmd) 114 | { 115 | base.FrameCleanup(cmd); 116 | } 117 | } 118 | 119 | private TiltShiftBlurPass _tiltShiftBlurPass; 120 | 121 | public override void Create() 122 | { 123 | _tiltShiftBlurPass = new TiltShiftBlurPass(RenderPassEvent.BeforeRenderingPostProcessing); 124 | } 125 | 126 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 127 | { 128 | _tiltShiftBlurPass.Setup(renderer.cameraColorTarget); 129 | renderer.EnqueuePass(_tiltShiftBlurPass); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Blur/TiltShiftBlur/TiltShiftBlurRenderFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4edbdb62aabd7f84dae5cbc362979e7b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityURPBlur 2 | Blur Basic Unity URP 3 | --------------------------------------------------------------------------------