Multipath

Reflection and diffraction path tracing in RayD

Overview#

RayD exposes low-level multipath primitives for building custom wave simulators. These APIs enumerate geometric paths and accumulate field contributions — they do not implement a complete propagation model. The caller owns the source model, receiver model, material policy, and optimization loop.

There are two categories:

  • trace_* — enumerate geometric or field paths, return per-ray records
  • accum_* — launch native accumulation kernels that reduce contributions into grid cells

Reflection Path Tracing#

Trace specular reflection chains using image sources:

chain = scene.trace_reflections(ray, max_bounces=2)
ParameterTypeDefaultDescription
rayRay or RayADrequiredRays to trace
max_bouncesintrequiredMaximum reflection bounces
optionsReflectionTraceOptions | NoneNoneOptional trace options
activeMaskTruePer-ray active mask
symbolicboolTrueUse symbolic Dr.Jit recording

Returns ReflectionChain (or ReflectionChainAD).

ReflectionChain fields#

FieldDescription
tHit distances per bounce
hit_pointsHit positions per bounce
geo_normalsGeometric normals per bounce
image_sourcesImage source positions per bounce
plane_pointsReflection plane points per bounce
plane_normalsReflection plane normals per bounce
shape_idsMesh indices per bounce
global_prim_idsGlobal primitive indices per bounce
bounce_countNumber of valid bounces per ray
ray_countTotal number of rays

ReflectionTraceOptions#

options = rd.ReflectionTraceOptions()
options.deduplicate = True
options.image_source_tolerance = 1e-5
FieldDefaultDescription
deduplicateFalseRemove duplicate reflection paths
image_source_tolerance1e-5Tolerance for image source deduplication
export_mode—Controls export verbosity

Reflection Accumulation#

Accumulate reflected field or power onto a receiver grid — the high-throughput path when individual path records are not needed:

grid = rd.AccumGrid()
grid.axis = 2           # z axis
grid.position = 1.5
grid.coord0_min = -5.0
grid.coord0_max = 5.0
grid.coord1_min = -5.0
grid.coord1_max = 5.0
grid.resolution0 = 32
grid.resolution1 = 32
 
material = rd.MaterialAD()
material.eta_r = ...
material.sigma = ...
material.mu_r = ...
material.gain = ...
material.valid = ...
 
options = rd.AccumOptions()
options.wavelength = 0.086
options.k = 73.0
options.solid_angle_per_ray = ...
options.cell_area = ...
options.seed = 0
 
result = scene.accumulate_reflections(
    ray, tx_position, grid, material, max_bounces=2, options=options
)

Returns AccumResult with:

FieldDescription
reflection_powerAccumulated power per grid cell
reflection_field_x/y/zAccumulated field components per grid cell
reflection_countNumber of reflections per grid cell
ray_countTotal rays launched

Equivalent Path Correction (EPC)#

EPC traces reflection paths toward a specific receiver point, correcting for path equivalence:

result = scene.trace_refl_epc(ray, receiver, max_bounces=2)

Returns ReflEpc with reflection points, path lengths, and primitive IDs per bounce.

For the complex field version:

options = rd.ReflEpcFieldOptions()
options.wavelength = 0.086
options.omega = 2 * math.pi * frequency
# ... set material slot fields ...
 
result = scene.trace_refl_epc_field(ray, receiver, max_bounces=2, options=options)

Returns ReflEpcField with complex field components field_x_re/im, field_y_re/im, field_z_re/im.

Diffraction Accumulation#

Native diffraction grid accumulation for order-1 chains:

result = scene.accum_dfr_direct(states, grid, material, options)

For order-2/3 chains:

result = scene.accum_dfr(initial_states, recursive_states, grid, material, options)

Both return DfrAccum with:

FieldDescription
powerAccumulated diffraction power per grid cell
field_x/y/zAccumulated field components
direct_countDirect diffraction contributions
keller_countKeller diffraction contributions
suffix_countSuffix-reflection contributions

Diffraction Path Export#

Export compact first-order diffraction paths:

paths = scene.trace_dfr_paths(tx_positions, rx_positions, states, material, options)

Returns DfrPaths with per-path fields: delay, field_x/y/z, order, edge0/1/2, p0/1/2.

AD Support#

All multipath APIs accept both non-AD and AD inputs. Geometric outputs carry Dr.Jit gradients. Discrete path selection decisions run detached.

APIAD support
trace_reflections()Geometric AD
accumulate_reflections()Native AD
trace_refl_epc()Detached only
trace_refl_epc_field()Native AD
accum_dfr_direct()Native AD
accum_dfr()Native AD
trace_dfr_paths()Geometric AD

Next Steps#