Skip to content

Commit

Permalink
close #95; Improve blurring for atlas
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai authored and mob-sakai committed Aug 24, 2018
1 parent 552d15f commit 251c3a7
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 33 deletions.
9 changes: 9 additions & 0 deletions Assets/Coffee/UIExtensions/UIEffect/Scripts/Common/Packer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ public static class Packer
/// </summary>
public static float ToFloat(float x, float y, float z, float w)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
z = z < 0 ? 0 : 1 < z ? 1 : z;
w = w < 0 ? 0 : 1 < w ? 1 : w;
const int PRECISION = (1 << 6) - 1;
return (Mathf.FloorToInt(w * PRECISION) << 18)
+ (Mathf.FloorToInt(z * PRECISION) << 12)
Expand All @@ -32,6 +36,9 @@ public static float ToFloat(Vector4 factor)
/// </summary>
public static float ToFloat(float x, float y, float z)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
z = z < 0 ? 0 : 1 < z ? 1 : z;
const int PRECISION = (1 << 8) - 1;
return (Mathf.FloorToInt(z * PRECISION) << 16)
+ (Mathf.FloorToInt(y * PRECISION) << 8)
Expand All @@ -44,6 +51,8 @@ public static float ToFloat(float x, float y, float z)
/// </summary>
public static float ToFloat(float x, float y)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
const int PRECISION = (1 << 12) - 1;
return (Mathf.FloorToInt(y * PRECISION) << 12)
+ Mathf.FloorToInt(x * PRECISION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ public static void DrawEffectProperties(string shaderName, SerializedObject seri
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Blur"));

var spAdvancedBlur = serializedObject.FindProperty("m_AdvancedBlur");
if (spAdvancedBlur != null)
{
EditorGUILayout.PropertyField(spAdvancedBlur);
}
EditorGUI.indentLevel--;
}

Expand Down
182 changes: 166 additions & 16 deletions Assets/Coffee/UIExtensions/UIEffect/Scripts/UIEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ public class UIEffect : UIEffectBase
[Obsolete][HideInInspector]
[SerializeField] List<UIShadow.AdditionalShadow> m_AdditionalShadows = new List<UIShadow.AdditionalShadow>();

[SerializeField] bool m_AdvancedBlur = false;


public enum BlurEx
{
None = 0,
Ex = 1,
}

//################################
// Public Members.
Expand Down Expand Up @@ -162,19 +167,119 @@ public override void ModifyMesh(VertexHelper vh)
return;
}

UIVertex vt = default(UIVertex);
int count = vh.currentVertCount;
// UIVertex vt = default(UIVertex);
// int count = vh.currentVertCount;
float normalizedIndex = ptex.GetNormalizedIndex(this);
//
// for (int i = 0; i < count; i++)
// {
// // Set prameters to vertex.
// vh.PopulateUIVertex(ref vt, i);
// vt.uv0 = new Vector2(
// Packer.ToFloat(vt.uv0.x, vt.uv0.y),
// normalizedIndex
// );
// vh.SetUIVertex(vt, i);
// }

for (int i = 0; i < count; i++)


