Skip to content

Commit

Permalink
Merge pull request #68 from andy840119/fix-performance-issue
Browse files Browse the repository at this point in the history
Fix outline shader performance issue.
  • Loading branch information
andy840119 authored Oct 20, 2021
2 parents 9992b17 + 2455a25 commit d78ce91
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class CustomizedShaderTestScene : ShaderTestScene
[TestCase(0, "#FF0000")]
[TestCase(10, "#00FF00")]
[TestCase(20, "#0000FF")]
[TestCase(100, "#0000FF")] // it might cause performance issue if set radius too large.
public void TestOutlineShader(int radius, string colour)
{
AddStep("Apply shader", () =>
Expand Down
36 changes: 20 additions & 16 deletions osu.Framework.Font/Resources/Shaders/sh_Outline.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "sh_Utils.h"

#define PI 3.14159265359
#define SAMPLES 128
#define STEP_SAMPLES 2

varying mediump vec2 v_TexCoord;

uniform lowp sampler2D m_Sampler;
Expand All @@ -10,28 +14,28 @@ uniform vec4 g_Colour;

lowp vec4 outline(sampler2D tex, int radius, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour)
{
mediump vec4 sum = texture2D(tex, texCoord);

for (int size = 2; size <= 200; size += 2)
float angle = 0.0;
float outlineAlpha = 0.0;

for (int i = 0; i < SAMPLES; i++)
{
// draw the circle outline with target size
for(int degree = 0; degree < 360; degree += 5)
{
mediump float xx = sin(degree);
mediump float yy = cos(degree);
angle += 1.0 / (float(SAMPLES) / 2.0) * PI;

// create sample with target position.
mediump vec4 texture = texture2D(tex, texCoord + vec2( xx, yy ) * size / texSize).a * colour;
sum += texture;
// 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;
float sampledAlpha = texture2D(tex, testPoint).a;
outlineAlpha = max(outlineAlpha, sampledAlpha);
}
if (size >= radius)
break;
}

// draw origin texture2D in center
sum += texture2D(tex, texCoord);
mediump vec4 ogCol = texture2D(tex, texCoord);
vec4 outlineCol = mix(vec4(0.0), colour, outlineAlpha);

return sum;
return mix(outlineCol, ogCol, ogCol.a);
}

void main(void)
Expand Down

0 comments on commit d78ce91

Please sign in to comment.