Skip to content

Add PBRT v4 scene importer#292

Merged
jeffamstutz merged 1 commit into
NVIDIA:next_releasefrom
tarcila:pbrt-v4-importer
May 13, 2026
Merged

Add PBRT v4 scene importer#292
jeffamstutz merged 1 commit into
NVIDIA:next_releasefrom
tarcila:pbrt-v4-importer

Conversation

@tarcila
Copy link
Copy Markdown
Collaborator

@tarcila tarcila commented May 13, 2026

Parses .pbrt files (including Include/Import with cycle detection) and maps them onto TSD's ANARI-mirrored scene.
Built around a stream Lexer, a recursive-descent Parser preserving PBRT v4 typed-parameter qualifiers ("rgb", "spectrum", "blackbody", "texture", "float", ...), and a scene walker (import_PBRT.cpp) that emits TSD geometries, materials, lights and a camera. Scene-relative file references are sandboxed (resolveScenePath rejects absolute paths). ObjectInstance templates are built once and shared across instances.

Supported

  • Directives: WorldBegin/End, AttributeBegin/End, TransformBegin/End, ObjectBegin/End, ObjectInstance, MediumInterface, MakeNamedMedium, ReverseOrientation, Option, all transform directives (Identity, Transform, ConcatTransform, Translate, Scale, Rotate, LookAt, CoordinateSystem, CoordSysTransform), Include/Import.
  • Shapes: trianglemesh, plymesh (tinyply, with N / uv / vertex_index variants), sphere, cylinder, disk (with annulus and phimax), curve (bezier and bspline; 4 control points), bilinearmesh (triangulated), loopsubdiv (passed through as the control mesh).
  • Materials: diffuse, coateddiffuse, conductor, dielectric, thindielectric, diffusetransmission, coatedconductor, interface, mix (full RGB lerp; texture-driven amount baked into the mask sampler for baseColor).
  • Textures: imagemap (with sRGB vs linear selection, uscale/vscale/ udelta/vdelta UV transform, grayscale-to-RGB broadcast via outTransform), constant, scale chains (PBRT v4 'tex'/'scale' slots, affine-baked into the sampler), mix of constant + textured.
  • Normal maps: explicit "normalmap" path, plus a fallback that converts a "texture displacement" height map into a tangent-space normal via central differences.
  • Per-shape alpha: float cutoff or texture (alphaMode = mask), with baseColor.w neutralised so RGBA leaves don't double-apply alpha.
  • Lights: distant, point, spot, infinite (HDRI; equal-area sphere maps auto-converted to equirectangular). Area lights become emissive physicallyBased materials. Emission values honour "rgb"/"color"/"xyz", "blackbody" (Tanner Helland approximation), and sampled-spectrum inputs (averaged), with the PBRT "scale" parameter and film ISO applied as exposure.
  • Volumes: homogeneous media via KHR_materials_volume (attenuationColor = exp(-sigma_a), attenuationDistance = 1) on dielectric / thindielectric / interface.
  • Camera: perspective (with portrait-aware fov->fovy conversion), orthographic, depth of field via lensradius/focaldistance, shutter window.

Approximations and limitations

  • Geometric displacement is not real displacement — converted to a tangent-space bump-normal map (kBumpStrength=16) since ANARI has no equivalent.
  • Ribbon curves rendered as cylinder curves; only 4 control points are accepted per curve.
  • ReverseOrientation is only honoured on trianglemesh, plymesh and disk; other shape types log a warning.
  • 'scale' or 'mix' of two image textures collapses to a single sampler with the second's tint applied (ANARI samplers can't chain).
  • 'mix' material can only carry a texture-driven amount on baseColor; metallic/roughness/specular/clearcoat/transmission/ior collapse to a uniform lerp at the chosen amount.
  • Sampled spectra are approximated as the mean of their sample values (grayscale); named spectra (e.g. "spectrum L" "stdillum-D65") are unsupported and fall back to a neutral default.
  • Dielectric IOR is capped at 2.5 — single-scalar IOR plus ANARI volumes can't reproduce PBRT's spectral path tracing at higher eta.
  • Conductor 'eta' "metal-*-eta" named spectra are mapped to fixed normal-incidence RGB approximations (Cu/Au/Ag/Fe/Cr/Ni/Ti/Pt, default aluminium); roughness textures are supported.
  • subsurface, measured and hair materials are heuristic stand-ins (white glossy / matte) — no SSS, no tabulated BSDF playback, no hair scattering.
  • Heterogeneous media, emissive media, and sigma_s scattering are unsupported; scattering coefficients are folded into absorption with a warning.
  • Cameras: spherical and realistic types are downgraded to perspective.
  • Integrator, Sampler, PixelFilter, ColorSpace, Accelerator, ActiveTransform and TransformTimes are parsed and discarded — no motion blur, no spectral integration, no custom samplers.
  • The animation manager parameter is unused; no keyframe data is emitted.

