K3D-jupyter 3.0.3
A small release with one change you will see and one you will not. The cinematic renderer no longer pins its noise unless you ask it to, so two renders of the same scene now differ in their grain the way two photographs do instead of repeating one fixed pattern. Under the hood, the text tests learned to tolerate the few pixels of glyph anti-aliasing that differ between font rasterisers, which is what turned CI green again after 3.0.2 moved the test image to Debian trixie.
Cinematic renderer: fresh noise by default, repeatable on request
Since 3.0.0 every cinematic render was bit-for-bit repeatable: the same scene produced the same residual grain on the same pixels, no matter how often you re-rendered it. That was built for the reference-image test suite, where a PNG has to match exactly, and it leaked into every notebook - once you have noticed the pattern sitting still on the same pixels, you cannot stop seeing it.
Repeatability is now a parameter, and it is off by default:
plot = k3d.plot(renderer='cinematic')
plot.cinematic_seed = None # default: fresh noise for every accumulation
plot.cinematic_seed = 1 # pinned: N samples are a pure function of the sceneNone lets the tracer draw fresh noise for every accumulation. An integer pins it: the same plot then renders the same image, sample for sample, across page loads and machines, which is what a reference-image test or a frame-by-frame animation needs. Different seeds give different, equally valid patterns. The value is validated to None or an integer in [1, 2**31 - 1]. It is also a k3d.plot() argument, cinematic_seed=1.
If you relied on the old behaviour, set plot.cinematic_seed = 1 and you have 3.0.2 back exactly. The 3.0.0 release notes described the renderer as repeatable without qualification; from this release that sentence applies when the seed is set. Documented on the cinematic page under "The parameters". (#533, 5323604)
For contributors
The seven text tests - labels, text, text2d, texture_text - now pass max_mismatched_pixels=GLYPH_AA_BUDGET, a budget of 32 pixels. The suite runs in two environments that rasterise glyph edges differently, the Docker image (trixie, freetype 2.13.3 since 3.0.2) and the ubuntu-22.04 runner (freetype 2.11.1), and one set of reference PNGs at a budget of zero can match only one of them; it matched both before 3.0.2 by coincidence. The number comes from measurement: the largest observed difference is 18 pixels and pixelmatch's own anti-aliasing detector classifies nearly all of them as edge pixels, while a misplaced, missing or re-wrapped label differs by hundreds to thousands, so the gate still catches every failure it existed for. (#533, 7e0b2d1)
The visual suite pins cinematic_seed=1 from conftest.py, so its 27 cinematic references are unchanged. A new functional test reads the tracer's own stableNoise flag through the diagnostic handle rather than inferring it from pixels, then confirms the consequence once each way: unpinned, two one-sample renders differ; pinned, they are byte-identical.
Verified in the Docker image: 269 passed, ruff and eslint clean, webpack builds.
Full Changelog: v3.0.2...v3.0.3