From 06122ab28f0f77fe2970172933d12e03d3cd2a4f Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 30 Oct 2021 22:49:29 +0800 Subject: [PATCH 1/2] the final shader should looks like this. but seems init only run once(that's ok), but value cannot be saved. --- .../Resources/Shaders/sh_Outline.fs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs index b76beb3..a1c51c3 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs @@ -10,21 +10,20 @@ uniform mediump vec2 g_TexSize; uniform int g_Radius; uniform vec4 g_Colour; +vec2 angelPosition[SAMPLES]; + lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour) { - float angle = 0.0; float outlineAlpha = 0.0; for (int i = 0; i < SAMPLES; i++) { - angle += 1.0 / (float(SAMPLES) / 2.0) * PI; - // todo: might need to adjust step samples amount to fill the inner side. // but it will cause lots of performance issue if make step samples larger. // so should find a better algorithm to fill inner colour. for (int j = 1; j <= STEP_SAMPLES; j++) { - vec2 testPoint = texCoord - vec2(sin(angle), cos(angle)) * (float(radius) * (1.0 / j)) / texSize; + vec2 testPoint = texCoord - angelPosition[i] * (float(radius) * (1.0 / j)) / texSize; float sampledAlpha = texture2D(tex, testPoint).a; outlineAlpha = max(outlineAlpha, sampledAlpha); } @@ -36,6 +35,17 @@ lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 return mix(outlineCol, ogCol, ogCol.a); } +void init(void) +{ + // pre-calculate position in here. + float angle = 0.0; + for (int i = 0; i < SAMPLES; i++) + { + angle += 1.0 / (float(SAMPLES) / 2.0) * PI; + angelPosition[i] = vec2(sin(angle), cos(angle)); + } +} + void main(void) { gl_FragColor = outline(m_Sampler, g_Radius, v_TexCoord, g_TexSize, g_Colour); From eb9442c3a68c4b15941fb7a5b44c19aae074a34c Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 31 Oct 2021 10:55:25 +0800 Subject: [PATCH 2/2] pre-calculate all the position for preventing calculate in each frame. --- .../Visual/Shaders/TestSceneOutlineShader.cs | 21 +++ .../Resources/Shaders/sh_Outline.fs | 151 ++++++++++++++++-- 2 files changed, 157 insertions(+), 15 deletions(-) diff --git a/osu.Framework.Font.Tests/Visual/Shaders/TestSceneOutlineShader.cs b/osu.Framework.Font.Tests/Visual/Shaders/TestSceneOutlineShader.cs index 3954c1a..6823d34 100644 --- a/osu.Framework.Font.Tests/Visual/Shaders/TestSceneOutlineShader.cs +++ b/osu.Framework.Font.Tests/Visual/Shaders/TestSceneOutlineShader.cs @@ -1,6 +1,7 @@ // Copyright (c) andy840119 . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using NUnit.Framework; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; @@ -28,5 +29,25 @@ public void TestProperty(int radius, string colour) }; }); } + + [TestCase(128)] + public void CreateAnglePositionParams(int samples) + { + // it's a script on creating const params in shader. + + const float pi = 3.14159265359f; + double angle = 0.0f; + + Console.WriteLine($"const lowp vec2 angelPosition[{samples}] = lowp vec2[]("); + + for (int i = 0; i < samples; i++) + { + var last = i == samples - 1; + angle += 1.0 / (samples / 2.0) * pi; + Console.WriteLine($" lowp vec2({Math.Sin(angle):N2}, {Math.Cos(angle):N2})" + (last ? "" : ",")); + } + + Console.WriteLine(");"); + } } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs index a1c51c3..59f472f 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs @@ -10,7 +10,136 @@ uniform mediump vec2 g_TexSize; uniform int g_Radius; uniform vec4 g_Colour; -vec2 angelPosition[SAMPLES]; +const lowp vec2 angelPosition[SAMPLES] = lowp vec2[]( + lowp vec2(0.05, 1.00), + lowp vec2(0.10, 1.00), + lowp vec2(0.15, 0.99), + lowp vec2(0.20, 0.98), + lowp vec2(0.24, 0.97), + lowp vec2(0.29, 0.96), + lowp vec2(0.34, 0.94), + lowp vec2(0.38, 0.92), + lowp vec2(0.43, 0.90), + lowp vec2(0.47, 0.88), + lowp vec2(0.51, 0.86), + lowp vec2(0.56, 0.83), + lowp vec2(0.60, 0.80), + lowp vec2(0.63, 0.77), + lowp vec2(0.67, 0.74), + lowp vec2(0.71, 0.71), + lowp vec2(0.74, 0.67), + lowp vec2(0.77, 0.63), + lowp vec2(0.80, 0.60), + lowp vec2(0.83, 0.56), + lowp vec2(0.86, 0.51), + lowp vec2(0.88, 0.47), + lowp vec2(0.90, 0.43), + lowp vec2(0.92, 0.38), + lowp vec2(0.94, 0.34), + lowp vec2(0.96, 0.29), + lowp vec2(0.97, 0.24), + lowp vec2(0.98, 0.20), + lowp vec2(0.99, 0.15), + lowp vec2(1.00, 0.10), + lowp vec2(1.00, 0.05), + lowp vec2(1.00, -0.00), + lowp vec2(1.00, -0.05), + lowp vec2(1.00, -0.10), + lowp vec2(0.99, -0.15), + lowp vec2(0.98, -0.20), + lowp vec2(0.97, -0.24), + lowp vec2(0.96, -0.29), + lowp vec2(0.94, -0.34), + lowp vec2(0.92, -0.38), + lowp vec2(0.90, -0.43), + lowp vec2(0.88, -0.47), + lowp vec2(0.86, -0.51), + lowp vec2(0.83, -0.56), + lowp vec2(0.80, -0.60), + lowp vec2(0.77, -0.63), + lowp vec2(0.74, -0.67), + lowp vec2(0.71, -0.71), + lowp vec2(0.67, -0.74), + lowp vec2(0.63, -0.77), + lowp vec2(0.60, -0.80), + lowp vec2(0.56, -0.83), + lowp vec2(0.51, -0.86), + lowp vec2(0.47, -0.88), + lowp vec2(0.43, -0.90), + lowp vec2(0.38, -0.92), + lowp vec2(0.34, -0.94), + lowp vec2(0.29, -0.96), + lowp vec2(0.24, -0.97), + lowp vec2(0.20, -0.98), + lowp vec2(0.15, -0.99), + lowp vec2(0.10, -1.00), + lowp vec2(0.05, -1.00), + lowp vec2(-0.00, -1.00), + lowp vec2(-0.05, -1.00), + lowp vec2(-0.10, -1.00), + lowp vec2(-0.15, -0.99), + lowp vec2(-0.20, -0.98), + lowp vec2(-0.24, -0.97), + lowp vec2(-0.29, -0.96), + lowp vec2(-0.34, -0.94), + lowp vec2(-0.38, -0.92), + lowp vec2(-0.43, -0.90), + lowp vec2(-0.47, -0.88), + lowp vec2(-0.51, -0.86), + lowp vec2(-0.56, -0.83), + lowp vec2(-0.60, -0.80), + lowp vec2(-0.63, -0.77), + lowp vec2(-0.67, -0.74), + lowp vec2(-0.71, -0.71), + lowp vec2(-0.74, -0.67), + lowp vec2(-0.77, -0.63), + lowp vec2(-0.80, -0.60), + lowp vec2(-0.83, -0.56), + lowp vec2(-0.86, -0.51), + lowp vec2(-0.88, -0.47), + lowp vec2(-0.90, -0.43), + lowp vec2(-0.92, -0.38), + lowp vec2(-0.94, -0.34), + lowp vec2(-0.96, -0.29), + lowp vec2(-0.97, -0.24), + lowp vec2(-0.98, -0.20), + lowp vec2(-0.99, -0.15), + lowp vec2(-1.00, -0.10), + lowp vec2(-1.00, -0.05), + lowp vec2(-1.00, 0.00), + lowp vec2(-1.00, 0.05), + lowp vec2(-1.00, 0.10), + lowp vec2(-0.99, 0.15), + lowp vec2(-0.98, 0.20), + lowp vec2(-0.97, 0.24), + lowp vec2(-0.96, 0.29), + lowp vec2(-0.94, 0.34), + lowp vec2(-0.92, 0.38), + lowp vec2(-0.90, 0.43), + lowp vec2(-0.88, 0.47), + lowp vec2(-0.86, 0.51), + lowp vec2(-0.83, 0.56), + lowp vec2(-0.80, 0.60), + lowp vec2(-0.77, 0.63), + lowp vec2(-0.74, 0.67), + lowp vec2(-0.71, 0.71), + lowp vec2(-0.67, 0.74), + lowp vec2(-0.63, 0.77), + lowp vec2(-0.60, 0.80), + lowp vec2(-0.56, 0.83), + lowp vec2(-0.51, 0.86), + lowp vec2(-0.47, 0.88), + lowp vec2(-0.43, 0.90), + lowp vec2(-0.38, 0.92), + lowp vec2(-0.34, 0.94), + lowp vec2(-0.29, 0.96), + lowp vec2(-0.24, 0.97), + lowp vec2(-0.20, 0.98), + lowp vec2(-0.15, 0.99), + lowp vec2(-0.10, 1.00), + lowp vec2(-0.05, 1.00), + lowp vec2(0.00, 1.00) +); lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour) { @@ -23,9 +152,12 @@ lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 // so should find a better algorithm to fill inner colour. for (int j = 1; j <= STEP_SAMPLES; j++) { - vec2 testPoint = texCoord - angelPosition[i] * (float(radius) * (1.0 / j)) / texSize; - float sampledAlpha = texture2D(tex, testPoint).a; - outlineAlpha = max(outlineAlpha, sampledAlpha); + if(outlineAlpha < 0.99) + { + vec2 testPoint = texCoord - angelPosition[i] * (float(radius) * (1.0 / j)) / texSize; + float sampledAlpha = texture2D(tex, testPoint).a; + outlineAlpha = max(outlineAlpha, sampledAlpha); + } } } @@ -35,17 +167,6 @@ lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 return mix(outlineCol, ogCol, ogCol.a); } -void init(void) -{ - // pre-calculate position in here. - float angle = 0.0; - for (int i = 0; i < SAMPLES; i++) - { - angle += 1.0 / (float(SAMPLES) / 2.0) * PI; - angelPosition[i] = vec2(sin(angle), cos(angle)); - } -} - void main(void) { gl_FragColor = outline(m_Sampler, g_Radius, v_TexCoord, g_TexSize, g_Colour);