Parses .pbrt files (including Include/Import with cycle detection) and
maps them onto TSD's ANARI-mirrored scene. Built around a stream Lexer,
a recursive-descent Parser preserving PBRT v4 typed-parameter qualifiers
("rgb", "spectrum", "blackbody", "texture", "float", ...), and a scene
walker (import_PBRT.cpp) that emits TSD geometries, materials, lights
and a camera. Scene-relative file references are sandboxed
(resolveScenePath rejects absolute paths). ObjectInstance templates are
built once and shared across instances.

Supported
- Directives: WorldBegin/End, AttributeBegin/End, TransformBegin/End,
  ObjectBegin/End, ObjectInstance, MediumInterface, MakeNamedMedium,
  ReverseOrientation, Option, all transform directives (Identity,
  Transform, ConcatTransform, Translate, Scale, Rotate, LookAt,
  CoordinateSystem, CoordSysTransform), Include/Import.
- Shapes: trianglemesh, plymesh (tinyply, with N / uv / vertex_index
  variants), sphere, cylinder, disk (with annulus and phimax), curve
  (bezier and bspline; 4 control points), bilinearmesh (triangulated),
  loopsubdiv (passed through as the control mesh).
- Materials: diffuse, coateddiffuse, conductor, dielectric,
  thindielectric, diffusetransmission, coatedconductor, interface, mix
  (full RGB lerp; texture-driven amount baked into the mask sampler for
  baseColor).
- Textures: imagemap (with sRGB vs linear selection, uscale/vscale/
  udelta/vdelta UV transform, grayscale-to-RGB broadcast via
  outTransform), constant, scale chains (PBRT v4 'tex'/'scale' slots,
  affine-baked into the sampler), mix of constant + textured.
- Normal maps: explicit "normalmap" path, plus a fallback that converts
  a "texture displacement" height map into a tangent-space normal via
  central differences.
- Per-shape alpha: float cutoff or texture (alphaMode = mask), with
  baseColor.w neutralised so RGBA leaves don't double-apply alpha.
- Lights: distant, point, spot, infinite (HDRI; equal-area sphere maps
  auto-converted to equirectangular). Area lights become emissive
  physicallyBased materials. Emission values honour "rgb"/"color"/"xyz",
  "blackbody" (Tanner Helland approximation), and sampled-spectrum
  inputs (averaged), with the PBRT "scale" parameter and film ISO
  applied as exposure.
- Volumes: homogeneous media via KHR_materials_volume
  (attenuationColor = exp(-sigma_a), attenuationDistance = 1) on
  dielectric / thindielectric / interface.
- Camera: perspective (with portrait-aware fov->fovy conversion),
  orthographic, depth of field via lensradius/focaldistance, shutter
  window.

Approximations and limitations
- Geometric displacement is not real displacement — converted to a
  tangent-space bump-normal map (kBumpStrength=16) since ANARI has no
  equivalent.
- Ribbon curves rendered as cylinder curves; only 4 control points are
  accepted per curve.
- ReverseOrientation is only honoured on trianglemesh, plymesh and
  disk; other shape types log a warning.
- 'scale' or 'mix' of two image textures collapses to a single sampler
  with the second's tint applied (ANARI samplers can't chain).
- 'mix' material can only carry a texture-driven amount on baseColor;
  metallic/roughness/specular/clearcoat/transmission/ior collapse to a
  uniform lerp at the chosen amount.
- Sampled spectra are approximated as the mean of their sample values
  (grayscale); named spectra (e.g. "spectrum L" "stdillum-D65") are
  unsupported and fall back to a neutral default.
- Dielectric IOR is capped at 2.5 — single-scalar IOR plus ANARI
  volumes can't reproduce PBRT's spectral path tracing at higher eta.
- Conductor 'eta' "metal-*-eta" named spectra are mapped to fixed
  normal-incidence RGB approximations (Cu/Au/Ag/Fe/Cr/Ni/Ti/Pt, default
  aluminium); roughness textures are supported.
- subsurface, measured and hair materials are heuristic stand-ins
  (white glossy / matte) — no SSS, no tabulated BSDF playback, no hair
  scattering.
- Heterogeneous media, emissive media, and sigma_s scattering are
  unsupported; scattering coefficients are folded into absorption with
  a warning.
- Cameras: spherical and realistic types are downgraded to perspective.
- Integrator, Sampler, PixelFilter, ColorSpace, Accelerator,
  ActiveTransform and TransformTimes are parsed and discarded — no
  motion blur, no spectral integration, no custom samplers.
- The animation manager parameter is unused; no keyframe data is
  emitted.
@tarcila tarcila requested a review from jeffamstutz May 13, 2026 13:19
Copy link
Copy Markdown
Collaborator

@jeffamstutz jeffamstutz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@jeffamstutz jeffamstutz merged commit 9579b63 into NVIDIA:next_release May 13, 2026
12 checks passed
@tarcila tarcila deleted the pbrt-v4-importer branch May 13, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants