-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
using UnityEngine; | ||
using UnityEngine.Profiling; | ||
using UnityEngine.Rendering; | ||
|
||
namespace CompositeCanvas | ||
{ | ||
public class CompositeCanvasBlur : CompositeCanvasEffect | ||
{ | ||
[Header("Blur Settings")] | ||
[Range(0, 1)] | ||
[SerializeField] | ||
private float m_Blur = 0.5f; | ||
|
||
[Range(1, 10)] | ||
[SerializeField] | ||
private int m_Iteration = 3; | ||
|
||
[Range(0.05f, 3f)] | ||
[SerializeField] | ||
private float m_Power = 1f; | ||
|
||
[Range(0.05f, 3f)] | ||
[SerializeField] | ||
private float m_Multiplier = 1; | ||
|
||
[Range(0, 1)] | ||
[SerializeField] | ||
private float m_Limit = 1; | ||
|
||
private Material _material; | ||
|
||
public float blur | ||
{ | ||
get => m_Blur; | ||
set | ||
{ | ||
value = Mathf.Clamp01(value); | ||
if (Mathf.Approximately(m_Blur, value)) return; | ||
|
||
m_Blur = value; | ||
SetRendererDirty(); | ||
} | ||
} | ||
|
||
public int iteration | ||
{ | ||
get => m_Iteration; | ||
set | ||
{ | ||
value = Mathf.Clamp(value, 1, 10); | ||
if (m_Iteration == value) return; | ||
|
||
m_Iteration = value; | ||
SetRendererDirty(); | ||
} | ||
} | ||
|
||
public float power | ||
{ | ||
get => m_Power; | ||
set | ||
{ | ||
value = Mathf.Clamp(value, 0.05f, 3f); | ||
if (Mathf.Approximately(m_Power, value)) return; | ||
|
||
m_Power = value; | ||
SetRendererDirty(); | ||
} | ||
} | ||
|
||
public float multiplier | ||
{ | ||
get => m_Multiplier; | ||
set | ||
{ | ||
value = Mathf.Clamp(value, 0.05f, 3f); | ||
if (Mathf.Approximately(m_Multiplier, value)) return; | ||
|
||
m_Multiplier = value; | ||
SetRendererDirty(); | ||
} | ||
} | ||
|
||
public virtual float innerCutoff | ||
{ | ||
get => 1f; | ||
set { } | ||
} | ||
|
||
public float limit | ||
{ | ||
get => m_Limit; | ||
set | ||
{ | ||
value = Mathf.Clamp01(value); | ||
if (Mathf.Approximately(m_Limit, value)) return; | ||
|
||
m_Limit = value; | ||
SetRendererDirty(); | ||
} | ||
} | ||
|
||
private bool useCutoffPass => !Mathf.Approximately(innerCutoff, 1) | ||
|| !Mathf.Approximately(power, 1) | ||
|| !Mathf.Approximately(multiplier, 1) | ||
|| !Mathf.Approximately(limit, 1); | ||
|
||
protected override void OnDisable() | ||
{ | ||
MaterialRegistry.Release(ref _material); | ||
base.OnDisable(); | ||
} | ||
|
||
public override void ApplyBakedEffect(CommandBuffer cb) | ||
{ | ||
// Baked buffer | ||
Profiler.BeginSample("(CCR)[CompositeCanvasBlur] ApplyBakedEffect > Init"); | ||
var rt = compositeCanvasRenderer.mainTexture; | ||
var w = rt.width; | ||
var h = rt.height; | ||
var result = new RenderTargetIdentifier(rt); | ||
Profiler.EndSample(); | ||
|
||
// Get blur material | ||
Profiler.BeginSample("(CCR)[CompositeCanvasBlur] ApplyBakedEffect > Get blur material (lambda)"); | ||
var hash = new Hash128(ShaderPropertyIds.compositeCanvasBlur, 0, 0, 0); | ||
MaterialRegistry.Get(hash, ref _material, | ||
() => new Material(Shader.Find("Hidden/UI/CompositeCanvasRenderer/Blur")) | ||
{ | ||
hideFlags = HideFlags.DontSave | HideFlags.NotEditable | ||
}, CompositeCanvasRendererProjectSettings.cacheRendererMaterial); | ||
Profiler.EndSample(); | ||
|
||
var scale = w / compositeCanvasRenderer.renderingSize.x; | ||
var blurValue = blur * scale; | ||
if (0 < blurValue) | ||
{ | ||
Profiler.BeginSample("(CCR)[CompositeCanvasBlur] ApplyBakedEffect > Construct blur effect for cb"); | ||
cb.GetTemporaryRT(ShaderPropertyIds.tmpRt, w, h, 0, FilterMode.Bilinear); | ||
for (var i = 0; i < m_Iteration; i++) | ||
{ | ||
// Horizontal blur | ||
cb.SetGlobalVector(ShaderPropertyIds.blur, new Vector4(blurValue, 0)); | ||
cb.Blit(result, ShaderPropertyIds.tmpRt, _material, 0); | ||
|
||
// Vertical blur | ||
cb.SetGlobalVector(ShaderPropertyIds.blur, new Vector4(0, blurValue)); | ||
if (i == iteration - 1 && useCutoffPass) | ||
{ | ||
// blur and cutoff | ||
cb.SetGlobalFloat(ShaderPropertyIds.innerCutoff, innerCutoff); | ||
cb.SetGlobalFloat(ShaderPropertyIds.power, power); | ||
cb.SetGlobalFloat(ShaderPropertyIds.multiplier, multiplier); | ||
cb.SetGlobalFloat(ShaderPropertyIds.limit, limit); | ||
cb.Blit(ShaderPropertyIds.tmpRt, result, _material); | ||
} | ||
else | ||
{ | ||
cb.Blit(ShaderPropertyIds.tmpRt, result, _material, 0); | ||
} | ||
} | ||
|
||
cb.ReleaseTemporaryRT(ShaderPropertyIds.tmpRt); | ||
Profiler.EndSample(); | ||
} | ||
else if (useCutoffPass) | ||
{ | ||
Profiler.BeginSample("(CCR)[CompositeCanvasBlur] ApplyBakedEffect > Construct cutoff effect for cb"); | ||
cb.GetTemporaryRT(ShaderPropertyIds.tmpRt, w, h, 0, FilterMode.Bilinear); | ||
|
||
// cutoff | ||
cb.SetGlobalFloat(ShaderPropertyIds.innerCutoff, innerCutoff); | ||
cb.SetGlobalFloat(ShaderPropertyIds.power, power); | ||
cb.SetGlobalFloat(ShaderPropertyIds.multiplier, multiplier); | ||
cb.SetGlobalFloat(ShaderPropertyIds.limit, limit); | ||
cb.Blit(result, ShaderPropertyIds.tmpRt, _material, 1); | ||
cb.CopyTexture(ShaderPropertyIds.tmpRt, result); | ||
|
||
cb.ReleaseTemporaryRT(ShaderPropertyIds.tmpRt); | ||
Profiler.EndSample(); | ||
} | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using UnityEngine; | ||
using UnityEngine.Rendering; | ||
|
||
namespace CompositeCanvas | ||
{ | ||
[ExecuteAlways] | ||
[RequireComponent(typeof(CompositeCanvasRenderer))] | ||
[DisallowMultipleComponent] | ||
public abstract class CompositeCanvasEffect : MonoBehaviour | ||
{ | ||
private CompositeCanvasRenderer _compositeCanvasRenderer; | ||
|
||
protected CompositeCanvasRenderer compositeCanvasRenderer => | ||
_compositeCanvasRenderer | ||
? _compositeCanvasRenderer | ||
: _compositeCanvasRenderer = GetComponent<CompositeCanvasRenderer>(); | ||
|
||
public virtual void Reset() | ||
{ | ||
} | ||
|
||
protected virtual void OnEnable() | ||
{ | ||
SetRendererDirty(); | ||
} | ||
|
||
protected virtual void OnDisable() | ||
{ | ||
SetRendererDirty(); | ||
} | ||
|
||
protected virtual void OnValidate() | ||
{ | ||
SetRendererDirty(); | ||
} | ||
|
||
public void SetRendererDirty() | ||
{ | ||
if (!compositeCanvasRenderer) return; | ||
|
||
compositeCanvasRenderer.SetDirty(); | ||
} | ||
|
||
public void SetRendererVerticesDirty() | ||
{ | ||
if (!compositeCanvasRenderer) return; | ||
|
||
compositeCanvasRenderer.SetVerticesDirty(); | ||
} | ||
|
||
public void SetRendererMaterialDirty() | ||
{ | ||
if (!compositeCanvasRenderer) return; | ||
|
||
compositeCanvasRenderer.SetMaterialDirty(); | ||
} | ||
|
||
public abstract void ApplyBakedEffect(CommandBuffer cb); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Packages/src/Runtime/Effects/CompositeCanvasEffect.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
98 changes: 98 additions & 0 deletions
98
Packages/src/Shaders/Hidden-UI-CompositeCanvasRenderer-Blur.shader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
Shader "Hidden/UI/CompositeCanvasRenderer/Blur" | ||
{ | ||
Properties | ||
{ | ||
[PerRendererData] _MainTex("Main Texture", 2D) = "white" {} | ||
} | ||
|
||
SubShader | ||
{ | ||
ZTest Always | ||
Cull Off | ||
ZWrite Off | ||
Blend One Zero | ||
Fog | ||
{ | ||
Mode Off | ||
} | ||
|
||
Pass | ||
{ | ||
Name "Blur" | ||
|
||
CGPROGRAM | ||
#pragma vertex vert_img | ||
#pragma fragment frag_blur | ||
#pragma target 2.0 | ||
|
||
#include "UnityCG.cginc" | ||
|
||
sampler2D _MainTex; | ||
float4 _MainTex_TexelSize; | ||
half4 _Blur; | ||
|
||
fixed4 tex2DBlurring1D(sampler2D tex, half2 uv, half2 blur) | ||
{ | ||
const int KERNEL_SIZE = 9; | ||
float4 o = 0; | ||
float sum = 0; | ||
for (int i = -KERNEL_SIZE / 2; i <= KERNEL_SIZE / 2; i++) | ||
{ | ||
const half2 sample_uv = half2(uv + blur * i); | ||
const float weight = 1.0 / (abs(i) + 2); | ||
o += tex2D(tex, sample_uv) * weight; | ||
sum += weight; | ||
} | ||
return o / sum; | ||
} | ||
|
||
float invLerp(const float from, const float to, const float value) | ||
{ | ||
return saturate(max(0, value - from) / max(0.000000001, to - from)); | ||
} | ||
|
||
fixed4 frag_blur(v2f_img IN) : SV_Target | ||
{ | ||
const half2 blur_factor = _Blur.xy; | ||
return tex2DBlurring1D(_MainTex, IN.uv, blur_factor * _MainTex_TexelSize.xy); | ||
} | ||
ENDCG | ||
} | ||
|
||
Pass | ||
{ | ||
Name "Cutoff" | ||
|
||
CGPROGRAM | ||
#pragma vertex vert_img | ||
#pragma fragment frag | ||
#pragma target 2.0 | ||
|
||
#include "UnityCG.cginc" | ||
|
||
sampler2D _MainTex; | ||
float _InnerCutoff; | ||
float _Multiplier; | ||
float _Power; | ||
float _Limit; | ||
|
||
float invLerp(const float from, const float to, const float value) | ||
{ | ||
return (max(0, value - from) / max(0.000000001, to - from)); | ||
} | ||
|
||
fixed4 frag(v2f_img IN) : SV_Target | ||
{ | ||
half4 color = tex2D(_MainTex, IN.uv); | ||
color = pow(color, _Power); | ||
|
||
const half inner = invLerp(_InnerCutoff, 1, color.a); | ||
color *= lerp(_Multiplier, 0, inner); | ||
|
||
color = min(color, _Limit); | ||
return color; | ||
} | ||
ENDCG | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
Packages/src/Shaders/Hidden-UI-CompositeCanvasRenderer-Blur.shader.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.