if (m_AdvancedBlur)
{
// Set prameters to vertex.
vh.PopulateUIVertex(ref vt, i);
vt.uv0 = new Vector2(
Packer.ToFloat(vt.uv0.x, vt.uv0.y),
normalizedIndex
);
vh.SetUIVertex(vt, i);
vh.GetUIVertexStream(tempVerts);
vh.Clear();
var count = tempVerts.Count;

// Bundle
int bundleSize = targetGraphic is Text ? 6 : count;
Rect posBounds = default(Rect);
Rect uvBounds = default(Rect);
Vector3 size = default(Vector3);
Vector3 tPos = default(Vector3);
Vector3 tUV = default(Vector3);
float expand = (float)blurMode * 6;

for (int i = 0; i < count; i += bundleSize)
{
// Quadバンドル単位での最大/最小値
GetBounds(tempVerts, i, bundleSize, ref posBounds, ref uvBounds, true);

// Pack uv mask.
Vector2 uvMask = new Vector2(Packer.ToFloat(uvBounds.xMin, uvBounds.yMin), Packer.ToFloat(uvBounds.xMax, uvBounds.yMax));

// Quad
for (int j = 0; j < bundleSize; j += 6)
{
Vector3 cornerPos1 = tempVerts[i + j + 1].position;
Vector3 cornerPos2 = tempVerts[i + j + 4].position;

// 外周Quadかどうか.
bool hasOuterEdge = (bundleSize == 6)
|| !posBounds.Contains(cornerPos1)
|| !posBounds.Contains(cornerPos2);
if (hasOuterEdge)
{
Vector3 cornerUv1 = tempVerts[i + j + 1].uv0;
Vector3 cornerUv2 = tempVerts[i + j + 4].uv0;

Vector3 centerPos = (cornerPos1 + cornerPos2) / 2;
Vector3 centerUV = (cornerUv1 + cornerUv2) / 2;
size = (cornerPos1 - cornerPos2);

size.x = 1 + expand / Mathf.Abs(size.x);
size.y = 1 + expand / Mathf.Abs(size.y);
size.z = 1 + expand / Mathf.Abs(size.z);

tPos = centerPos - Vector3.Scale(size, centerPos);
tUV = centerUV - Vector3.Scale(size, centerUV);
}

// Vertex
for (int k = 0; k < 6; k++)
{
UIVertex vt = tempVerts[i + j + k];

Vector3 pos = vt.position;
Vector2 uv0 = vt.uv0;

if (hasOuterEdge && (pos.x < posBounds.xMin || posBounds.xMax < pos.x))
{
pos.x = pos.x * size.x + tPos.x;
uv0.x = uv0.x * size.x + tUV.x;
}
if (hasOuterEdge && (pos.y < posBounds.yMin || posBounds.yMax < pos.y))
{
pos.y = pos.y * size.y + tPos.y;
uv0.y = uv0.y * size.y + tUV.y;
}

// vt.uv0 = new Vector2(Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f), blur);
vt.uv0 = new Vector2(Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f), normalizedIndex);
vt.position = pos;
vt.uv1 = uvMask;

tempVerts[i + j + k] = vt;
}
}
}

vh.AddUIVertexTriangleStream(tempVerts);
tempVerts.Clear();
}
else
{
int count = vh.currentVertCount;
UIVertex vt = default(UIVertex);
for (int i = 0; i < count; i++)
{
vh.PopulateUIVertex(ref vt, i);
Vector2 uv0 = vt.uv0;
vt.uv0 = new Vector2(
Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f),
normalizedIndex
);
vh.SetUIVertex(vt, i);
}
}
}

Expand Down Expand Up @@ -312,7 +417,7 @@ protected override Material GetMaterial ()
{
return null;
}
return MaterialResolver.GetOrGenerateMaterialVariant(Shader.Find(shaderName), m_ToneMode, m_ColorMode, m_BlurMode);
return MaterialResolver.GetOrGenerateMaterialVariant(Shader.Find(shaderName), m_ToneMode, m_ColorMode, m_BlurMode, m_AdvancedBlur ? BlurEx.Ex : BlurEx.None);
}

#pragma warning disable 0612
Expand Down Expand Up @@ -367,7 +472,11 @@ protected override void UpgradeIfNeeded()
}
}

if (m_ToneMode == ToneMode.Hue)
int tone = (int)m_ToneMode;
const int Mono = 5;
const int Cutoff = 6;
const int Hue = 7;
if (tone == Hue)
{
var go = gameObject;
var hue = m_ToneLevel;
Expand All @@ -377,13 +486,14 @@ protected override void UpgradeIfNeeded()
hsv.range = 1;
}

