From 1e3ef61fc9e34675c48189a106d6aae37cb885ad Mon Sep 17 00:00:00 2001
From: Cameron Taylor <cameron.taylor.ninja@gmail.com>
Date: Tue, 11 Jun 2024 15:57:45 -0400
Subject: [PATCH] freeplay bg nicer AA and proper sizing

---
 source/funkin/graphics/shaders/AngleMask.hx | 76 +++++++++++++++------
 source/funkin/ui/freeplay/FreeplayState.hx  | 19 ++++--
 2 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/source/funkin/graphics/shaders/AngleMask.hx b/source/funkin/graphics/shaders/AngleMask.hx
index 30e508a58..c5ef87b72 100644
--- a/source/funkin/graphics/shaders/AngleMask.hx
+++ b/source/funkin/graphics/shaders/AngleMask.hx
@@ -5,35 +5,73 @@ import flixel.system.FlxAssets.FlxShader;
 class AngleMask extends FlxShader
 {
   @:glFragmentSource('
-		#pragma header
-        uniform vec2 endPosition;
-		void main()
-		{
-			vec4 base = texture2D(bitmap, openfl_TextureCoordv);
+    #pragma header
 
-            vec2 uv = openfl_TextureCoordv.xy;
+    uniform vec2 endPosition;
+    vec2 hash22(vec2 p) {
+      vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
+      p3 += dot(p3, p3.yzx + 33.33);
+      return fract((p3.xx + p3.yz) * p3.zy);
+    }
 
 
 
-            vec2 start = vec2(0.0, 0.0);
-            vec2 end = vec2(endPosition.x / openfl_TextureSize.x, 1.0);
+    // ====== GAMMA CORRECTION ====== //
+    // Helps with color mixing -- good to have by default in almost any shader
+    // See https://www.shadertoy.com/view/lscSzl
+    vec3 gamma(in vec3 color) {
+      return pow(color, vec3(1.0 / 2.2));
+    }
 
-            float dx = end.x - start.x;
-            float dy = end.y - start.y;
+    vec4 mainPass(vec2 fragCoord) {
+      vec4 base = texture2D(bitmap, fragCoord);
 
-            float angle = atan(dy, dx);
+      vec2 uv = fragCoord.xy;
 
-            uv.x -= start.x;
-            uv.y -= start.y;
+      vec2 start = vec2(0.0, 0.0);
+      vec2 end = vec2(endPosition.x / openfl_TextureSize.x, 1.0);
 
-            float uvA = atan(uv.y, uv.x);
+      float dx = end.x - start.x;
+      float dy = end.y - start.y;
 
-            if (uvA < angle)
-                gl_FragColor = base;
-            else
-                gl_FragColor = vec4(0.0);
+      float angle = atan(dy, dx);
 
-		}')
+      uv.x -= start.x;
+      uv.y -= start.y;
+
+      float uvA = atan(uv.y, uv.x);
+
+      if (uvA < angle)
+        return base;
+      else
+        return vec4(0.0);
+    }
+
+    vec4 antialias(vec2 fragCoord) {
+
+      const float AA_STAGES = 2.0;
+
+      const float AA_TOTAL_PASSES = AA_STAGES * AA_STAGES + 1.0;
+      const float AA_JITTER = 0.5;
+
+      // Run the shader multiple times with a random subpixel offset each time and average the results
+      vec4 color = mainPass(fragCoord);
+      for (float x = 0.0; x < AA_STAGES; x++)
+      {
+          for (float y = 0.0; y < AA_STAGES; y++)
+          {
+              vec2 offset = AA_JITTER * (2.0 * hash22(vec2(x, y)) - 1.0) / openfl_TextureSize.xy;
+              color += mainPass(fragCoord + offset);
+          }
+      }
+      return color / AA_TOTAL_PASSES;
+    }
+
+    void main() {
+      vec4 col = antialias(openfl_TextureCoordv);
+      // col.xyz = gamma(col.xyz);
+      gl_FragColor = col;
+    }')
   public function new()
   {
     super();
diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index 06684ae7c..1149aec0c 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -458,15 +458,20 @@ class FreeplayState extends MusicBeatSubState
 
     add(dj);
 
-    bgDad = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad'));
-    bgDad.setGraphicSize(0, FlxG.height);
-    bgDad.updateHitbox();
+    bgDad = new FlxSprite(pinkBack.width * 0.74, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad'));
     bgDad.shader = new AngleMask();
     bgDad.visible = false;
 
     var blackOverlayBullshitLOLXD:FlxSprite = new FlxSprite(FlxG.width).makeGraphic(Std.int(bgDad.width), Std.int(bgDad.height), FlxColor.BLACK);
     add(blackOverlayBullshitLOLXD); // used to mask the text lol!
 
+    // this makes the texture sizes consistent, for the angle shader
+    bgDad.setGraphicSize(0, FlxG.height);
+    blackOverlayBullshitLOLXD.setGraphicSize(0, FlxG.height);
+
+    bgDad.updateHitbox();
+    blackOverlayBullshitLOLXD.updateHitbox();
+
     exitMovers.set([blackOverlayBullshitLOLXD, bgDad],
       {
         x: FlxG.width * 1.5,
@@ -475,7 +480,7 @@ class FreeplayState extends MusicBeatSubState
       });
 
     add(bgDad);
-    FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.76}, 0.7, {ease: FlxEase.quintOut});
+    FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.74}, 0.7, {ease: FlxEase.quintOut});
 
     blackOverlayBullshitLOLXD.shader = bgDad.shader;
 
@@ -971,13 +976,15 @@ class FreeplayState extends MusicBeatSubState
     grpCapsules.members[curSelected].ranking.scale.set(20, 20);
     grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20);
 
-    if (fromResults?.newRank != null) {
+    if (fromResults?.newRank != null)
+    {
       grpCapsules.members[curSelected].ranking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true);
     }
 
     FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1);
 
-    if (fromResults?.newRank != null) {
+    if (fromResults?.newRank != null)
+    {
       grpCapsules.members[curSelected].blurredRanking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true);
     }
     FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1);