diff --git a/chunky/src/java/se/llbit/chunky/renderer/DefaultRenderManager.java b/chunky/src/java/se/llbit/chunky/renderer/DefaultRenderManager.java index 94ed65e9d7..a143f384c9 100644 --- a/chunky/src/java/se/llbit/chunky/renderer/DefaultRenderManager.java +++ b/chunky/src/java/se/llbit/chunky/renderer/DefaultRenderManager.java @@ -288,6 +288,12 @@ public void run() { getRenderer().sceneReset(this, reason, resetCount); getPreviewRenderer().sceneReset(this, reason, resetCount); + // Reset sps rolling average + spp_history.clear(); + spp_history_times.clear(); + spp_history.addLast(0); + spp_history_times.addLast(0.0); + // Select the correct renderer Renderer render = mode == RenderMode.PREVIEW ? getPreviewRenderer() : getRenderer(); @@ -370,6 +376,10 @@ private void updateRenderState(Scene scene) { } } + private static final int SPS_AVERAGE_TIME = 30; + private LinkedList spp_history = new LinkedList(); + private LinkedList spp_history_times = new LinkedList(); + /** * @return the current rendering speed in samples per second (SPS) */ @@ -378,7 +388,10 @@ private int samplesPerSecond() { int canvasHeight = bufferedScene.canvasHeight(); long pixelsPerFrame = (long) canvasWidth * canvasHeight; double renderTime = bufferedScene.renderTime / 1000.0; - return (int) ((bufferedScene.spp * pixelsPerFrame) / renderTime); + + double timeDiff = renderTime - spp_history_times.getFirst(); + int sppDiff = bufferedScene.spp - spp_history.getFirst(); + return (int) (sppDiff * pixelsPerFrame / timeDiff); } private void updateRenderProgress() { @@ -398,6 +411,15 @@ private void updateRenderProgress() { } synchronized (this) { + // Update list of spp values + spp_history_times.addLast(renderTime); + spp_history.addLast(bufferedScene.spp); + // These lists shouldn't contain information older than SPS_AVERAGE_TIME, but must contain at least one old value + while ((spp_history_times.getFirst() + SPS_AVERAGE_TIME < renderTime) && (spp_history_times.size() > 2)) { + spp_history_times.removeFirst(); + spp_history.removeFirst(); + } + // Update render status display. renderStatusListeners.forEach(listener -> { listener.setRenderTime(bufferedScene.renderTime);