Pupil Sampling — A Lecture on Where the Rays Go
Every analysis in KrakenOS — spot diagrams, PSFs, MTF, OPD maps, Seidel sums, radiometric throughput, Monte-Carlo stray-light — ultimately estimates an integral over the entrance pupil:
Choosing the sample positions \(\{(x_i, y_i)\}\) is pupil sampling. The choice controls three different things at once: how fast the estimate converges, how isotropic the result is, and how much aliasing leaks into image-plane FFTs. This page surveys the strategies KrakenOS ships, derives the equal-area trick they all share, and motivates the Vogel / golden-angle spiral that the UI uses internally for source previews and Lambertian / lobe scattering.
The unit pupil \(\{(x_p, y_p) : x_p^2 + y_p^2 \le 1\}\).
The chief ray sits at the centre; analysis rays are deposited
on the disk and then mapped to real-world starting positions and
direction cosines by PupilCalc.Pattern2Field.
1. What makes a sampler “good”?
Three useful quality metrics, all easy to read off the figures further down:
Equal area. Every sample should represent the same area of the pupil. If samples cluster near the centre, the Monte-Carlo estimate becomes a biased estimate of an axially-symmetric integrand. The fix is the radial mapping \(r = \sqrt{u}\) for \(u \in [0,1]\) derived below.
Low discrepancy. Loosely: no large empty regions and no clumps. Quantitatively, the star discrepancy \(D^*_N\) measures the worst-case deviation between sample density and true area. Truly random points have \(D^*_N \sim N^{-1/2}\); quasi-random sequences (Halton, Sobol, golden-angle) can reach \(D^*_N \sim N^{-1} \log^{d-1} N\).
Isotropy. Section fans deliberately collapse the pupil to a line and are fine for tangential / sagittal aberration plots. For PSFs, MTFs, and stray light you want sampling that does not pick a direction.
A useful empirical proxy for the last two is the nearest-neighbour distance distribution: a tight peak ≈ uniform spacing; a long left tail ≈ clumps.
Nearest-neighbour distances for the three full-disk samplers at \(N \approx 300\). Random sampling produces clumps (left tail of short distances); hexapolar and Vogel are tightly peaked, with Vogel slightly narrower than hexapolar.
2. The equal-area mapping
A common rookie mistake: place \(N\) samples by stepping \(r = i/N\) and rotating around. Because \(dA = r\, dr\, d\theta\), that recipe oversamples the centre by a factor of \(r\).
The fix follows from the inverse-CDF method. For uniform sampling on a disk of radius \(R\), the radial CDF is
Inverting \(F_R(r) = u\) with \(u \sim \mathcal{U}(0, 1)\) gives
so every linear, equal-spaced sequence in \(u\) produces an
equal-area sequence in \(r\). This single identity is why
KrakenOS’s Vogel sampler uses r = sqrt(i/N) and why the Random-disk
generator works by rejection sampling on the unit square (which is
equivalent to taking \(u \sim \mathcal{U}(0,1)\)).
Same 200 indices, two radial maps: \(r = i/N\) (left) over-densifies the centre, \(r = \sqrt{i/N}\) (right) gives constant area density.
3. Section fans — when one dimension is enough
For tangential / sagittal aberration slices, a 2D sampler is wasteful: the integrand is constant along the orthogonal direction. KrakenOS exposes three section patterns (see Pupil Patterns (Source Model: Pupil / field)):
Fan Y (
Pup.Ptype = "fany") — the meridional fan, \(\{(0, j/\mathrm{Samp})\}\). Canonical input for transverse ray-aberration plots \(\Delta y' = \mathrm{TRA}_y(p_y)\).Fan X (
"fanx") — sagittal fan.Cross fan (
"fan") — Fan X ∪ Fan Y, useful for a quick visual sanity check of both aberration directions in one trace.
Section patterns. They are not physical 3D launch distributions; Open 3D source-cone tracing maps them to a filled angular cone.
Section fans converge as \(O(1/N^{2})\) for the 1D integrals they target (Simpson-like behaviour with smooth integrands) but they are not valid for any quantity that requires a 2D integral over the pupil — PSF, encircled energy, MTF, throughput.
4. Hexapolar — equal-area rings
The traditional analysis default. One chief ray at the centre plus
Samp concentric rings, ring \(j\) carrying \(6j\) samples
evenly spaced in azimuth at radius \(r_j = j/\mathrm{Samp}\). Each
ring covers an area \(\pi (r_j^2 - r_{j-1}^2)
= \pi (2j-1)/\mathrm{Samp}^{2}\), and there are \(6j\) samples on
it, giving constant per-sample area
\(\pi (2j-1) / (6j\,\mathrm{Samp}^{2}) \approx \pi/(3\,\mathrm{Samp}^{2})\)
for large \(j\) — so the pattern is asymptotically equal-area
without the \(\sqrt{\cdot}\) step.
The total ray count is
Hexapolar at Samp = 5: six-fold azimuthal symmetry and well
defined ring radii. Deterministic, reproducible, and visually
readable in spot diagrams.
Strengths: zero variance for any radially-symmetric integrand at finite \(N\); exact six-fold symmetry plays nicely with PSF cores. Weakness: the strong angular ordering aliases sharp pupil features (a hard mask, a vignette edge) into Moiré-like artefacts in FFTs.
5. Square grid — when the detector decides
A Cartesian grid of step \(1/\mathrm{Samp}\) clipped to the unit
disk (Pup.Ptype = "square"). It contains roughly \(\pi
\mathrm{Samp}^{2}\) samples after clipping. Useful when:
The downstream computation is an FFT-based OPD → PSF pipeline that wants a square footprint anyway.
Sample positions must align with detector pixel centres in image space (e.g. discrete-grid optical-bench experiments).
The Cartesian grid that survives the disk clip. The corner samples are dropped, leaving a slightly noisy boundary.
Weakness: the boundary is irregular, so a marginal-ray sweep produced by this pattern has gaps. Avoid for Seidel sums or marginal-rim analyses; prefer hexapolar or Vogel there.
6. Random disk — the Monte-Carlo baseline
Pup.Ptype = "rand": rejection sampling on the square
\([-1, 1]^2\) keeping points with \(x^2 + y^2 < 1\). Up to
\(4\,\mathrm{Samp}^{2}\) candidates produce a disk population of
roughly \(\pi \mathrm{Samp}^{2}\).
Uniform pseudo-random samples. Note the visible clumps and voids typical of low-\(N\) random draws.
For an integrand \(f\) with finite variance \(\sigma^{2}\), the standard Monte-Carlo error is
Strength: the rate \(1/\sqrt{N}\) is independent of dimension, which is why it remains the workhorse for high-dimensional stray-light integrals. Weakness: clumps and voids at small \(N\) produce visible banding in PSF / spot estimates.
7. The Vogel / golden-angle spiral
This is the sampler KrakenOS uses inside the source preview, the
reference-disk launcher, and the Lambertian / cosine-lobe hemisphere
generators — see sample_source_disk_points in
KrakenOS/UI/source_trace_helpers.py, the matching 3D variant
sample_reference_disk_points_3d, and the hemisphere code in
KrakenOS/KrakenSys.py. It is colloquially called “Fibonacci sampling”
because its azimuthal step is the limit of the Fibonacci ratios.
Definition
For sample index \(i = 0, 1, \dots, N-1\):
The radial step is the equal-area mapping of §2. The azimuthal step \(\alpha\) is the golden angle.
\(N = 300\) Vogel samples. The green polyline highlights the first 14 in order — they spiral outward at exactly \(137.5^\circ\) per step.
Why the golden angle?
The golden angle is the unique angle that is maximally irrational in a number-theoretic sense, and that is what makes the resulting spiral low-discrepancy. The derivation has three steps.
Step 1 — turn fraction. Set \(\alpha = 2\pi\,\rho\) for some turn fraction \(\rho \in (0, 1)\). After \(N\) steps the azimuths are \(\{2\pi\,\rho\,i \bmod 2\pi\}\). If \(\rho = p/q\) is rational with small \(q\), every \(q^{\text{th}}\) sample lands on the same ray and you get \(q\)-arm starburst patterns instead of a uniform fill.
Step 2 — continued fractions. The “how rational” of any \(\rho\) is measured by how well it can be approximated by rationals. Every irrational \(\rho\) has a unique simple continued-fraction expansion \(\rho = [a_{0}; a_{1}, a_{2}, \dots]\). Large \(a_{k}\) mean cheap rational approximations (close clumps); small \(a_{k}\) mean the opposite. The most-irrational choice is the one where every \(a_{k} = 1\):
Step 3 — back to the angle. Either turn fraction \(\rho^{*}\) or \(1 - \rho^{*}\) works; by convention we take
The successive Fibonacci ratios \(F_{n}/F_{n+1} = 1/1, 1/2, 2/3, 3/5, 5/8, 8/13, \dots\) are exactly the convergents of the continued-fraction expansion, which is why this angle is also called the Fibonacci angle even though no Fibonacci number appears in the runtime formula.
The golden angle as a fraction of the full circle. The green arc is the turn taken between successive samples; the grey-dashed arc is the complement taken on every other revolution. Neither arc closes into a low-period orbit.
Same \(N = 200\) indices, three angles. A rational angle (\(360^{\circ}/7\)) produces seven straight arms. A mildly irrational angle (\(360^{\circ}/\pi\)) still shows visible curved bands. The golden angle uniformly fills the disk.
Why optical designers care
Convergence. For smooth integrands the Vogel spiral behaves like a 2D quasi-random sequence: error \(\sim N^{-1}\) versus \(N^{-1/2}\) for pure random. In a typical PSF estimate you reach the same standard error with \(\sim \sqrt{N_{\text{random}}}\) rays.
Isotropy. Unlike the hexapolar grid, the Vogel spiral has no preferred direction at any \(N\), so it never imprints six-fold structure on a PSF or MTF.
Incremental. Adding samples never re-positions existing ones. This makes it ideal for live UI previews: increase
ray_countand the previously drawn rays remain valid — a property thesample_source_disk_pointshelper relies on.Boundary fill. The outermost ring is exactly \(r_{N-1} = R\), so the marginal rim is always sampled. The square-grid and random-disk patterns leave a fluctuating gap there.
8. From disk to hemisphere — Lambertian and lobe scattering
The same spiral lifts straight onto a hemisphere. KrakenOS’s Lambertian
emitter (KrakenSys.py around line 2565) and its glossy lobe
(line 2602) both use it.
For a cosine-weighted hemisphere (Lambert’s law), the joint PDF in spherical coordinates is \(p(\theta, \phi) = \cos\theta\,\sin\theta / \pi\). Integrating gives the marginal radial CDF
so the recipe is
which is exactly what KrakenSys._sample_lambertian_directions does
(sin2_max clamps the cone). The Vogel spiral on the disk maps
isomorphically onto the cosine-weighted hemisphere by reading the
disk-radius \(r_{i} = \sqrt{i/N}\) as \(\sin\theta_{i}\).
400 directions drawn from the cosine-weighted hemisphere using the Vogel spiral with \(\sin^{2}\theta = i/N\). The density falls off toward the rim because Lambert’s law puts more flux near the normal.
The directional-lobe variant raises the cosine to a power \(n\)
(settings["lobe_exponent"]), giving a glossy specular highlight; the
golden-angle azimuth keeps the lobe rotationally uniform.
9. KrakenOS code map
Where each sampler lives, for reference:
Sampler |
Where it is implemented |
Where it is used |
|---|---|---|
Hexapolar / Square / Random / fans |
|
Sequential analysis driven by |
Vogel disk (2D) |
|
2D source previews; non-sequential disk launches with
|
Vogel disk (3D) |
|
Open 3D scene reference launches. |
Vogel preview overlays |
|
Live “Source preview” and “Trace preview” overlays in the Layout Editor. |
Vogel hemisphere (Lambertian) |
|
Diffuse scattering from a surface; non-sequential thermal / Lambertian sources. |
Vogel cosine-lobe |
|
Glossy specular scattering with adjustable |
Vogel finite-source offsets |
|
Mapping a finite-radius emitter to a Lambertian fan when
|
10. Choosing in practice
A short decision tree for the analyses the Layout Editor surfaces:
Tangential aberration plot, sagittal aberration plot, ray-fan display — Fan Y or Fan X (then maybe Cross fan).
Spot diagram, Seidel sums, ABCD/wavefront overlay, classical OPD — Hexapolar at
Samp = 5…8(deterministic, six-fold benign).Square-detector PSF / FFT-OPD pipeline — Square grid; align
Sampto the detector sampling.Encircled energy, throughput, stray-light Monte-Carlo, edge-of-pupil vignetting — Vogel (via source preview / disk launchers) or Random if you need an unbiased variance estimate.
Non-sequential diffuse / glossy surface scattering — leave it to the built-in Lambertian and lobe samplers, both of which already use the golden-angle spiral.
When in doubt: start with hexapolar for analysis and Vogel for source launches. They cover almost every workflow in KrakenOS.
Further reading
Pupil Patterns (Source Model: Pupil / field) — UI combobox →
Pup.Ptypemapping.PupilCalc Tool — how patterns are turned into rays with
Pattern2Field.Finding the Cardinal Points and Pupils by Ray Tracing — what the pupil is and how EP/XP are located.
Rules of Thumb — Optics, Imaging, Laser — sampling counts you actually need for PSF / MTF / spot reductions.
H. Vogel, A better way to construct the sunflower head, Mathematical Biosciences 44 (1979), 179–189.