diff --git a/chunky/src/java/se/llbit/chunky/renderer/PathTracingRenderer.java b/chunky/src/java/se/llbit/chunky/renderer/PathTracingRenderer.java index 0ba0b1b20c..c397f16e97 100644 --- a/chunky/src/java/se/llbit/chunky/renderer/PathTracingRenderer.java +++ b/chunky/src/java/se/llbit/chunky/renderer/PathTracingRenderer.java @@ -71,7 +71,7 @@ public void render(DefaultRenderManager manager) throws InterruptedException { while (scene.spp < scene.getTargetSpp()) { int spp = scene.spp; - int branchCount = (tracer instanceof PathTracer) ? scene.getBranchCount() : 1; + int branchCount = (tracer instanceof PathTracer) ? scene.getCurrentBranchCount() : 1; double sinv = 1.0 / (sppPerPass * branchCount + spp); submitTiles(manager, (state, pixel) -> { diff --git a/chunky/src/java/se/llbit/chunky/renderer/scene/PathTracer.java b/chunky/src/java/se/llbit/chunky/renderer/scene/PathTracer.java index 01846045d0..da75ea168a 100644 --- a/chunky/src/java/se/llbit/chunky/renderer/scene/PathTracer.java +++ b/chunky/src/java/se/llbit/chunky/renderer/scene/PathTracer.java @@ -135,7 +135,7 @@ public static boolean pathTrace(Scene scene, Ray ray, WorkerState state, int add // The main caveat is that antialiasing is achieved by varying the starting rays at the subpixel level (see PathTracingRenderer.java) // Therefore, it's still necessary to have a decent amount (20 is ok, 50 is better) of distinct starting rays for each pixel // scene.branchCount is the number of times we use the same first ray before casting a new one - int count = firstReflection ? scene.getBranchCount() : 1; + int count = firstReflection ? scene.getCurrentBranchCount() : 1; for (int i = 0; i < count; i++) { boolean doMetal = pMetal > Ray.EPSILON && random.nextFloat() < pMetal; if (doMetal || (pSpecular > Ray.EPSILON && random.nextFloat() < pSpecular)) { diff --git a/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java b/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java index 91876dab39..013d2c5a8d 100644 --- a/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java +++ b/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java @@ -1920,10 +1920,27 @@ public void setTargetSpp(int value) { } /** - * @return The branch count + * @return The "nominal" value of the branch count. */ public int getBranchCount() { - return branchCount; + return branchCount; + } + + /** + * Usually the same as getBranchCount, but reduces branch count to 1 for first few SPP. + * + * @return The current "true" branch count + */ + public int getCurrentBranchCount() { + if(spp < branchCount) { + if(spp <= Math.sqrt(branchCount)) { // This is arbitrary, but should be a good compromise in most cases + return 1; + } else { + return branchCount - spp; + } + } else { + return branchCount; + } } /** diff --git a/lib/src/se/llbit/chunky/PersistentSettings.java b/lib/src/se/llbit/chunky/PersistentSettings.java index 5684123bfb..1f38e64a0f 100644 --- a/lib/src/se/llbit/chunky/PersistentSettings.java +++ b/lib/src/se/llbit/chunky/PersistentSettings.java @@ -64,7 +64,7 @@ public final class PersistentSettings { public static final double DEFAULT_FOG_BLUE = 1; public static final int DEFAULT_RAY_DEPTH = 5; - public static final int DEFAULT_BRANCH_COUNT = 5; + public static final int DEFAULT_BRANCH_COUNT = 10; public static final int DEFAULT_SPP_TARGET = 1000; public static final int DEFAULT_DIMENSION = 0;