audio-branding-and-storytelling
A Step-by-step Guide to Implementing Real-time Audio Occlusion in Wwise
Table of Contents
Implementing real-time audio occlusion in Wwise enhances the immersive experience by accurately simulating how sounds are blocked or muffled by obstacles in a game environment. This guide provides a comprehensive, step-by-step approach to achieving this feature effectively, from initial setup in Wwise to integration with your game engine and fine-tuning for optimal realism.
Understanding Audio Occlusion in Wwise
Audio occlusion refers to the reduction or alteration of sound when it encounters obstacles between the listener and the sound source. In Wwise, this effect can be dynamically managed using Real-Time Parameter Controls (RTPCs) and auxiliary buses, allowing the audio engine to respond to in-game changes such as player movement, object positioning, and environmental geometry. Properly implemented occlusion creates a more believable and engaging audio environment, helping players intuitively understand spatial relationships and environmental obstacles.
It is important to distinguish between occlusion and obstruction. Occlusion occurs when there is a solid obstruction between the listener and the source that blocks most or all sound, resulting in muffling and volume reduction. Obstruction, on the other hand, happens when an object partially blocks the sound path, causing filtering and attenuation but not complete loss. Wwise can handle both simultaneously using separate parameters and effects, but this guide focuses primarily on occlusion with the option to extend to obstruction.
Prerequisites
- Wwise authoring tool (version 2021.1 or later recommended)
- Basic knowledge of Wwise project setup, including actor-mixer hierarchy and sound banks
- A game engine integrated with Wwise (e.g., Unity, Unreal Engine, or Godot)
- A 3D environment containing geometry that can serve as obstacles (walls, pillars, terrain)
- Understanding of the Wwise Audio Link or similar integration package for your engine
Step 1: Create an Occlusion Bus and Effect
Begin by setting up a dedicated auxiliary bus that will process the muffled sound when occlusion is detected. In the Wwise Project Explorer, navigate to the Master-Mixer Hierarchy and create a new Audio Bus named “Occlusion_Bus”. This bus will house the effects that simulate the sound passing through an obstacle.
With the bus selected, open the Effect Settings tab and add a low-pass filter effect (e.g., Wwise Low-Pass Filter or a custom effect). Configure the filter cutoff frequency to be controlled by an RTPC. For instance, set the cutoff to 500 Hz when occlusion is maximum (value 1) and to 20,000 Hz (no filtering) when occlusion is 0. This creates the characteristic muffled sound of an occluded audio source. You may also add a gain reduction or attenuation effect to lower the volume proportionally.
Tip: For a more advanced setup, create two separate auxiliary buses: one for occlusion and one for obstruction. This allows independent control of low-pass filtering and volume, giving you greater creative flexibility.
Step 2: Set Up an Auxiliary Send on Sound Objects
In the Actor-Mixer Hierarchy, select the sound objects that should support occlusion (e.g., footsteps, gunshots, ambient environmental sounds). Open the General Settings tab for each object and locate the Auxiliary Sends section. Add a new send targeting the “Occlusion_Bus” you created. By default, the send level can remain at 0 dB (100% of the signal) – the actual amount of occlusion that is mixed in will be controlled via the RTPC later.
It is often best to create a SoundBank containing these sound objects and the occlusion bus to ensure proper runtime loading. Also, consider assigning a dedicated “Occlusion” attenuation share set to the object, which will provide initial distance-based attenuation curves that blend with the occlusion effect.
Step 3: Implement Raycasting in the Game Engine
In your game engine, write a script that performs a raycast from the listener (player’s audio listener or camera) to each active sound source that should support occlusion. The raycast should check for collision with any physical objects tagged as obstacles (e.g., walls, floors, large objects).
For Unity (C#), a typical implementation might look like this:
// Example: Calculate occlusion value for a single sound source
public float CalculateOcclusionValue(Vector3 listenerPos, Vector3 sourcePos)
{
RaycastHit hit;
Vector3 direction = sourcePos - listenerPos;
float distance = direction.magnitude;
if (Physics.Raycast(listenerPos, direction.normalized, out hit, distance))
{
// An obstacle was hit – calculate occlusion based on hit distance and material
// For simplicity, return 1 if anything is hit, but more nuanced values can be used.
return 1.0f;
}
return 0.0f;
}
This basic approach returns binary occlusion (1.0 if hit, 0.0 if clear). For more realistic results, you can cast multiple rays (e.g., a box of rays around the listener) and average the hits, or use the distance from the hit point to determine gradual occlusion. You can also differentiate between materials – concrete blocks more sound than a thin curtain – by checking the collider’s tag or material property.
Important: Perform raycasts in a performance-friendly manner. Use object caching, spatial hashing, or a dedicated occlusion system (e.g., Unity’s built-in occlusion culling for audio, though Wwise often provides better results). Avoid heavy raycasting every frame for all sources; instead, update only when sources or listener move significantly, or use a fixed update rate (e.g., 10 Hz).
Step 4: Send Occlusion Data to Wwise via RTPC
Once your raycast calculation produces an occlusion value (typically a float between 0.0 and 1.0), you need to send it to Wwise using the Wwise API. In most engines, this is done by calling AkSoundEngine.SetRTPCValue(). Define a custom RTPC name in Wwise, such as “Occlusion_Value”, and associate it with the effect parameters you set up in Step 1.
In Unity C#, the call might be:
AkSoundEngine.SetRTPCValue("Occlusion_Value", occlusionValue, gameObject);
Replace gameObject with the GameObject emitting the sound (that has an AkGameObj component attached). This ensures the RTPC applies only to that specific source. For global listener occlusion (e.g., when the player is underwater), you can omit the game object parameter to set a global value.
In Unreal Engine, the equivalent call uses AK::SoundEngine::SetRTPCValue() with an AkGameObjectID. Both engines provide Blueprint or C++ nodes for this purpose.
Creating the RTPC in Wwise
Back in the Wwise authoring tool, create a new RTPC: go to Project > Game Syncs > Real-Time Parameters. Add a new RTPC named “Occlusion_Value”. Set its default value to 0 and define a range from 0 to 1. Then, in the effect of your occlusion bus, bind the low-pass filter’s cutoff frequency parameter to this RTPC. Similarly, you can bind a gain parameter to reduce volume as occlusion increases.
Step 5: Adjust Attenuation and Effects
Now you need to fine-tune how the occlusion value affects the sound. In the Occlusion_Bus effect, open the RTPC binding graph for the low-pass filter. The X-axis should be the RTPC value (0 to 1), and the Y-axis the cutoff frequency (e.g., 20,000 Hz at 0, and 500 Hz at 1). You can add intermediate points for a curved transition – for example, gradual drop from 20,000 Hz to 5,000 Hz at 0.5 occlusion, then steeper decline to 500 Hz above 0.9. This creates a more natural sound.
You may also add a second effect for volume reduction. Use a Wwise Meter effect to read the RTPC and drive a gain node. Set gain to 0 dB at 0 occlusion, and -6 dB to -12 dB at full occlusion depending on the material thickness. Remember that occlusion should not completely silence a sound in most games; even a thick wall allows some sound through.
Additionally, consider applying a reverb or delay to the occluded signal to simulate sound reflecting off nearby surfaces. This can be achieved by adding a reverb effect on the occlusion bus at a low mix level, or by using a second send to a reverb bus.
Best Practice: Always A/B test your occlusion settings in the game world. Use the Wwise Profiler to monitor RTPC values, bus output levels, and CPU usage. The real-time bi‑directional connectivity between Wwise and the game engine is invaluable for iteration.
Step 6: Testing and Refinement
With the basic pipeline in place, begin testing inside your game environment. Walk your character behind walls, pillars, and other obstacles while listening to a source that plays continuously (e.g., an ambient loop or a test tone). Evaluate how naturally the sound transitions from clear to occluded and back.
Common issues and their solutions:
- Too abrupt transitions: Add smoothing (linear interpolation) to the occlusion value in your script, or use Wwise’s built-in RTPC smoothing. A small delay (50–100 ms) makes the change feel more organic.
- Occlusion not triggered by thin objects: Adjust raycast layer masks and collider sizes. Ensure your obstacles have appropriate colliders and are on a layer that the raycast checks.
- Performance spikes: Limit occlusion updates to once every 0.1 to 0.2 seconds for distant sources, or implement a system that only updates when the source’s position relative to the listener changes significantly.
- No audible effect: Verify that the RTPC name in your script matches exactly with the one in Wwise (case‑sensitive). Check that the occlusion bus has its volume enabled and the effect is active.
- All sources sound occluded: Ensure your raycast origin is correct (usually the camera’s position for first‑person, or the character’s ear location). Also check that you are not setting a global RTPC value that overrides local ones.
Iterate on the raycast parameters, RTPC curves, and effect mix until the occlusion feels convincing but not distracting. The goal is for players to instinctively know there is an obstacle between them and the sound source without needing to see it.
Advanced Considerations
Dynamic Obstacles
If your game includes moving obstacles (doors, vehicles, debris), ensure the occlusion system updates in real time. Use a trigger that recalculates occlusion when the obstacle changes position. This can be done by marking dynamic objects and updating their occlusion status via a separate script that forces a raycast refresh.
Multiple Listeners and Split Screen
For cooperative or multiplayer games with separate listeners, each listener must have its own occlusion calculation. Send individual RTPC values per listener by using different RTPC names or by associating the value with the listener’s AkGameObj. Wwise supports per‑listener audio processing, so plan your setup accordingly.
Occlusion for Ambisonics and 3D Audio
If using spatial audio features like Ambisonics or binaural rendering, occlusion bus effects should be applied before the spatializer processing. In Wwise, ensure the occlusion bus is placed early in the signal chain (e.g., as a ShareSet on the source’s output bus) so that the spatializer receives the muffled signal and places it correctly in 3D space.
Conclusion
Implementing real-time audio occlusion in Wwise involves creating dedicated buses, scripting environment interactions, and fine-tuning effects. With these steps, you can significantly enhance the realism of your game’s audio experience, making it more immersive for players. By dynamically adjusting sound based on physical obstacles, you help players better understand their surroundings and react intuitively. Remember to iterate often, profile performance, and test in representative game scenarios. For more information, consult the Wwise documentation on occlusion and obstruction, Unity’s AudioListener reference, or Unreal Engine’s Wwise integration guide.