A raytracing context is a standalone world, composed of:
- many primitives (spheres, prisms, etc)
- many voices (3D positions that rays will attempt to discover)
- a single listener
A context must be initialised with a settings object:
<div data-tabs="create-context" markdown="1">
<div data-tab="C#" markdown="1">
```cs
var settings = new RaytracingContextSettings()
{
worldPosition = new Vector3F(0, 0, 0),
worldSize = new Vector3F(100, 100, 100)
};
// Throws an exception if the settings are invalid
var context = new RaytracingContext(settings);
```
</div>
<div data-tab="C" markdown="1">
```c
RaytracingContextSettings* settings = raytracing_context_settings_create();
settings->world_position = vector3f_create(0, 0, 0);
settings->world_size = vector3f_create(100, 100, 100);
// Validate settings manually
ValidationResult result = validate_raytracing_context_settings(settings);
if (!result.is_valid)
{
printf(result.error_message);
return;
}
RaytracingContext* context = raytracing_context_create(settings);
// Must free this yourself
free(settings);
```
</div>
</div>
After a context is created, its settings object is no longer used. To update settings after a context is created, see [[Updating Raytracing Settings]].
## Settings List
<div data-tabs="settings-list" markdown="1">
<div data-tab="C#" markdown="1">
```csharp
public class RaytracingContextSettings
{
/// <summary>
/// The minimum bounds of the world. <see cref="Voice"/>s outside the world will not be raytraced, and <see cref="Primitive"/>s that are fully outside these bounds will be ignored.
/// </summary>
public Vector3F worldPosition;
/// <summary>
/// The size of the world. <see cref="Voice"/>s outside the world will not be raytraced, and <see cref="Primitive"/>s that are fully outside these bounds will be ignored.
/// </summary>
public Vector3F worldSize;
/// <summary>
/// When true, <see cref="Voice"/>s outside the world will have 0 occlusion and 0 permeation energy. When false, they will have maximum occlusion and permeation energy.
/// </summary>
public bool voicesOutsideTheWorldAreMuffled;
/// <summary>
/// A custom string logging callback. Defaults to Console.WriteLine
/// </summary>
public Action<string> logCallback;
/// <summary>
/// Whether to create a separate window to display the low-poly world used by the raytracing simulation. Only available in dev builds.
/// </summary>
public bool renderingEnabled;
/// <summary>
/// The number of work items to split trails across for load balancing. <br />
/// Example: 1024 trails / 128 work items = 8 trails per item. <br />
/// With 4 threads: 128 / 4 = 32 work items per thread. <br />
/// A high workItemCount helps evenly distribute work across all threads.
/// </summary>
public int workItemCount = 128;
/// <summary>
/// The maximum amount of threads that can run at any one time
/// </summary>
public int maximumConcurrencyLevel = ThreadStatistics.BackgroundThreadCount;
/// <summary>
/// The maximum number of <see cref="Voice"/>s that can be active at once. Increasing this value will increase memory usage.
/// </summary>
public int maxVoices;
/// <summary>
/// The number of trails, evaluated as max(reverbRayCount, occlusionRayCount, permeationRayCount)
/// </summary>
public int trailRayCount => Math.Max(reverbRayCount, Math.Max(occlusionRayCount, permeationRayCount));
/// <summary>
/// The number of times a ray will bounce to form a trail
/// </summary>
public int trailBounceCount;
/// <summary>
/// The number of trails that will cast reverb rays back towards the listener. <br />
/// e.g. with 1024 trails and reverbRayCount as 512, every 2nd trail will cast reverb rays back towards the listener
/// </summary>
public int reverbRayCount;
/// <summary>
/// The number of trails that will cast line-of-sight rays towards each <see cref="Voice"/>. <br />
/// e.g. with 1024 trails and occlusionRayCount as 512, every 2nd trail will cast line-of-sight rays towards each <see cref="Voice"/>
/// </summary>
public int occlusionRayCount;
/// <summary>
/// The number of trails that will cast permeation rays towards each <see cref="Voice"/>. <br />
/// e.g. with 1024 trails and occlusionRayCount as 512, every 2nd trail will cast line-of-sight rays towards each <see cref="Voice"/>
/// </summary>
/// <remarks>
/// Permeation rays are only cast on the first bounce of the trail.
/// </remarks>
public int permeationRayCount;
/// <summary>
/// The number of trails that are rebuilt from scratch each frame. <br />
/// This prevents trails from becoming stale when the listener moves far away.
/// </summary>
public int refreshRayCount = 16;
/// <summary>
/// [Optional] The number of rays cast outwards from each <see cref="Voice"/>, to determine reverb properties of the environment around them.
/// </summary>
public int voiceReverbRayCount;
/// <summary>
/// [Optional] The number of times a ray will bounce to form a trail
/// </summary>
public int voiceReverbBounceCount;
/// <summary>
/// The number of trails that are rebuilt from scratch each frame.
/// </summary>
public int voiceReverbRefreshRayCount = 1;
/// <summary>
/// The number of shared EAX reverb presets to create for all voices. <br />
/// Higher values will increase accuracy but it is expensive to run many EAX reverb effects in real time. <br />
/// Each voice will use the preset that best matches its environment, accesible via <see cref="Voice.groupedEAXIndex"/>.
/// </summary>
public int groupedEAXPropertiesAmount = 2;
/// <summary>
/// Permeation rays with energy below this threshold are cancelled to prevent unnecessary traversal
/// </summary>
public float minimumPermeationEnergy = 0.01f;
/// <summary>
/// Air absorption settings. Set this to null to disable air absorption
/// </summary>
public AirAbsorptionSettings airAbsorption = new();
/// <summary>
/// Material settings. Use this object to customise existing materials and define new ones
/// </summary>
public MaterialSettings materials = new();
/// <summary>
/// When true, prioritizes raytracing new <see cref="Voice"/>s over updating existing ones to reduce playback latency.
/// </summary>
public bool prioritiseNewVoices;
/// <summary>
/// The number of new voices to raytrace per frame. <br />
/// Lower values reduce playback latency for new <see cref="Voice"/>s.
/// </summary>
public int maxNewVoiceBatchSize = 4;
/// <summary>
/// Meters per world unit. Affects air absorption and reverb calculation.
/// </summary>
public float metersPerUnit = 1;
/// <summary>
/// Inverse speed of sound in seconds per meter (defaults to 1 / 343.0f). Affects reverb calculation.
/// </summary>
public float speedOfSound = 1.0f / 343.0f;
/// <summary>
/// Low-frequency reference (Hz) for air absorption, reverb, and material scattering (ScatteringLF).
/// </summary>
public float referenceFrequencyLF = 300;
/// <summary>
/// High-frequency reference (Hz) for air absorption, reverb, and material scattering (ScatteringHF).
/// </summary>
public float referenceFrequencyHF = 4000;
/// <summary>
/// Custom formulas for calculating EAX properties (diffusion, density, etc)
/// </summary>
public CustomEAXFormulas customEaxFormulas;
/// <summary>
/// Custom formula for calculating a <see cref="Voice"/>'s muffling percentage. <br />
/// Parameters: (int voiceType, int occlusionRayCount, int permeationRayCount, float occlusionEnergy, float permeationEnergy)
/// Returns: float
/// </summary>
public Func<int, int, int, float, float, float> voiceEnergyFormula;
/// <summary>
/// Validates this settings object.
/// </summary>
/// <exception cref="An ArgumentException is thrown when a parameter is invalid."></exception>
/// <exception cref="An InvalidOperationException is thrown when renderingEnabled is true and another context already has a rendering window."></exception>
public void Validate()
}
```
</div>
<div data-tab="C" markdown="1">
```c
typedef struct RaytracingContextSettings
{
// The minimum bounds of the world. Voices outside the world will not be raytraced, and Primitives that are fully outside these bounds will be ignored.
Vector3F world_position;
// The size of the world. Voices outside the world will not be raytraced, and Primitives that are fully outside these bounds will be ignored.
Vector3F world_size;
// A custom string logging callback. Defaults to Console.WriteLine
void (*log_callback)(const char* message);
// The number of work items to split trails across for load balancing.
// Example: 1024 trails / 128 work items = 8 trails per item.
// With 4 threads: 128 / 4 = 32 work items per thread.
// A high work_item_count helps evenly distribute work across all threads.
int work_item_count;
// The maximum amount of threads that can run at any one time
int maximum_concurrency_level;
// The maximum number of Voices that can be active at once. Increasing this value will increase memory usage.
int max_voices;
// The number of times a ray will bounce to form a trail
int trail_bounce_count;
// The number of trails that will cast reverb rays back towards the listener.
// e.g. with 1024 trails and reverb_ray_count as 512, every 2nd trail will cast reverb rays back towards the listener
int reverb_ray_count;
// The number of trails that will cast line-of-sight rays towards each Voice.
// e.g. with 1024 trails and occlusion_ray_count as 512, every 2nd trail will cast line-of-sight rays towards each Voice
int occlusion_ray_count;
// The number of trails that will cast permeation rays towards each Voice.
// e.g. with 1024 trails and permeation_ray_count as 512, every 2nd trail will cast line-of-sight rays towards each Voice
// NOTE: Permeation rays are only cast on the first bounce of the trail.
int permeation_ray_count;
// The number of trails that are rebuilt from scratch each frame.
// This prevents trails from becoming stale when the listener moves far away.
int refresh_ray_count;
// [Optional] The number of rays cast outwards from each Voice, to determine reverb properties of the environment around them.
int voice_reverb_ray_count;
// [Optional] The number of times a ray will bounce to form a trail
int voice_reverb_bounce_count;
// The number of trails that are rebuilt from scratch each frame.
int voice_reverb_refresh_ray_count;
// The maximum number of shared EAX reverb presets to create for all voices.
// Higher values will increase accuracy but it is expensive to run many EAX reverb effects in real time.
// Each voice will use the preset that best matches its environment, accessible via Voice.blended_eax_index.
int maximum_grouped_eax_count;
// Permeation rays with energy below this threshold are cancelled to prevent unnecessary traversal
float minimum_permeation_energy;
// The number of new voices to raytrace per frame.
// Lower values reduce playback latency for new Voices.
int max_new_voice_batch_size;
// Meters per world unit. Affects air absorption and reverb calculation.
float meters_per_unit;
// Inverse speed of sound in seconds per meter (defaults to 1 / 343.0f). Affects reverb calculation.
float speed_of_sound;
// Low-frequency reference (Hz) for air absorption, reverb, and material scattering (ScatteringLF).
float reference_frequency_lf;
// High-frequency reference (Hz) for air absorption, reverb, and material scattering (ScatteringHF).
float reference_frequency_hf;
// Air absorption settings. Set this to null to disable air absorption
AirAbsorptionSettings* air_absorption;
// Material settings. Use this object to customise existing materials and define new ones
MaterialSettings* material_settings;
// Custom formulas for calculating EAX properties (diffusion, density, etc)
CustomEAXFormulas* custom_eax_formulas;
// Custom formula for calculating a Voice's muffling percentage.
// Parameters: (int voice_type, int occlusion_ray_count, int permeation_ray_count, float occlusion_energy, float permeation_energy)
// Returns: float
float (*voice_energy_formula)(int voice_type, int occlusion_ray_count, int permeation_ray_count, float occlusion_energy, float permeation_energy);
// When true, prioritizes raytracing new Voices over updating existing ones to reduce playback latency.
bool prioritise_new_voices;
// When true, Voices outside the world will have 0 occlusion and 0 permeation energy. When false, they will have maximum occlusion and permeation energy.
bool voices_outside_the_world_are_muffled;
} RaytracingContextSettings;
```
</div>
</div>
## workItemCount
This setting controls how raytracing work is divided across multiple background threads. If you have 8 threads, it seems logical to split the work into 8 work items (one for each thread).
However some threads might finish earlier than others. To prevent threads from idling while other threads work, you can divide the raytracing work into smaller work items.
To do this, set `workItemCount` to a number higher than `maximumConcurrencyLevel`. For example, if you have:
- `trailRayCount` = 1024
- `workItemCount` = 128
- `maximumConcurrencyLevel` = 8
This means that each work item will contain 1024 / 128 = 8 trails, and the threads have a pool of 128 work items to choose from.
Read more: [[Threading Architecture]].
## trailBounceCount
Controls how many times rays will bounce to form a trail.
Read more: [[Trail-Based Raytracing]].
## reverbRayCount, occlusionRayCount and permeationRayCount
These settings control how many rays are used for reverb, occlusion and permeation.
You can also disable reverb/occlusion/permeation by providing `0` for the ray count.
I recommend experimenting with these settings to figure out how many rays you need for your game.
## voiceReverbRayCount and voiceReverbBounceCount
Rays can also be cast outwards from each voice to determine reverb properties of the environment around it.
To enable this, set both `voiceReverbRayCount` and `voiceReverbBounceCount` to a value higher than zero.
Read more: [[Per-Voice Reverb]].
## airAbsorption
There is an in-built air absorption formula based on humidity, temperature and pressure. You can adjust each value via this `airAbsorption` object.
You can also provide a custom formula for air absorption.
Read more: [[Air Absorption]]
## materials
Customise absorption, scattering and transmission values for existing materials, or create new materials.
Read more: [[Materials]]
## customEaxFormulas
This class provides custom formulas for calculating EAX reverb properties.
Read more: [[Custom EAX Formulas]]
## voiceEnergyFormula
This function converts energy values to a muffling percentage.
Read more: [[Voice Energy Formula]]