Skip to content

Commit

Permalink
feat: add SamplingScale option
Browse files Browse the repository at this point in the history
close #269
  • Loading branch information
mob-sakai committed Dec 14, 2024
1 parent 8117933 commit 94f0376
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Packages/src/Editor/UIEffectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class UIEffect2Editor : Editor

private SerializedProperty _samplingFilter;
private SerializedProperty _samplingIntensity;
private SerializedProperty _samplingScale;

private SerializedProperty _transitionFilter;
private SerializedProperty _transitionRate;
Expand Down Expand Up @@ -71,6 +72,7 @@ private void OnEnable()

_samplingFilter = serializedObject.FindProperty("m_SamplingFilter");
_samplingIntensity = serializedObject.FindProperty("m_SamplingIntensity");
_samplingScale = serializedObject.FindProperty("m_SamplingScale");

_transitionFilter = serializedObject.FindProperty("m_TransitionFilter");
_transitionRate = serializedObject.FindProperty("m_TransitionRate");
Expand Down Expand Up @@ -145,6 +147,7 @@ public void DrawProperties()
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_samplingIntensity);
EditorGUILayout.PropertyField(_samplingScale);
EditorGUI.indentLevel--;
}

Expand Down
3 changes: 3 additions & 0 deletions Packages/src/Editor/UIEffectReplicaEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ public class UIEffectReplicaEditor : Editor
{
private SerializedProperty _target;
private SerializedProperty _useTargetTransform;
private SerializedProperty _samplingScale;
private Editor _uiEffectEditor;

private void OnEnable()
{
_target = serializedObject.FindProperty("m_Target");
_useTargetTransform = serializedObject.FindProperty("m_UseTargetTransform");
_samplingScale = serializedObject.FindProperty("m_SamplingScale");
}

public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(_target);
EditorGUILayout.PropertyField(_useTargetTransform);
EditorGUILayout.PropertyField(_samplingScale);

if (_target.objectReferenceValue)
{
Expand Down
56 changes: 56 additions & 0 deletions Packages/src/Runtime/Internal/Utilities/PowerRangeAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using UnityEditor;
using UnityEngine;

namespace Coffee.UIEffectInternal
{
[AttributeUsage(AttributeTargets.Field)]
public sealed class PowerRangeAttribute : PropertyAttribute
{
public readonly float min;
public readonly float max;
public readonly float power;

public PowerRangeAttribute(float min, float max, float power)
{
this.min = min;
this.max = max;
this.power = power;
}
}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(PowerRangeAttribute))]
internal sealed class RangeDrawer : PropertyDrawer
{
public override void OnGUI(Rect r, SerializedProperty property, GUIContent label)
{
var labelWidth = EditorGUIUtility.labelWidth;
var attr = (PowerRangeAttribute)attribute;
label = EditorGUI.BeginProperty(r, label, property);

EditorGUI.BeginChangeCheck();
var rSlider = new Rect(r.x + labelWidth + 1, r.y, r.width - labelWidth - 57, r.height);
var powValue = Mathf.Log(property.floatValue, attr.power);
var powMin = Mathf.Log(attr.min, attr.power);
var powMax = Mathf.Log(attr.max, attr.power);
powValue = GUI.HorizontalSlider(rSlider, powValue, powMin, powMax);
if (EditorGUI.EndChangeCheck())
{
property.floatValue = Mathf.Clamp(Mathf.Pow(attr.power, powValue), attr.min, attr.max);
}

EditorGUI.BeginChangeCheck();
EditorGUIUtility.labelWidth = r.width - 53;
var newValue = EditorGUI.FloatField(r, label, property.floatValue);
if (EditorGUI.EndChangeCheck())
{
property.floatValue = Mathf.Clamp(newValue, attr.min, attr.max);
}

EditorGUI.EndProperty();
EditorGUIUtility.labelWidth = labelWidth;
}
}
#endif
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Packages/src/Runtime/UIEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public class UIEffect : UIEffectBase
[SerializeField]
protected float m_SamplingIntensity = 0.5f;

[PowerRange(0.01f, 100f, 10f)]
[SerializeField]
protected float m_SamplingScale = 1f;

[SerializeField]
protected TransitionFilter m_TransitionFilter = TransitionFilter.None;

Expand Down Expand Up @@ -205,6 +209,22 @@ public float samplingIntensity
}
}

