Open ellenhp opened 3 years ago
The algorithm for blending isn't really all that obvious, but because people will probably end up composing multiple area overrides to form complex shapes, doing a simple mean will cause a transition zone overlapping with an area that's fully overriding the bus to actually cause the overall effect to be reduced. Because of this, the algorithm should loop through all bus overrides and pick the max diversion to each then normalize the results. Hopefully that makes sense. By only picking the maximum value for the override to each bus, two areas that send sound to the same bus won't be dragging each other down. Obviously normalizing is important after though.
If this turns out to be too complex, a simple time-based blending approach with a configurable per-area duration might be good enough. It could default to a transition duration of 1 second.
Describe the project you are working on
Godot Audio!
Describe the problem or limitation you are having in your project
Bus overrides are immediate which is jarring as a user. Additionally, they only occur when the source is inside the overriding area. The listener's position has no effect and the path the sound took has no effect.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Once https://github.com/godotengine/godot/pull/51296 is merged, audio stream players gain the ability to mix audio to multiple busses at the same time. With that change comes the ability to gradually transition from one bus to the other during an Area based bus override. That opens up the ability to change Area-based overrides to have transition zones. I think it would be really cool to also add an override mode setting to the area that allows it to override the bus that all spatial audio players play through.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Adding the following properties to Area2D/3D:
bus_override_mode
which can be any ofSOURCE_POSITION
LISTENER_POSITION
ANDSOURCE_AND_LISTENER_POSITIONS
. Defaults toSOURCE_POSITION
for compat.bus_override_max_fraction
which is a slider from 0 to 1, representing the maximum fraction of sound that can be diverted from the audio player node's default bus to the override bus. Defaults to 1 for compat.bus_override_transition_zone
which is a slider from 0% to 100% or 0 to 1 or something. Defaults to zero for compat. The value set with this slider is the fraction of the area (in a single dimension) that is devoted to a transition from no diverted audio to fully diverted audio (or up tobus_override_max_fraction
).bus_override_priority
which is an int describing the priority for this area-based bus override. If multiple areas attempt to override the audio bus of a sound, the overrides are applied in order of priority. In other words, a large cave area might fully override the audio bus to add a strong reverb effect with a long decay time. When the player or a sound source enters a smaller cave area though, it may have a higher priority and divert some sound away from the strong reverb bus into a second reverb bus with a shorter decay time.Both spatial audio players will have to be updated to read and respect these values from any bus overrides. In the case of multiple bus overrides, the overrides should be blended together somehow.
The algorithm for blending isn't really all that obvious, but because people will probably end up composing multiple area overrides to form complex shapes, doing a simple mean will cause a transition zone overlapping with an area that's fully overriding the bus to actually cause the overall effect to be reduced. Because of this, the algorithm should loop through all bus overrides and pick the max diversion to each then normalize the results. Hopefully that makes sense. By only picking the maximum value for the override to each bus, two areas that send sound to the same bus won't be dragging each other down. Obviously normalizing is important after though.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No but if https://github.com/godotengine/godot/pull/51296 is merged and the methods it adds are exposed to script it theoretically becomes possible to maybe kind of work around this. Huge pain though.
Is there a reason why this should be core and not an add-on in the asset library?
Lack of effective workarounds.