diff --git a/SeeSharp/Integrators/Bidir/BidirBase.cs b/SeeSharp/Integrators/Bidir/BidirBase.cs index 20a8812..6561688 100644 --- a/SeeSharp/Integrators/Bidir/BidirBase.cs +++ b/SeeSharp/Integrators/Bidir/BidirBase.cs @@ -108,6 +108,8 @@ public struct CameraPath { /// Roughness of the material at the currently last vertex of the path. /// public float CurrentRoughness; + + public int Depth => Vertices.Count; } /// diff --git a/SeeSharp/Integrators/Bidir/VertexConnectionAndMerging.cs b/SeeSharp/Integrators/Bidir/VertexConnectionAndMerging.cs index de9d0d7..05d012a 100644 --- a/SeeSharp/Integrators/Bidir/VertexConnectionAndMerging.cs +++ b/SeeSharp/Integrators/Bidir/VertexConnectionAndMerging.cs @@ -121,6 +121,12 @@ protected override void OnAfterRender() { Scene.FrameBuffer.MetaData["AverageCameraPathLength"] = AverageCameraPathLength; Scene.FrameBuffer.MetaData["AverageLightPathLength"] = AverageLightPathLength; Scene.FrameBuffer.MetaData["AveragePhotonsPerQuery"] = AveragePhotonsPerQuery; + Scene.FrameBuffer.MetaData["MergeAccelBuildTime"] = mergeBuildTimer.ElapsedMilliseconds; + } + + protected override void OnBeforeRender() { + base.OnBeforeRender(); + mergeBuildTimer = new(); } protected override void OnStartIteration(uint iteration) { @@ -137,7 +143,9 @@ protected override void OnCameraPathTerminate(CameraPath path) private float ComputeAverageLightPathLength() { float average = 0; - if (LightPaths == null) return 0; + if (LightPaths == null) + return 0; + for (int i = 0; i < LightPaths.NumPaths; ++i) { int length = LightPaths.PathCache.Length(i); average = (length + i * average) / (i + 1); @@ -186,6 +194,8 @@ public override void Render(Scene scene) { photonMap = null; } + Stopwatch mergeBuildTimer; + /// /// Generates the acceleration structure for merging /// @@ -193,6 +203,8 @@ protected override void ProcessPathCache() { base.ProcessPathCache(); if (EnableMerging) { + mergeBuildTimer.Start(); + photonMap.Clear(); for (int i = 0; i < LightPaths.PathCache.NumVertices; ++i) { var vertex = LightPaths.PathCache[i]; @@ -201,6 +213,8 @@ protected override void ProcessPathCache() { } } photonMap.Build(); + + mergeBuildTimer.Stop(); } } @@ -307,6 +321,7 @@ protected virtual float ComputeLocalMergeRadius(float primaryDistance) { protected virtual RgbColor PerformMerging(SurfaceShader shader, RNG rng, CameraPath path, float cameraJacobian) { if (path.Vertices.Count == 1 && !MergePrimary) return RgbColor.Black; if (!EnableMerging) return RgbColor.Black; + if (!MergePrimary && path.Depth == 1) return RgbColor.Black; float localRadius = ComputeLocalMergeRadius(path.Distances[0]); RgbColor estimate = RgbColor.Black; diff --git a/SeeSharp/Integrators/Common/PathCache.cs b/SeeSharp/Integrators/Common/PathCache.cs index b430897..1943f13 100644 --- a/SeeSharp/Integrators/Common/PathCache.cs +++ b/SeeSharp/Integrators/Common/PathCache.cs @@ -83,6 +83,8 @@ public void Prepare() { this.overflow += overflow; totalUnused += unused; } + threadCaches.Values.Clear(); + // TODO compact the holes after flushing incomplete caches } @@ -124,7 +126,8 @@ class ThreadCache { int overflow = next - (vertices.Length - insertPos); if (overflow > 0) next -= overflow; - Array.ConstrainedCopy(batch, 0, vertices, insertPos, next); + if (next > 0) + Array.ConstrainedCopy(batch, 0, vertices, insertPos, next); // For uncompleted batches, add a guard int unused = overflow > 0 ? 0 : (BatchSize - next);