public float samplingScale
{
get => m_SamplingScale;
set
{
value = Mathf.Clamp(value, 0.01f, 100);
if (Mathf.Approximately(m_SamplingScale, value)) return;
m_SamplingScale = value;
ApplyContextToMaterial();
}
}

public override float actualSamplingScale => samplingFilter != SamplingFilter.None
? Mathf.Clamp(m_SamplingScale, 0.01f, 100)
: 1;

public TransitionFilter transitionFilter
{
get => m_TransitionFilter;
Expand Down Expand Up @@ -651,6 +671,7 @@ public void LoadPreset(UIEffect preset)

m_SamplingFilter = preset.m_SamplingFilter;
m_SamplingIntensity = preset.m_SamplingIntensity;
m_SamplingScale = preset.m_SamplingScale;

m_TransitionFilter = preset.m_TransitionFilter;
m_TransitionRate = preset.m_TransitionRate;
Expand Down
6 changes: 4 additions & 2 deletions Packages/src/Runtime/UIEffectBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public abstract class UIEffectBase : UIBehaviour, IMeshModifier, IMaterialModifi

public Graphic graphic => _graphic ? _graphic : _graphic = GetComponent<Graphic>();
public virtual uint effectId => (uint)GetInstanceID();
public virtual float actualSamplingScale => 1;

public virtual UIEffectContext context
{
Expand Down Expand Up @@ -90,7 +91,8 @@ public virtual Material GetModifiedMaterial(Material baseMaterial)
}

Profiler.BeginSample("(UIE)[UIEffect] GetModifiedMaterial");
var hash = new Hash128((uint)baseMaterial.GetInstanceID(), effectId, 0, 0);
var samplingScaleId = (uint)(Mathf.InverseLerp(0.01f, 100, actualSamplingScale) * uint.MaxValue);
var hash = new Hash128((uint)baseMaterial.GetInstanceID(), effectId, samplingScaleId, 0);
if (!MaterialRepository.Valid(hash, _material))
{
Profiler.BeginSample("(UIE)[UIEffect] GetModifiedMaterial > Get or create material");
Expand Down Expand Up @@ -200,7 +202,7 @@ public virtual void ApplyContextToMaterial()
{
if (!isActiveAndEnabled || context == null) return;

context.ApplyToMaterial(_material);
context.ApplyToMaterial(_material, actualSamplingScale);

#if UNITY_EDITOR
UIEffectProjectSettings.shaderRegistry.RegisterVariant(_material, "UI > UIEffect");
Expand Down
4 changes: 3 additions & 1 deletion Packages/src/Runtime/UIEffectContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class UIEffectContext
private static readonly int s_ColorValue = Shader.PropertyToID("_ColorValue");
private static readonly int s_ColorIntensity = Shader.PropertyToID("_ColorIntensity");
private static readonly int s_SamplingIntensity = Shader.PropertyToID("_SamplingIntensity");
private static readonly int s_SamplingScale = Shader.PropertyToID("_SamplingScale");
private static readonly int s_TransitionRate = Shader.PropertyToID("_TransitionRate");
private static readonly int s_TransitionReverse = Shader.PropertyToID("_TransitionReverse");
private static readonly int s_TransitionTex = Shader.PropertyToID("_TransitionTex");
Expand Down Expand Up @@ -189,7 +190,7 @@ public void CopyFrom(UIEffectContext preset)
shadowEffectOnOrigin = preset.shadowEffectOnOrigin;
}

public void ApplyToMaterial(Material material)
public void ApplyToMaterial(Material material, float actualSamplingScale = 1f)
{
if (!material) return;

Expand All @@ -205,6 +206,7 @@ public void ApplyToMaterial(Material material)
material.SetFloat(s_ColorIntensity, Mathf.Clamp01(colorIntensity));

material.SetFloat(s_SamplingIntensity, Mathf.Clamp01(samplingIntensity));
material.SetFloat(s_SamplingScale, actualSamplingScale);

material.SetFloat(s_TransitionRate, Mathf.Clamp01(transitionRate));
material.SetInt(s_TransitionReverse, transitionReverse ? 1 : 0);
Expand Down
20 changes: 20 additions & 0 deletions Packages/src/Runtime/UIEffectReplica.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public class UIEffectReplica : UIEffectBase
[SerializeField] private UIEffect m_Target;
[SerializeField] private bool m_UseTargetTransform = true;

[PowerRange(0.01f, 100, 10f)]
[SerializeField]
protected float m_SamplingScale = 1f;

private UIEffect _currentTarget;
private Matrix4x4 _prevTransformHash;

Expand Down Expand Up @@ -35,6 +39,22 @@ public bool useTargetTransform
}
}

public float samplingScale
{
get => m_SamplingScale;
set
{
value = Mathf.Clamp(value, 0.01f, 100);
if (Mathf.Approximately(m_SamplingScale, value)) return;
m_SamplingScale = value;
ApplyContextToMaterial();
}
}

public override float actualSamplingScale => target && target.samplingFilter != SamplingFilter.None
? Mathf.Clamp(m_SamplingScale, 0.01f, 100)
: 1;

public override uint effectId => target ? target.effectId : 0;
public override UIEffectContext context => target && target.isActiveAndEnabled ? target.context : null;

Expand Down
16 changes: 11 additions & 5 deletions Packages/src/Shaders/UIEffect.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ uniform float _ToneIntensity;
uniform half4 _ColorValue;
uniform float _ColorIntensity;
uniform float _SamplingIntensity;
uniform float _SamplingScale;
uniform sampler2D _TransitionTex;
uniform float4 _TransitionTex_ST;
uniform float _TransitionRate;
Expand Down Expand Up @@ -41,6 +42,11 @@ uniform float _TargetSoftness;
* step(uvMask.x, uv.x) * step(uv.x, uvMask.z) \
* step(uvMask.y, uv.y) * step(uv.y, uvMask.w)

float2 texel_size()
{
return _MainTex_TexelSize.xy * _SamplingScale;
}

float3 rgb_to_hsv(float3 c)
{
const float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
Expand Down Expand Up @@ -243,7 +249,7 @@ half4 apply_sampling_filter(float2 uv, const float4 uvMask, const float2 uvLocal
float4 o = 0;
float sum = 0;
float2 shift = 0;
const half2 blur = _MainTex_TexelSize.xy * _SamplingIntensity * 2;
const half2 blur = texel_size() * _SamplingIntensity * 2;
for (int x = 0; x < KERNEL_SIZE; x++)
{
shift.x = blur.x * (float(x) - KERNEL_SIZE / 2);
Expand Down Expand Up @@ -381,13 +387,13 @@ half4 uieffect(float2 uv, const float4 uvMask, const float2 uvLocal)
// Sampling.Pixelation
#if SAMPLING_PIXELATION
{
const half2 pixelSize = max(2, (1 - lerp(0.5, 0.95, _SamplingIntensity)) * _MainTex_TexelSize.zw);
const half2 pixelSize = max(2, (1 - lerp(0.5, 0.95, _SamplingIntensity)) / texel_size());
uv = round(uv * pixelSize) / pixelSize;
}
// Sampling.RgbShift
#elif SAMPLING_RGB_SHIFT
{
const half2 offset = half2(_SamplingIntensity * _MainTex_TexelSize.x * 20, 0);
const half2 offset = half2(_SamplingIntensity * texel_size().x * 20, 0);
const half2 r = uieffect_internal(uv + offset, uvMask, uvLocal).ra;
const half2 g = uieffect_internal(uv, uvMask, uvLocal).ga;
const half2 b = uieffect_internal(uv - offset, uvMask, uvLocal).ba;
Expand All @@ -397,8 +403,8 @@ half4 uieffect(float2 uv, const float4 uvMask, const float2 uvLocal)
#elif SAMPLING_EDGE_LUMINANCE || SAMPLING_EDGE_ALPHA
{
// Pixel size
const float dx = _MainTex_TexelSize.x;
const float dy = _MainTex_TexelSize.y;
const float dx = texel_size().x;
const float dy = texel_size().y;

// Pixel values around the current pixel (3x3, 8 neighbors)
const float2 uv00 = uv + half2(-dx, -dy);
Expand Down

0 comments on commit 94f0376

Please sign in to comment.