Stop palette switches flashing a magnified texture

Switching palettes dropped the last frame's timing, so the first frame
fell back to one sample per ~29 pixels and drew a texture pixel in each
square. The first frame is now sized from the previous source's speed,
and coarse frames use block colours instead of texture pixels.

Model used: Claude Opus 5.5
This commit is contained in:
piexel committed 2026-10-25 19:58:08 +01:00
1 parent 065c6fed1d
commit 806a33976a
1 file changed
+13 -4
@@ -99,6 +99,7 @@ public final class NoiseExplorerGUI extends JPanel {
private static final int REFINEMENT_DELAY_MILLIS = 180;
private static final long DEFAULT_SEED = 12345L;
private static final double TEXTURE_PIXELS_MAX_BLOCKS_PER_PIXEL = 0.25D;
private static final int FULL_DETAIL_SAMPLE_STEP = 1;
private static final double PALETTE_START_BLOCKS_PER_PIXEL = 1D / 16D;
private static final long COARSE_SAMPLE_BUDGET = 4_096L;
private static final double REFINEMENT_TARGET_MILLIS = 250D;
@@ -176,6 +177,7 @@ public final class NoiseExplorerGUI extends JPanel {
private PaletteLayerPreview palettePreview;
private int paletteDepth;
private NoiseRenderCoordinator.Result renderResult;
private NoiseRenderCoordinator.Result lastTimedFrame;
private NoiseRenderCoordinator.Request interactiveFrame;
private boolean interactiveFramePending;
private Point pointer;
@@ -991,12 +993,17 @@ public final class NoiseExplorerGUI extends JPanel {
}
private NoiseColorScale activeColorScale() {
return activeColorScale(FULL_DETAIL_SAMPLE_STEP);
}
// A coarse frame's sample stands for a whole square of pixels, so texture pixels would show magnified there.
private NoiseColorScale activeColorScale(int sampleStep) {
PaletteLayerPreview preview = palettePreview;
if (preview == null) {
BlockRange blockRange = samplerBlockRange;
return blockRange == null ? palette : new BlockHeightColorScale(palette, blockRange.lowest(), blockRange.highest());
}
boolean showTexturePixels = viewport.blocksPerPixel() <= TEXTURE_PIXELS_MAX_BLOCKS_PER_PIXEL;
boolean showTexturePixels = viewport.blocksPerPixel() * sampleStep <= TEXTURE_PIXELS_MAX_BLOCKS_PER_PIXEL;
return new PaletteLayerScale(paletteInspector.selectedView(), preview, palette, showTexturePixels);
}
@@ -1106,9 +1113,10 @@ public final class NoiseExplorerGUI extends JPanel {
return interactiveFrame != null && interactiveFrame.revision() == viewRevision;
}
// The last frame's speed predicts this one, so cheap views draw sharp straight away instead of starting blocky.
// The last frame's speed predicts this one, so cheap views draw sharp straight away instead of starting blocky. It
// outlives a switch to another source, which samples about as fast.
private long interactiveSampleBudget() {
NoiseRenderCoordinator.Result lastResult = renderResult;
NoiseRenderCoordinator.Result lastResult = lastTimedFrame;
if (lastResult == null) {
return COARSE_SAMPLE_BUDGET;
}
@@ -1166,7 +1174,7 @@ public final class NoiseExplorerGUI extends JPanel {
viewRevision,
sampler,
viewport,
activeColorScale(),
activeColorScale(sampleStep),
getWidth(),
renderHeight(),
sampleStep
@@ -1680,6 +1688,7 @@ public final class NoiseExplorerGUI extends JPanel {
rendering = false;
errorMessage = null;
renderResult = result;
lastTimedFrame = result;
repaint();
refreshStatus();
if (finishInteractiveFrame(result.request())) {