Implicit geometry (Dr.Jit)
rayd.drjit SdfGrid, SurfelCloud, SurfelGeometry, SurfelAppearance, SurfelScene, and MixedScene - classes, options, methods, and result records.
This page covers signed-distance grids, surfels, and mixed scenes in rayd.drjit. For a walkthrough, see Use SDF grids and surfels. Each query has a detached overload (Ray, drjit.cuda arrays) and an AD overload (RayAD, drjit.cuda.ad arrays).
SdfGrid#
SdfGrid(values: Float, nx: int, ny: int, nz: int, position: Array3f, rotation: Float, scale: Array3f)A signed-distance field sampled on a regular grid in an oriented box. Pass drjit.cuda.ad arrays to make the values or the placement differentiable.
nx * ny * nz vertex-centered samples, index (i * ny + j) * nz + k. Negative inside the surface, in world-space distance units.
Grid resolution per axis.
Center of the box.
Four entries: a scalar-first unit quaternion (qw, qx, qy, qz).
Full side lengths of the box.
Read-only attributes: nx, ny, nz, value_count, values, position, rotation, scale.
SdfGrid.intersect#
intersect(ray: Ray, options: SdfTraceOptions = SdfTraceOptions(), active: Bool = True) -> SdfIntersectionSphere-traces each ray against the trilinearly interpolated field. Returns an SdfIntersection.
SdfGrid.visible#
visible(start: Array3f, end: Array3f, options: SdfTraceOptions = SdfTraceOptions(), active: Bool = True) -> BoolTrue where the segment does not cross the surface.
SdfGrid.trace_reflections#
trace_reflections(ray: Ray, max_bounces: int, options: SdfTraceOptions = SdfTraceOptions(), active: Bool = True) -> ReflectionChainSpecular reflections off the SDF surface, in the ReflectionChain layout.
SdfTraceOptions#
| Field | Default | Meaning |
|---|---|---|
max_steps | 64 | maximum sphere-tracing steps |
relaxation | 0.9 | fraction of the sampled distance to step |
eps_hit | -1 | hit threshold; a negative value derives it from the grid on the device |
SdfIntersection#
t, hit_mask, position, normal (from the field gradient), steps (steps taken). is_valid() returns the hit mask.
Surfels#
SurfelCloud#
SurfelCloud(center: Array3f, tangent_u: Array3f, tangent_v: Array3f, opacity: Float = [], value: Float = [])Flat Gaussian discs. tangent_u and tangent_v are the two Gaussian axes and set the orientation and extent. opacity and value have one entry per surfel. surfel_count returns the count. Pass drjit.cuda.ad arrays for a differentiable cloud.
Raises RuntimeError when value or opacity has a different lane count than center.
SurfelGeometry#
SurfelGeometry(center: Array3f, tangent_u: Array3f, tangent_v: Array3f)Surfel geometry without appearance, for use with SurfelAppearance.
SurfelAppearance#
SurfelAppearance(opacity: Float, values: Float, color_model: SurfelColorModel, channel_count: int, sh_degree: int = 0)
SurfelAppearance.rgb(opacity: Float, rgb: Array3f) -> SurfelAppearance
SurfelAppearance.features(opacity: Float, values: Float, channel_count: int) -> SurfelAppearance
SurfelAppearance.sh(opacity: Float, coeffs: Float, sh_degree: int) -> SurfelAppearanceOpacity and color per surfel. SurfelColorModel is ConstantRGB, SH (spherical harmonics), or FeatureChannels.
SurfelScene#
SurfelScene(cloud: SurfelCloud | SurfelGeometry, options: SurfelTraceOptions = SurfelTraceOptions())Acceleration structure over a surfel cloud. Call build() before queries.
| Method | Returns |
|---|---|
build() -> None | builds the proxy geometry |
is_ready() -> bool | built and current |
intersect(ray, active=True) | SurfelIntersection: first surfel hit |
shadow_test(ray, active=True) | Bool |
visible(start, end, active=True) | Bool |
trace_reflections(ray, max_bounces, active=True) | ReflectionChain |
composite_alpha(ray, active=True) | SurfelComposite: front-to-back alpha blending |
composite_alpha_reference(ray, active=True) | SurfelComposite from a reference implementation, for testing |
render(ray, render_options=SurfelRenderOptions(), active=True) | SurfelRender |
update_geometry(geometry: SurfelGeometry) -> None | replaces the geometry |
update_appearance(appearance: SurfelAppearance) -> None | replaces the appearance |
Properties: surfel_count, triangle_count (proxy triangles), build_count.
SurfelTraceOptions#
| Field | Default | Meaning |
|---|---|---|
alpha_min | 1/255 | minimum Gaussian alpha included in the proxy and in compositing |
cutoff | inf | optional local-radius cap, for debugging; inf disables it |
alpha_cap | 0.99 | maximum alpha of one surfel hit |
proxy_epsilon | 1e-3 | normal-axis thickness of the Icosahedron20 proxy, relative to the Gaussian radius |
max_candidate_hits | 8 | per-ray candidate buffer size for detached compositing |
primitive_mode | Icosahedron20 | proxy shape: Icosahedron20, QuadTriangles, or SingleTriangle |
face_forward | True | face-forward the surfel normal |
single_launch | True | use the native OptiX surfel pipeline for detached intersect and compositing; AD compositing keeps the reference path |
collect_candidate_stats | False | collect per-ray candidate buffer diagnostics |
opacity_aware_proxy_bounds | False | use per-surfel opacity when building proxy bounds |
continue_after_full_buffer | False | keep tracing after a full candidate buffer until transmittance is low enough |
transmittance_min | 0.03 | stop compositing below this transmittance |
max_trace_segments | 4 | maximum trace segments per ray |
SurfelRenderOptions#
| Field | Default | Meaning |
|---|---|---|
mode | SurfelRenderMode.RGB | RGB, Alpha, Depth, RGBDepth, or Feature |
color_model | ConstantRGB | color model |
normal | False | also render normals |
sh_degree | 0 | spherical-harmonic degree |
channel_count | 3 | output channels |
channel_chunk | 0 | channel chunk size for feature rendering |
background_rgb | (0, 0, 0) | background color |
Constructors: SurfelRenderOptions.rgb(sh_degree=0, background_rgb=[0, 0, 0], normal=False) and SurfelRenderOptions.feature(channel_count).
Surfel result records#
| Record | Fields |
|---|---|
SurfelIntersection | t, p, n, local_uv, gaussian_weight, opacity, alpha, value, surfel_id, triangle_id; is_valid() |
SurfelComposite | intensity, alpha, transmittance, depth, candidate_count, candidate_buffer_full; is_valid() |
SurfelRender | channels, rgb, normal, alpha, transmittance, depth, candidate_count, candidate_buffer_full, channel_count; is_valid() |
cloud = rd.SurfelCloud(center, tangent_u, tangent_v, opacity)
scene = rd.SurfelScene(cloud)
scene.build()
comp = scene.composite_alpha(ray)MixedScene#
MixedScene(trace_backend: str = "auto", edge_bvh_backend: str = "auto")Meshes, SDF grids, and surfel clouds in one scene. Note the argument order matches the Torch Scene, not the Dr.Jit Scene; pass them by keyword.
| Method | Returns |
|---|---|
add_mesh(mesh: Mesh, dynamic: bool = False) | geometry id |
add_sdf(grid: SdfGrid, options: SdfTraceOptions = SdfTraceOptions()) | geometry id |
add_surfel(cloud: SurfelCloud, options: SurfelTraceOptions = SurfelTraceOptions()) | geometry id |
build() -> None | builds all parts |
is_ready() -> bool | built and current |
intersect(ray, active=True, flags=RayFlags.All) | Intersection: nearest hit over all geometry |
visible(start, end, active=True) | SegmentVisibility |
trace_reflections(ray, max_bounces, active=True) | ReflectionChain |
transmittance(ray, active=True) | Float: fraction of light that passes |
Properties: num_meshes, num_sdfs, num_surfel_scenes. There are no edge or diffraction methods.