Scene View

template<IsSpectral TSpectral>
class SceneView

View of a scene at a specific time and camera instance.

SceneView collects geometry, lights, unresolved objects, and stars for rendering.

Template Parameters:

TSpectral – The spectral type (e.g., RGB, Visible8)

Public Functions

SceneView(const Scene<TSpectral> &scene, const Interval &exposure_interval, const InstanceHandle<TSpectral> &camera_instance, ObservationMode obs_mode = ObservationMode::ABERRATED_STATE, std::optional<std::size_t> num_temporal_samples = std::nullopt, double motion_tolerance = DEFAULT_MOTION_TOLERANCE)

Construct a SceneView for a given scene, time, camera, and observation mode.

Collects geometry, lights, unresolved objects, and stars for rendering.

Parameters:
  • scene – Scene to view

  • exposure_interval – Exposure interval. Poses set by hand hold at its reference time.

  • camera_instance – Camera instance handle

  • obs_mode – Where each thing is seen: ABERRATED_STATE (the default), with light time and the aberration from the camera’s velocity, as a camera really sees it; GEOMETRIC_STATE, with light time alone; or TRUE_STATE, where it is at the instant

  • num_temporal_samples – The number of temporal samples every moving thing is given, evenly spaced through the exposure, or none (the default) to choose them for each thing: one for whatever does not move in view, and otherwise as many as keep the path it is drawn along within motion_tolerance pixels of its true path (see choose_fractions_()). One sample renders a still frame, at the middle of the exposure, as does turning the camera’s motion blur off (see CameraModel::enable_motion_blur()), whatever number is given.

  • motion_tolerance – How far, in pixels, the path a thing is drawn along may stray from its true path, when the samples are chosen. Positive.

Throws:

std::runtime_error – if the interval ends before it starts, no temporal samples or more than Embree’s 129 are asked for, or the tolerance is not positive and finite.

~SceneView()

Destructor for SceneView, releases TLAS and clears geometry and lights.

SceneView(const SceneView&) = delete
SceneView &operator=(const SceneView&) = delete
SceneView(SceneView&&) = delete
SceneView &operator=(SceneView&&) = delete
HitRecord intersect(const Ray<TSpectral> &ray, float time = 0.5f, unsigned int mask = 0xFFFFFFFF) const

Intersect a ray with the scene and return the hit record.

Parameters:
  • ray – The ray to intersect.

  • time – The time for motion blur.

  • mask – The ray mask: only geometry whose mask shares a bit with it is hit (all, by default).

Returns:

The hit record.

TSpectral evaluate_transmittance(const Ray<TSpectral> &shadow_ray, float t_far, const MediumStack<TSpectral> &initial_stack, RandomSampler<float> &sampler, float time = 0.5f, AlphaMode alpha_mode = AlphaMode::Stochastic) const

Evaluate transmission along a ray.

Parameters:
  • ray – The ray to intersect.

  • t_far – The distance along the ray to evaluate the transmission to.

  • initial_stack – The media the ray starts in.

  • sampler – Random numbers, for the media and for partially opaque surfaces.

  • time – The time for motion blur.

  • alpha_mode – How partially opaque surfaces are passed through.

Returns:

The spectral transmission

Interaction<TSpectral> resolve_hit(const Ray<TSpectral> &ray, const HitRecord &hit) const

Resolve a hit record into a full interaction, including position, normals, UVs, etc.

Parameters:
  • ray – The ray that caused the hit.

  • hit – The hit record to resolve.

Returns:

The resolved interaction.

std::vector<HitRecord> intersect(const std::vector<Ray<TSpectral>> &rays, float time = 0.5f) const

Intersect a batch of rays with the scene and return their hit records.

Parameters:
  • rays – The rays to intersect.

  • time – The time for motion blur.

Returns:

A vector of hit records corresponding to each ray.

std::vector<Interaction<TSpectral>> resolve_hits(const std::vector<Ray<TSpectral>> &rays, const std::vector<HitRecord> &hits) const

Resolve a batch of hit records into full interactions.

Parameters:
  • rays – The rays that caused the hits.

  • hits – The hit records to resolve.

Returns:

A vector of resolved interactions.

inline const std::vector<LightInstance<TSpectral>> &lights() const

The light instances collected for this view.

inline const std::vector<IndirectSourceInstance<TSpectral>> &indirect_sources() const

The designated indirect illumination sources collected for this view.

std::size_t indirect_source_index(const HitRecord &hit) const

Returns the indirect-source index of the instance a hit landed on.

Parameters:

hit – The hit record to classify.

Returns:

Index into indirect_sources(), or NO_INDIRECT_SOURCE if the hit is invalid or not on a designated indirect source.

ObjectIds object_ids(const HitRecord &hit) const

Returns the IDs of the scene objects a hit landed on.

Parameters:

hit – The hit record to identify.

