pub struct Rng(/* private fields */);Expand description
Deterministic xorshift64* PRNG. Avoids a dependency and keeps scene generation identical on every platform (important for WASM + tests).
Clone is deliberate: cloning captures the exact stream position, which is
how a speculative draw can be replayed or a substream forked at a known point.
Implementations§
Source§impl Rng
impl Rng
Sourcepub fn new(seed: u64) -> Self
pub fn new(seed: u64) -> Self
A generator from a seed.
Every seed but zero is used as given; xorshift is stuck at zero forever, so that one value is replaced.
Sourcepub fn for_index(seed: u64, index: u64) -> Rng
pub fn for_index(seed: u64, index: u64) -> Rng
An independent stream for one piece of work, identified by index.
Stateless and order-free: the stream for index 10 000 is what it is whether or not index 3 was ever drawn. That is what lets a trace be parallel and bit-reproducible at the same time, and it is why every stochastic loop should seed per item rather than share one generator.
Both arguments are mixed, so (seed, index) and (index, seed) differ and
adjacent indices do not produce correlated streams.
Sourcepub fn split(&mut self) -> Rng
pub fn split(&mut self) -> Rng
Fork a child stream and advance this one past it.
For nesting that has no natural index — a recursive bounce that needs its
own sampling without disturbing the caller’s sequence. Where an index
exists, prefer Rng::for_index: splitting is still order-dependent.
Sourcepub fn range(&mut self, lo: f64, hi: f64) -> f64
pub fn range(&mut self, lo: f64, hi: f64) -> f64
Uniform in [lo, hi). One draw from the stream, whatever the bounds.
Sourcepub fn in_disc(&mut self, radius: f64) -> (f64, f64)
pub fn in_disc(&mut self, radius: f64) -> (f64, f64)
Uniform point inside a disc of the given radius.
Sourcepub fn on_hemisphere(&mut self, normal: DVec3) -> DVec3
pub fn on_hemisphere(&mut self, normal: DVec3) -> DVec3
Uniform direction on the hemisphere about normal.
Sourcepub fn cosine_hemisphere(&mut self, normal: DVec3) -> DVec3
pub fn cosine_hemisphere(&mut self, normal: DVec3) -> DVec3
Cosine-weighted direction about normal — the Lambertian scatter.
A matte surface does not spray light evenly over the hemisphere: it sends it in proportion to the cosine of the angle from the normal, which is why it looks equally bright from every direction. Sampled by Malley’s method (a uniform disc lifted onto the hemisphere), so the cosine weight is in the distribution and the estimator needs no correction factor.
Sourcepub fn gaussian(&mut self) -> f64
pub fn gaussian(&mut self) -> f64
A standard normal deviate, mean 0 and variance 1.
Read noise, mechanical jitter, thermal fluctuation, Brownian motion: the noise in a simulation is Gaussian far more often than it is uniform. Plain Box-Muller rather than the polar form, because it draws exactly two numbers every time — a rejection loop would make stream consumption depend on the values drawn, and that is a needless dependency in something whose whole job is being predictable.
Sourcepub fn normal(&mut self, mean: f64, std_dev: f64) -> f64
pub fn normal(&mut self, mean: f64, std_dev: f64) -> f64
A normal deviate with the given mean and standard deviation.
Sourcepub fn poisson(&mut self, mean: f64) -> u64
pub fn poisson(&mut self, mean: f64) -> u64
A Poisson deviate: the number of independent events that happened, when the
expected number was mean.
The distribution of counting things that arrive at random — photons on a detector,
decays in a sample, molecules crossing a boundary. Its defining property is that
the variance equals the mean, so the noise on a count of N is √N and the
signal-to-noise ratio of counting improves only as the square root of how long you
count. That is not a limitation of any instrument; it is what counting is.
Two methods, chosen by the mean rather than by the draw, so stream consumption stays a function of the inputs:
- Below 30, inverse transform from a single uniform. Walking the cumulative
distribution costs
O(mean)time and exactly one draw, where the textbook product-of-uniforms method would consume a variable number and make the stream depend on the values it produced. - At 30 and above, a rounded normal. The skew there is 0.18 and the tail error is under a percent, which is far below any detector’s calibration — and the exact method’s cost grows with the mean while its benefit does not.