Add ability to change background dim colour in grayscale
Previously discussed here: https://github.com/ppy/osu/discussions/12983
Depends on:
- https://github.com/ppy/osu-resources/pull/344
- https://github.com/ppy/osu-framework/pull/6395
- https://github.com/ppy/osu-framework/pull/6404
- https://github.com/ppy/osu-framework/pull/6591
Allows to change which colour the background is dimmed to. Currently only supports grayscale.
This is not a full implementation, as it doesn't support storyboards and videos.
The main reason I'm asking for comments so early is that this implementation handles dimming in two different classes, which leads to code duplication, so I wonder if there is a cleaner way to do this.
https://github.com/user-attachments/assets/5be01be4-7bae-4d9d-b8cb-057d933abb0e
Here are also a few examples of how it could look with colour picker instead of a grayscale slider, using SettingsColour, but I'm unsure if it fits the design, as colour pickers weren't used in Settings/Visual Settings before. Also it doesn't work properly in Visual Settings yet, because it doesn't have a PopoverContainer in its hierarchy, and I'm not really sure how to handle it.
Just a quick thing, "0%-100%" doesn't really make sense in the context of a slider changing how light or dark the dim is. This would be fixed in the color picker implementation anyway though (which I personally think makes more sense, though maybe hiding the UI element behind an option that's off by default?)
Just a quick thing, "0%-100%" doesn't really make sense in the context of a slider changing how light or dark the dim is. This would be fixed in the color picker implementation anyway though (which I personally think makes more sense, though maybe hiding the UI element behind an option that's off by default?)
I'm not sure what would be better than 0%-100% for a slider. Or do you mean ditching the slider completely? Would renaming the setting to background dim brightness make more sense?
Just a quick thing, "0%-100%" doesn't really make sense in the context of a slider changing how light or dark the dim is. This would be fixed in the color picker implementation anyway though (which I personally think makes more sense, though maybe hiding the UI element behind an option that's off by default?)
I'm not sure what would be better than 0%-100% for a slider. Or do you mean ditching the slider completely? Would renaming the setting to background dim brightness make more sense?
yes that would be better, if I saw a slider labeled "background dim color" and it was a percent I wouldn't know what the number represented, "brightness" works better.
It might make more sense to rename "Background dim" to "Background opacity" and have 100% be a fully visible image. Although this will go against user expectations coming from stable so maybe it's too late to make a change like this.
I wonder if it is fine to just add an overlay (a quad with Colour == DimColour, Alpha == DimLevel and a size that covers an entire background) to achieve same effect for storyboards/videos.
It's a way simpler solution than changing shaders of all of the osu.Game.Storyboards.Drawables. It might cause performance to drop a bit, though I'm unsure how noticeable it would be with storyboards/videos enabled.
I can only understand doing this for storyboards since they are not buffered (and I would question how it's supposed to behave, because blending the entire storyboard behind some "background dim colour" overlay might end up looking silly). For videos, this can still totally be done by shaders with some changes framework-side.
Currently coloured dimming in the shader is done using a mix function (mix(texel, m_DimColour, m_DimLevel)), which can be expanded as texel * (1 - m_DimLevel) + m_DimColour * m_DimLevel
Since all colours of all storyboard drawables are already multiplied by 1 - DimLevel, the entire effect can be reproduced by just adding an overlay quad with additive blending and Colour == DimColour && Alpha == DimLevel
Also I just realized that in the mix function I'm also interpolating alpha, need to fix that.
"Just adding an overlay quad with..." is exactly the 1x overhead problem that we would like to avoid here by doing better.
Yeah, true I just wondered if it's going to be fine at least with storyboards, given that they're pretty heavy already (though it depends on individual storyboards), so the performance hit might not be as noticeable But ok, no shortcuts
Storyboards are now also supported
https://github.com/user-attachments/assets/89e11fdc-0980-4b3b-a5a2-6a744918c30f
However, I used default method implementation in IColouredDimmable interface, unsure if that's ok to do
Current implementation makes performance on heavy storyboards (such as Mili - world.execute(me);) significantly worse. Mean frametimes for different parts of the map:
| Gameplay | Breaks | Fade in | Fade out | |
|---|---|---|---|---|
| 2025.607.0 | 3.51 ms | 3.56 ms | 3.43 ms | 3.68 ms |
| 80c93b3 | 4.32 ms | 4.34 ms | 4.22 ms | 4.50 ms |
| Relative increase | 23% | 22% | 23% | 22% |