Returns:

The geometry, model, instance and part hit (see ObjectIds), or NO_OBJECT_ID for each if the hit is invalid or on a light.

TSpectral unresolved_irradiance(const InstanceHandle<TSpectral> &instance, const Time &time) const

The irradiance an instance of an unresolved object gives the camera at a time, as this view resolved it.

Between the instance’s temporal samples, the irradiance is interpolated linearly; before the first or after the last, it is held at that sample’s.

Parameters:
  • instance – The instance of the unresolved object, in the scene graph.

  • time – The time at which to query irradiance.

Throws:

std::runtime_error – if the instance does not place an unresolved object in this view.

Returns:

The spectral irradiance at the camera.

TSpectral direct_lit_radiance(const Ray<TSpectral> &ray, const HitRecord &hit, RandomSampler<float> &sampler, float time = 0.5f, const MediumStack<TSpectral> &medium_stack = MediumStack<TSpectral>{}, bool bsdf_ray_follows = false) const

Evaluates the direct (next-event-estimated) radiance leaving a hit point.

Resolves the hit, evaluates its material, and accumulates the contribution of every light in the view toward the hit point, returning the outgoing radiance along -ray.direction(). Only primitive (non-light) geometry is shaded; hits on light geometry return zero, as emission is the caller’s responsibility. Partial opacity at the hit point is not resampled here.

By default this is all of the direct light the point reflects. A renderer whose path also samples the point’s BSDF there, with a ray it will trace, finds part of the light that way: it passes bsdf_ray_follows, and gets the rest, the lights’ samples weighted against that ray by the power heuristic.

Parameters:
  • ray – The ray that produced the hit.

  • hit – The hit record (must reference primitive geometry to shade).

  • sampler – Random sampler for light sampling and transmittance estimation.

  • time – Normalized time in [0, 1] for motion blur.

  • medium_stack – The medium stack at the hit point (defaults to empty).

  • bsdf_ray_follows – Whether the caller traces a ray sampled from the BSDF at the hit point, whose share of the lights’ light is then left out.

Returns:

The direct-lit outgoing spectral radiance at the hit.

TSpectral indirect_source_radiance(const Ray<TSpectral> &ray, std::size_t source, const MediumStack<TSpectral> &medium_stack, RandomSampler<float> &sampler, float time = 0.5f, bool bsdf_ray_follows = false) const

The radiance arriving along a ray from an indirect source, by the direct light the source reflects.

The ray is followed through whatever lets light through, as a shadow ray is (see evaluate_transmittance()): past surfaces by their alpha, through them by their transmission, and through the media between them. The direct light that each of the source’s surfaces it meets reflects back along it (see direct_lit_radiance()) is added up, attenuated by what lies in front. The ray stops at the first surface that lets no light through, which hides anything beyond it, and at a light, whose sphere does too.

Parameters:
  • ray – The ray, from the point that receives the light.

  • source – The source’s index in indirect_sources().

  • medium_stack – The media the ray starts in.

  • sampler – Random numbers, for sampling the lights, the media and partially opaque surfaces.

  • time – The time for motion blur, from 0 to 1 over the exposure.

  • bsdf_ray_follows – Whether the caller traces a ray sampled from the BSDF at each of the source’s surfaces it reaches, as for direct_lit_radiance().

Returns:

The spectral radiance.

inline bool tlas_is_empty() const noexcept

True when the TLAS contains nothing that a ray could ever hit.

inline bool has_motion_blur() const noexcept

Whether anything rays can hit (geometry and lights) moves in view during the exposure, as the view samples it: rays are then traced at times through the exposure.

inline std::size_t max_temporal_samples() const noexcept

The most temporal samples anything in the view was given (1 when nothing moves).

inline const std::vector<OccupancyBound> &occupancy_bounds() const noexcept

Per-occupant bounds for every instance in the TLAS, over the exposure.

inline bool occupancy_bounds_complete() const noexcept

False when the bounds are not usable for culling.

inline const std::shared_ptr<Image<TSpectral>> &background() const

The scene background, sampled by rays that hit nothing.

inline Interval get_exposure_interval() const
inline units::Second duration() const
inline Time get_time() const
inline Time get_start_time() const
inline Time get_end_time() const

Public Static Attributes

static constexpr double DEFAULT_MOTION_TOLERANCE = 0.1

How far, by default, the path a thing is drawn along may stray from its true path during the exposure, in pixels, when the number of temporal samples is chosen automatically.

static constexpr std::size_t NO_INDIRECT_SOURCE = std::numeric_limits<std::size_t>::max()

Sentinel returned by indirect_source_index() for hits that are not on an indirect source.

struct OccupancyBound

Conservative camera-space bounding sphere of one TLAS occupant.

Public Members

Vec3<float> center

Camera-frame centre.

float radius

Radius enclosing the occupant over the time it covers.