if (m_ToneMode == ToneMode.Cutoff || m_ToneMode == ToneMode.Mono)
// Cutoff/Mono
if (tone == Cutoff || tone == Mono)
{
var go = gameObject;
var factor = m_ToneLevel;
var transitionMode = m_ToneMode == ToneMode.Cutoff
var transitionMode = tone == Cutoff
? UITransitionEffect.EffectMode.Cutoff
: UITransitionEffect.EffectMode.Mono;
: UITransitionEffect.EffectMode.Fade;
DestroyImmediate(this, true);
var trans = go.GetComponent<UITransitionEffect>() ?? go.AddComponent<UITransitionEffect>();
trans.effectFactor = factor;
Expand All @@ -400,5 +510,45 @@ protected override void UpgradeIfNeeded()
//################################
// Private Members.
//################################
static void GetBounds(List<UIVertex> verts, int start, int count, ref Rect posBounds, ref Rect uvBounds, bool global)
{
Vector2 minPos = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxPos = new Vector2(float.MinValue, float.MinValue);
Vector2 minUV = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxUV = new Vector2(float.MinValue, float.MinValue);
for (int i = start; i < start + count; i++)
{
UIVertex vt = verts[i];

Vector2 uv = vt.uv0;
Vector3 pos = vt.position;

// Left-Bottom
if (minPos.x >= pos.x && minPos.y >= pos.y)
{
minPos = pos;
}
// Right-Top
else if (maxPos.x <= pos.x && maxPos.y <= pos.y)
{
maxPos = pos;
}

// Left-Bottom
if (minUV.x >= uv.x && minUV.y >= uv.y)
{
minUV = uv;
}
// Right-Top
else if (maxUV.x <= uv.x && maxUV.y <= uv.y)
{
maxUV = uv;
}
}

// Shrink coordinate for detect edge
posBounds.Set(minPos.x + 0.001f, minPos.y + 0.001f, maxPos.x - minPos.x - 0.002f, maxPos.y - minPos.y - 0.002f);
uvBounds.Set(minUV.x, minUV.y, maxUV.x - minUV.x, maxUV.y - minUV.y);
}
}
}
39 changes: 28 additions & 11 deletions Assets/Coffee/UIExtensions/UIEffect/Shaders/UI-Effect.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -64,41 +64,58 @@ half2 UnpackToVec2(float value)
return unpacked;
}


// Sample texture with blurring.
// * Fast: Sample texture with 3x3 kernel.
// * Medium: Sample texture with 5x5 kernel.
// * Detail: Sample texture with 7x7 kernel.
fixed4 Tex2DBlurring (sampler2D tex, half2 uv, half2 blur)
fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur, half4 mask)
{
#if FASTBLUR
const int KERNEL_SIZE = 3;
const float KERNEL_[3] = { 0.4566, 1.0, 0.4566};
#elif MEDIUMBLUR
const int KERNEL_SIZE = 5;
const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486};
#elif DETAILBLUR
const int KERNEL_SIZE = 7;
const float KERNEL_[7] = { 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719};
#else
const int KERNEL_SIZE = 1;
const float KERNEL_[1] = { 1.0 };
#endif
float4 o = 0;
float sum = 0;
float weight;
half2 texcood;
for(int x = -KERNEL_SIZE/2; x <= KERNEL_SIZE/2; x++)
float2 shift = 0;
for(int x = 0; x < KERNEL_SIZE; x++)
{
for(int y = -KERNEL_SIZE/2; y <= KERNEL_SIZE/2; y++)
shift.x = blur.x * (float(x) - KERNEL_SIZE/2);
for(int y = 0; y < KERNEL_SIZE; y++)
{
texcood = uv;
texcood.x += blur.x * x;
texcood.y += blur.y * y;
weight = 1.0/(abs(x)+abs(y)+2);
o += tex2D(tex, texcood)*weight;
shift.y = blur.y * (float(y) - KERNEL_SIZE/2);
float2 uv = texcood + shift;
float weight = KERNEL_[x] * KERNEL_[y];
sum += weight;
#if EX
fixed masked = min(mask.x <= uv.x, uv.x <= mask.z) * min(mask.y <= uv.y, uv.y <= mask.w);
o += lerp(fixed4(0.5, 0.5, 0.5, 0), tex2D(tex, uv), masked) * weight;
#else
o += tex2D(tex, uv) * weight;
#endif
}
}
return o / sum;
}

// Sample texture with blurring.
// * Fast: Sample texture with 3x3 kernel.
// * Medium: Sample texture with 5x5 kernel.
// * Detail: Sample texture with 7x7 kernel.
fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur)
{
return Tex2DBlurring(tex, texcood, blur, half4(0,0,1,1));
}


// Sample texture with blurring.
// * Fast: Sample texture with 3x1 kernel.
// * Medium: Sample texture with 5x1 kernel.
Expand Down
Loading

0 comments on commit 251c3a7

Please sign in to comment.