
Shader "PostProcessing/GaussianBlurFullScreen"{ Properties { [HideInInspector] _MainTex ("Texture", 2D) = "white" {}
[HideInInspector] _Spread ("Spread", Float) = 0
[HideInInspector] _GridSize ("Grid Size", Integer) = 0 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" }
HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#define E 2.71828f
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
CBUFFER_START(UnityPerMaterial) float4 _MainTex_TexelSize; uint _Grid; float _Spread; CBUFFER_END
struct appdata { float4 positionOS : POSITION; float2 uv : TEXCOORD0; };
struct interpolators { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; };
float gaussian(const int param) { const float sigma_sqr = _Spread * _Spread; return (1 / sqrt(TWO_PI * sigma_sqr) * pow(E, -(param * param) / (2 * sigma_sqr))); }
interpolators vert(appdata v) { interpolators o; o.positionCS = TransformObjectToHClip(v.positionOS.xyz); o.uv = v.uv; return o; }
float4 frag_horizontal(const interpolators input) : SV_Target { float3 col = 0; float grid_sum = 0.0f;
// how many pixels are there left / right of this fragment const int upper = (_Grid - 1) / 2; const int lower = -upper;
for (int x = lower; x <= upper; ++x) { const float g = gaussian(x); const float2 uv_offset_x = float2(input.uv.x + _MainTex_TexelSize.x * x, input.uv.y); grid_sum += g; col += g * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv_offset_x).xyz; } col /= grid_sum; return float4(col, 1); }
float4 frag_vertical(const interpolators input) : SV_Target { float3 col = 0; float grid_sum = 0.0f;
// how many pixels are there up / down of this fragment const int upper = (_Grid - 1) / 2; const int lower = -upper;
for (int y = lower; y <= upper; ++y) { const float g = gaussian(y); const float2 uv_offset_y = float2(input.uv.x, input.uv.y + _MainTex_TexelSize.y * y); grid_sum += g; col += g * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv_offset_y).xyz; } col /= grid_sum; return float4(col, 1); } ENDHLSL
Pass { Name "Horizontal"
HLSLPROGRAM #pragma vertex vert; #pragma fragment frag_horizontal; ENDHLSL }
Pass { Name "Vertical"
HLSLPROGRAM #pragma vertex vert; #pragma fragment frag_vertical; ENDHLSL } }}
xxxxxxxxxxusing UnityEngine;using UnityEngine.Rendering;using UnityEngine.Rendering.Universal;
public class BlurRenderPass : ScriptableRenderPass{ private Material _material; private BlurPostProcessSettings _blurPostProcessSettings; private RenderTargetIdentifier _source; private RenderTargetHandle _blurTexture; private int _blurTextureID; private static readonly int GridSize = Shader.PropertyToID("_Grid"); private static readonly int Spread = Shader.PropertyToID("_Spread");
public bool Setup(ScriptableRenderer renderer) { _source = renderer.cameraColorTarget; _blurPostProcessSettings = VolumeManager.instance.stack.GetComponent<BlurPostProcessSettings>(); renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
if (_blurPostProcessSettings != null && _blurPostProcessSettings.IsActive()) { _material = new Material(Shader.Find("PostProcessing/GaussianBlurFullScreen")); return true; }
return false; }
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTexDesc) { if (_blurPostProcessSettings == null || !_blurPostProcessSettings.IsActive()) return;
_blurTextureID = Shader.PropertyToID("_TemporaryBlurTextureID"); _blurTexture = new RenderTargetHandle(); _blurTexture.id = _blurTextureID; cmd.GetTemporaryRT(_blurTexture.id, cameraTexDesc); base.Configure(cmd, cameraTexDesc); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (_blurPostProcessSettings == null || !_blurPostProcessSettings.IsActive()) return;
CommandBuffer cmd = CommandBufferPool.Get("Blur Post Process"); int gridSize = Mathf.CeilToInt(_blurPostProcessSettings.GetBlurValue()); if (gridSize % 2 == 0) { gridSize++; } _material.SetInteger(GridSize, gridSize); _material.SetFloat(Spread, _blurPostProcessSettings.GetBlurValue()); cmd.Blit(_source, _blurTexture.id, _material, 0); cmd.Blit(_blurTexture.id, _source, _material, 1); context.ExecuteCommandBuffer(cmd); cmd.Clear(); CommandBufferPool.Release(cmd); }
public override void FrameCleanup(CommandBuffer cmd) { cmd.ReleaseTemporaryRT(_blurTextureID); base.FrameCleanup(cmd); }}xxxxxxxxxxusing UnityEngine.Rendering.Universal;
public class BlurRendererFeature : ScriptableRendererFeature{ private BlurRenderPass _renderPass; public override void Create() { _renderPass = new BlurRenderPass(); name = "Blur"; }
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { if (_renderPass.Setup(renderer)) { renderer.EnqueuePass(_renderPass); } }}using UnityEngine;using UnityEngine.Rendering;using UnityEngine.Rendering.Universal;
[System.Serializable, VolumeComponentMenu("Gaussian Blur")]public class BlurPostProcessSettings : VolumeComponent, IPostProcessComponent{ [Tooltip("Standard Deviation (spread) of the blur. Grid size is approx. 3x larger.")] [SerializeField] private ClampedFloatParameter strength = new(0.0f, MinStrength, MaxStrength);
private const float MinStrength = 0.001f; private const float MaxStrength = 15.0f; public bool IsActive() { return strength.value > MinStrength && active; }
public bool IsTileCompatible() { return false; }
public void SetBlurStrength(float str) { strength.SetValue(new FloatParameter(Mathf.Clamp(str, MinStrength, MaxStrength))); strength.SetValue(new FloatParameter(str)); } public float GetBlurValue() { return strength.value * 6.0f; }}
How To Install
This package uses the [scoped registry] feature to resolve package dependencies. Open the Package Manager page in the Project Settings window and add the following entry to the Scoped Registries list:



Name: Enter any name here
URL: https://registry.npmjs.com
Scope: com.femiroglu


Now you can install the package from My Registries page in the Package Manager window.