bugfix(audio): Fix range volume fade of 3D sounds and make it configurable in AudioSettings.ini#2369
bugfix(audio): Fix range volume fade of 3D sounds and make it configurable in AudioSettings.ini#2369xezon wants to merge 3 commits intoTheSuperHackers:mainfrom
Conversation
…rable in AudioSettings.ini
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/Common/AudioSettings.h | Adds m_use3DSoundRangeVolumeFade and m_3DSoundRangeVolumeFadeExponent fields with correct constructor initialization; existing structure and pragma-once guard are intact. |
| Core/GameEngine/Source/Common/Audio/GameAudio.cpp | Two new INI parse-table entries wired up correctly to the new AudioSettings fields; no functional issues. |
| Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp | Replaces the broken reciprocal-distance attenuation with a correct configurable exponential fade; logic is sound for valid exponent values but lacks a guard against zero or negative exponents which can produce negative volume output. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[getEffectiveVolume called] --> B{isPositionalAudio?}
B -- No --> C[volume *= m_soundVolume]
B -- Yes --> D{getCurrentPosition != null?}
D -- No --> E[return volume as-is]
D -- Yes --> F[compute distance vector\ndistance = listenerPos - soundPos]
F --> G{ST_GLOBAL flag?}
G -- Yes --> H[objMin/Max = globalMinRange / globalMaxRange]
G -- No --> I[objMin/Max = event minDistance / maxDistance]
H & I --> J[objDistance = distance.length]
J --> K{objDistance >= objMaxDistance?}
K -- Yes --> L[volume = 0.0f]
K -- No --> M{use3DSoundRangeVolumeFade\n&& objDistance > objMinDistance?}
M -- No --> N[volume unchanged]
M -- Yes --> O["attenuation = (objDist - minDist) / (maxDist - minDist)"]
O --> P["attenuation = pow(attenuation, fadeExponent)"]
P --> Q["volume *= 1.0f - attenuation"]
L & N & Q --> R[return volume]
Last reviewed commit: 49616d2
| //} | ||
| else if( audioSettings->m_use3DSoundRangeVolumeFade && objDistance > objMinDistance ) | ||
| { | ||
| Real attenuation = (objDistance - objMinDistance) / (objMaxDistance - objMinDistance); |
There was a problem hiding this comment.
when objMaxDistance and objMinDistance are set by m_globalMaxRange and m_globalMinRange, they are set through ini. Theoretically, a user could (incorrectly) edit the ini such that the values are the same, causing a division by zero.
Looking at it, this could also be the case if objMax/MinDistance is set by m_minDistance and m_maxDistance.
There was a problem hiding this comment.
If objMaxDistance == objMinDistance, then it never gets here, because if( objDistance >= objMaxDistance ) above.
This change is a follow up for #2058 which accidentally and insufficiently changed the volume of 3D sounds depending on their distance to the camera pivot.
Originally the sounds did not correctly consider the 3D distance checks in
MilesAudioManager::getEffectiveVolume. They were considered for some logic, but not for the actual volume. This meant that the volume never correctly faded between the min and max ranges of audio events, and left sharp audio cut offs instead.Problems
The originally unused fade math in
MilesAudioManager::getEffectiveVolumewas incorrect. The commented linear fade math was actually correct.The original 3D sounds were always loud all the way to the max range because they never faded correctly. Therefore an exponential fade is suitable to better preserve the original loudness of 3D sounds.
AudioSettings.ini
New configuration options were added to AudioSettings.ini to control the 3D sounds fade behavior:
Use3DSoundRangeVolumeFade = Yes/No// Set No for original bugged behavior3DSoundRangeVolumeFadeExponent = 1..N// Set 1 for linear fade, larger 1 for sharp fade near max rangeExponential Fade
I picked a exponent of 4 which creates a curve like this and sounded good.
x(0) is MinRange, x(1) is MaxRange
y(0) is MinVolume, y(1) is MaxVolume