mirror of
https://github.com/ppy/osu.git
synced 2024-09-21 21:27:24 +08:00
Improve quality of beatmap background blurs
This commit is contained in:
parent
01a3cf3849
commit
906e700b60
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -17,8 +18,6 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
/// </summary>
|
||||
public class Background : CompositeDrawable, IEquatable<Background>
|
||||
{
|
||||
private const float blur_scale = 0.5f;
|
||||
|
||||
public readonly Sprite Sprite;
|
||||
|
||||
private readonly string textureName;
|
||||
@ -46,7 +45,7 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
Sprite.Texture = textures.Get(textureName);
|
||||
}
|
||||
|
||||
public Vector2 BlurSigma => bufferedContainer?.BlurSigma / blur_scale ?? Vector2.Zero;
|
||||
public Vector2 BlurSigma => Vector2.Divide(bufferedContainer?.BlurSigma ?? Vector2.Zero, blurScale);
|
||||
|
||||
/// <summary>
|
||||
/// Smoothly adjusts <see cref="IBufferedContainer.BlurSigma"/> over time.
|
||||
@ -67,9 +66,48 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
}
|
||||
|
||||
if (bufferedContainer != null)
|
||||
bufferedContainer.FrameBufferScale = newBlurSigma == Vector2.Zero ? Vector2.One : new Vector2(blur_scale);
|
||||
transformBlurSigma(newBlurSigma, duration, easing);
|
||||
}
|
||||
|
||||
bufferedContainer?.BlurTo(newBlurSigma * blur_scale, duration, easing);
|
||||
private void transformBlurSigma(Vector2 newBlurSigma, double duration, Easing easing)
|
||||
=> this.TransformTo(nameof(blurSigma), newBlurSigma, duration, easing);
|
||||
|
||||
private Vector2 blurSigmaBacking = Vector2.Zero;
|
||||
private Vector2 blurScale = Vector2.One;
|
||||
|
||||
private Vector2 blurSigma
|
||||
{
|
||||
get => blurSigmaBacking;
|
||||
set
|
||||
{
|
||||
Debug.Assert(bufferedContainer != null);
|
||||
|
||||
blurSigmaBacking = value;
|
||||
blurScale = new Vector2(calculateBlurDownscale(value.X), calculateBlurDownscale(value.Y));
|
||||
|
||||
bufferedContainer.FrameBufferScale = blurScale;
|
||||
bufferedContainer.BlurSigma = value * blurScale; // If the image is scaled down, the blur radius also needs to be reduced to cover the same pixel block.
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines a factor to downscale the background based on a given blur sigma, in order to reduce the computational complexity of blurs.
|
||||
/// </summary>
|
||||
/// <param name="sigma">The blur sigma.</param>
|
||||
/// <returns>The scale-down factor.</returns>
|
||||
private float calculateBlurDownscale(float sigma)
|
||||
{
|
||||
// If we're blurring within one pixel, scaling down will always result in an undesirable loss of quality.
|
||||
// The algorithm below would also cause this value to go above 1, which is likewise undesirable.
|
||||
if (sigma <= 1)
|
||||
return 1;
|
||||
|
||||
// A good value is one where the loss in quality as a result of downscaling the image is not easily perceivable.
|
||||
// The constants here have been experimentally chosen to yield nice transitions by approximating a log curve through the points {{ 1, 1 }, { 4, 0.75 }, { 16, 0.5 }, { 32, 0.25 }}.
|
||||
float scale = -0.18f * MathF.Log(0.004f * sigma);
|
||||
|
||||
// To reduce shimmering, the scaling transitions are limited to happen only in increments of 0.2.
|
||||
return MathF.Round(scale / 0.2f, MidpointRounding.AwayFromZero) * 0.2f;
|
||||
}
|
||||
|
||||
public virtual bool Equals(Background other)
|
||||
|
Loading…
Reference in New Issue
Block a user