diff --git a/osu.Game.Resources/Shaders/sh_ArgonBarPath.fs b/osu.Game.Resources/Shaders/sh_ArgonBarPath.fs index 99123222a..8b1311d85 100644 --- a/osu.Game.Resources/Shaders/sh_ArgonBarPath.fs +++ b/osu.Game.Resources/Shaders/sh_ArgonBarPath.fs @@ -31,7 +31,7 @@ lowp vec4 glowColAt(highp float absoluteTexturePos, highp float absoluteGlowPort mixValue *= mixValue; mixValue *= mixValue; mixValue *= mixValue; - return vec4(glowColour.rgb, glowColour.a * mixValue); + return glowColour.rgba * mixValue; } lowp vec4 getColour(highp float absoluteTexturePos) diff --git a/osu.Game.Resources/Shaders/sh_ArgonBarPathBackground.fs b/osu.Game.Resources/Shaders/sh_ArgonBarPathBackground.fs index 713a30710..9f423d8ea 100644 --- a/osu.Game.Resources/Shaders/sh_ArgonBarPathBackground.fs +++ b/osu.Game.Resources/Shaders/sh_ArgonBarPathBackground.fs @@ -21,13 +21,19 @@ layout(location = 0) out vec4 o_Colour; lowp vec4 bgColAt(highp float absoluteTexturePos, mediump float pathRadius) { highp float relativeTexturePos = clamp(absoluteTexturePos / pathRadius, 0.0, 1.5); - return mix(vec4(vec3(0.0), 0.2), vec4(vec3(1.0), 0.8), relativeTexturePos / 1.5); + vec4 result = mix(vec4(0.2), vec4(vec3(1.0), 0.8), relativeTexturePos / 1.5); + result = vec4(result.rgb * result.a, result.a); + return result; } lowp vec4 getColour(highp float absoluteTexturePos, mediump float pathRadius) { if (absoluteTexturePos > pathRadius - 1.0) - return mix(vec4(1.0), vec4(vec3(1.0), 0.0), absoluteTexturePos - (pathRadius - 1.0)); + { + vec4 result = mix(vec4(1.0), vec4(vec3(1.0), 0.0), absoluteTexturePos - (pathRadius - 1.0)); + result = vec4(result.rgb * result.a, result.a); + return result; + } if (absoluteTexturePos > pathRadius - 2.0) return mix(bgColAt(absoluteTexturePos, pathRadius), vec4(1.0), absoluteTexturePos - (pathRadius - 2.0)); diff --git a/osu.Game.Resources/Shaders/sh_CircularFlashlight.fs b/osu.Game.Resources/Shaders/sh_CircularFlashlight.fs index bb4c859b2..6714659d6 100644 --- a/osu.Game.Resources/Shaders/sh_CircularFlashlight.fs +++ b/osu.Game.Resources/Shaders/sh_CircularFlashlight.fs @@ -6,5 +6,5 @@ lowp vec4 getColourAt(highp vec2 diff, highp vec2 size, lowp vec4 originalColour highp float dist = length(diff); highp float flashlightRadius = length(size); - return originalColour * vec4(1.0, 1.0, 1.0, smoothstep(flashlightRadius, flashlightRadius * flashlightSmoothness, dist)); + return originalColour * vec4(smoothstep(flashlightRadius, flashlightRadius * flashlightSmoothness, dist)); } \ No newline at end of file diff --git a/osu.Game.Resources/Shaders/sh_CursorTrail.vs b/osu.Game.Resources/Shaders/sh_CursorTrail.vs index 73d8f6b50..12454b5dc 100644 --- a/osu.Game.Resources/Shaders/sh_CursorTrail.vs +++ b/osu.Game.Resources/Shaders/sh_CursorTrail.vs @@ -22,7 +22,7 @@ void main(void) vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position, 1.0); v_MaskingPosition = maskingPos.xy / maskingPos.z; - v_Colour = vec4(m_Colour.rgb, m_Colour.a * pow(clamp(m_Time - g_FadeClock, 0.0, 1.0), g_FadeExponent)); + v_Colour = m_Colour.rgba * pow(clamp(m_Time - g_FadeClock, 0.0, 1.0), g_FadeExponent); v_TexCoord = m_TexCoord; v_TexRect = m_TexRect; diff --git a/osu.Game.Resources/Shaders/sh_Flashlight.h b/osu.Game.Resources/Shaders/sh_Flashlight.h index fcfc34d29..4c20ffb83 100644 --- a/osu.Game.Resources/Shaders/sh_Flashlight.h +++ b/osu.Game.Resources/Shaders/sh_Flashlight.h @@ -18,5 +18,7 @@ void main(void) // todo: workaround for a SPIR-V bug (https://github.com/ppy/osu-framework/issues/5719) float one = g_WrapModeS >= 0 ? 1 : 0; - o_Colour = mix(getColourAt(flashlightPos - v_Position, flashlightSize, v_Colour), vec4(0.0, 0.0, 0.0, v_Colour.a), flashlightDim) * one; + vec4 result = mix(getColourAt(flashlightPos - v_Position, flashlightSize, v_Colour), vec4(vec3(0.0), v_Colour.a), flashlightDim) * one; + result = vec4(result.rgb * result.a, result.a); + o_Colour = result; } \ No newline at end of file diff --git a/osu.Game.Resources/Shaders/sh_LogoAnimation.fs b/osu.Game.Resources/Shaders/sh_LogoAnimation.fs index fa7ba34e8..c6871d700 100644 --- a/osu.Game.Resources/Shaders/sh_LogoAnimation.fs +++ b/osu.Game.Resources/Shaders/sh_LogoAnimation.fs @@ -18,7 +18,13 @@ void main(void) // todo: workaround for a SPIR-V bug (https://github.com/ppy/osu-framework/issues/5719) float one = g_BackbufferDraw ? 1 : 0; - vec4 colour = texture(sampler2D(m_Texture, m_Sampler), v_TexCoord, -0.9) * one; + vec4 texel = texture(sampler2D(m_Texture, m_Sampler), v_TexCoord, -0.9) * one; - o_Colour = colour.r < progress ? vec4(v_Colour.rgb, v_Colour.a * colour.a) : vec4(0); + // in the logo animation textures, progress information is stored in red channel, + // and alpha information is stored in green channel. this is done this way + // to avoid alpha pre-multiplication causing data precision loss. + float current = texel.r; + float alpha = texel.g; + + o_Colour = current < progress ? v_Colour.rgba * alpha : vec4(0); } \ No newline at end of file diff --git a/osu.Game.Resources/Shaders/sh_RectangularFlashlight.fs b/osu.Game.Resources/Shaders/sh_RectangularFlashlight.fs index 8fe9c97f3..ce01c1069 100644 --- a/osu.Game.Resources/Shaders/sh_RectangularFlashlight.fs +++ b/osu.Game.Resources/Shaders/sh_RectangularFlashlight.fs @@ -6,5 +6,5 @@ lowp vec4 getColourAt(highp vec2 diff, highp vec2 size, lowp vec4 originalColour lowp float alpha = length(smoothstep(size, size * flashlightSmoothness, diff)); - return originalColour * vec4(1.0, 1.0, 1.0, alpha); + return originalColour * vec4(alpha); } diff --git a/osu.Game.Resources/Shaders/sh_TriangleBorder.fs b/osu.Game.Resources/Shaders/sh_TriangleBorder.fs index ba0581fd4..443c83b8b 100644 --- a/osu.Game.Resources/Shaders/sh_TriangleBorder.fs +++ b/osu.Game.Resources/Shaders/sh_TriangleBorder.fs @@ -55,5 +55,5 @@ void main(void) lowp vec4 col = getRoundedColor(vec4(1.0), v_TexCoord); - o_Colour = vec4(col.rgb, col.a * alpha); + o_Colour = col.rgba * alpha; } diff --git a/osu.Game.Resources/Textures/Intro/Triangles/LogoTextureProcessor.cs b/osu.Game.Resources/Textures/Intro/Triangles/LogoTextureProcessor.cs new file mode 100644 index 000000000..3c572ba73 --- /dev/null +++ b/osu.Game.Resources/Textures/Intro/Triangles/LogoTextureProcessor.cs @@ -0,0 +1,28 @@ +// Post-process for logo animation path textures, moving alpha information away from the alpha channel +// for the shader to produce correct animation without losing information from textures being alpha-premultiplied. +// Input: textures with colours in the form: (x, x, x, y), in which x represents current progress and y represents alpha. +// Output: textures with colours in the form: (x, y, 0, 255). + +// Code is commented to not cause compile errors on osu-resources. + +/* +const string path = "/osu.Game.Resources/Textures/Intro/Triangles"; +processImage(Path.Combine(path, "logo-background.png")); +processImage(Path.Combine(path, "logo-highlight.png")); + +void processImage(string filename) +{ + using var image = Image.Load(filename); + + image.ProcessPixelRows(p => + { + for (int i = 0; i < p.Height; i++) + { + foreach (ref var pixel in p.GetRowSpan(i)) + pixel = new Rgba32(pixel.R, pixel.A, 0, 255); + } + }); + + image.SaveAsPng(filename); +} +*/ \ No newline at end of file diff --git a/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png b/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png index 31e093d75..9a52dc936 100644 Binary files a/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png and b/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png differ diff --git a/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png b/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png index ce1a45b42..9b5c8f37a 100644 Binary files a/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png and b/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png differ