Cornell Box denoised
Jan Walter November 11, 2023 [TRACE] #arnold #denoise #pbrt-v4Let's talk about denoising in general before we go into some details how this might be handled by various renderers. We will use the famous Cornell Box for a start. If someone can't wait to get started or is too lazy to learn how to model such a simple scene in any DCC I do provide a Blender 2.79 scene (should still work on older computers) for convenience:

Just press the render button (F12) and watch the Cycles renderer doing it's job.

I do recommend though to try at least once to model this simple scene in any DCC by just using the provided data.
Arnold
For Arnold I described the details already in Denoising with Arnold. Therefore here the short version:
$ more Makefile
ARNOLD = /usr/local/Arnold
KICK = $(ARNOLD)/bin/kick
NOICE = $(ARNOLD)/bin/noice
EXR = arnold.exr noice.exr
all: render
clean:
-rm -f *~
clobber: clean
-rm -f $(EXR)
render: cornell_box_denoise.ass
$(KICK) -dp -dw -i cornell_box_denoise.ass -v 6
$(NOICE) -i arnold.exr -o noice.exr
A Makefile (see above) can be used to first call kick (to render
several AOVs into an
OpenEXR file called arnold.exr) and
then noice (to use those AOVs to create a less noisy image called
noice.exr).

The full log can be seen here:
$ make
/usr/local/Arnold/bin/kick -dp -dw -i cornell_box_denoise.ass -v 6
00:00:00 114MB | log started Sat Nov 11 15:42:16 2023
00:00:00 114MB | Arnold 7.2.4.1 [1fee86c4] linux x86_64 clang-15.0.7 oiio-2.4.1 osl-1.12.9 vdb-7.1.1 adlsdk-7.4.2.47 clmhub-3.1.1.43 rlm-14.2.5 optix-6.6.0 2023/10/17 03:09:19
00:00:00 114MB | running on tuxedo-desktop, pid=28827
00:00:00 114MB | 1 x Intel(R) Core(TM) i9-9940X CPU @ 3.30GHz (14 cores, 28 logical) with 128488MB
00:00:00 126MB | NVIDIA driver version 535.54 (Optix 60806)
00:00:00 126MB | GPU 0: NVIDIA GeForce RTX 2080 Ti @ 1545MHz (compute 7.5) with 11011MB (11002MB available) (NVLink:0)
00:00:00 126MB | GPU 1: NVIDIA GeForce RTX 2080 Ti @ 1545MHz (compute 7.5) with 11003MB (10464MB available) (NVLink:0)
00:00:00 126MB | Ubuntu 22.04.2 LTS (Jammy Jellyfish), Linux kernel 5.15.0-76-generic
00:00:00 126MB | soft limit for open files is set at 1048574
00:00:00 126MB |
00:00:00 127MB | [color_manager_ocio] default ocio.config found in /media/datadisk3/local/Arnold-7.2.4.1/bin/../ocio/configs/arnold/config.ocio
00:00:00 127MB | loading plugins from /media/datadisk3/local/Arnold-7.2.4.1/bin/../plugins ...
00:00:00 128MB | cryptomatte.so: cryptomatte uses Arnold 7.2.4.1
00:00:00 128MB | cryptomatte.so: cryptomatte_filter uses Arnold 7.2.4.1
00:00:00 128MB | cryptomatte.so: cryptomatte_manifest_driver uses Arnold 7.2.4.1
00:00:00 128MB | alembic_proc.so: alembic uses Arnold 7.2.4.1
00:00:00 128MB | usd_proc.so: usd uses Arnold 7.2.4.1
00:00:00 128MB | loaded 5 plugins from 3 lib(s) in 0:00.00
00:00:00 128MB | [color_manager_ocio] default ocio.config found in /media/datadisk3/local/Arnold-7.2.4.1/bin/../ocio/configs/arnold/config.ocio
00:00:00 129MB | [kick] command: /usr/local/Arnold/bin/kick -dp -dw -i cornell_box_denoise.ass -v 6
00:00:00 129MB | loading plugins from . ...
00:00:00 129MB | no plugins loaded
00:00:00 131MB | [metadata] loading metadata file: cornell_box_denoise.ass
00:00:00 132MB | [ass] loading cornell_box_denoise.ass ...
00:00:00 132MB | [ass] read 4425 bytes, 16 nodes in 0:00.00
00:00:00 132MB |
00:00:00 132MB | authorizing with license manager: user ...
00:00:00 135MB | [user] authorized user "jdb.walter3QDPU" in 0:00.42
00:00:00 135MB | [user] expiration date: 2024-06-11T11:58:47+02:00
00:00:00 135MB |
00:00:00 135MB | [color_manager] using color manager of type "color_manager_ocio"
00:00:00 136MB | [color_manager_ocio] using config file /media/datadisk3/local/Arnold-7.2.4.1/bin/../ocio/configs/arnold/config.ocio
00:00:00 137MB | [color_manager] rendering color space is "ACEScg"
00:00:00 186MB |
00:00:00 186MB | there are 1 light and 5 objects:
00:00:00 186MB | 1 persp_camera
00:00:00 186MB | 1 mesh_light
00:00:00 186MB | 1 ray_switch_rgba
00:00:00 186MB | 2 utility
00:00:00 186MB | 5 standard_surface
00:00:00 186MB | 1 driver_exr
00:00:00 186MB | 2 box_filter
00:00:00 186MB | 1 gaussian_filter
00:00:00 186MB | 1 variance_filter
00:00:00 186MB | 4 polymesh
00:00:00 186MB | 2 list_aggregate
00:00:00 186MB | 2 color_manager_ocio
00:00:00 186MB |
00:00:00 186MB | rendering image at 500 x 500, 5 AA samples
00:00:00 186MB | AA samples max <disabled>
00:00:00 186MB | AA sample clamp <disabled>
00:00:00 186MB | diffuse samples 1 / depth 3
00:00:00 186MB | specular samples 3 / depth 1
00:00:00 186MB | transmission samples 3 / depth 6
00:00:00 186MB | volume indirect <disabled by depth>
00:00:00 186MB | total depth 12
00:00:00 186MB | bssrdf samples 2
00:00:00 186MB | light <using per light samples>
00:00:00 186MB | transparency depth 10
00:00:00 186MB | initializing 20 nodes
00:00:00 186MB | creating root object list ...
00:00:00 186MB | node initialization done in 0:00.00 (multithreaded)
00:00:00 186MB | updating 21 nodes
00:00:00 187MB | MALight_light: mesh_light using 3 samples, 2 volume samples
00:00:00 187MB | scene bounds: (-0.556000113 -1.49375722e-07 0) -> (7.79891695e-15 0.559200048 0.548800051)
00:00:00 187MB | node update done in 0:00.00 (multithreaded)
00:00:00 188MB | [aov] parsing 8 output statements ...
00:00:00 188MB | [aov] registered driver: "driver" (driver_exr)
00:00:00 188MB | [aov] * "RGBA" of type RGBA filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "emission" of type RGB filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "diffuse_direct" of type RGB filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "diffuse_indirect" of type RGB filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "RGBA" of type RGBA filtered by "variance_filter" (variance_filter)
00:00:00 188MB | [aov] * "diffuse_albedo" of type RGB filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "Z" of type FLOAT filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] * "N" of type VECTOR filtered by "filter" (gaussian_filter)
00:00:00 188MB | [aov] done preparing 8 AOVs for 8 outputs to 1 driver (0 deep AOVs)
00:00:00 214MB | starting 28 bucket workers of size 32x32 ...
00:00:00 249MB | [accel] list_aggregate bvh4 done - 0:00.00 (wall time) - 4 prims, 1 key
00:00:00 250MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 5 prims, 1 key
00:00:00 253MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 6 prims, 1 key
00:00:00 258MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 6 prims, 1 key
00:00:00 280MB | 1% done - 75 rays/pixel
00:00:01 282MB | 5% done - 113 rays/pixel
00:00:01 282MB | 10% done - 307 rays/pixel
00:00:01 284MB | 15% done - 559 rays/pixel
00:00:01 286MB | 20% done - 215 rays/pixel
00:00:02 288MB | 25% done - 322 rays/pixel
00:00:02 290MB | 30% done - 301 rays/pixel
00:00:02 291MB | 35% done - 171 rays/pixel
00:00:02 292MB | 40% done - 427 rays/pixel
00:00:02 293MB | 45% done - 157 rays/pixel
00:00:03 293MB | 50% done - 207 rays/pixel
00:00:03 293MB | 55% done - 177 rays/pixel
00:00:03 294MB | 60% done - 149 rays/pixel
00:00:03 294MB | 65% done - 287 rays/pixel
00:00:03 295MB | 70% done - 374 rays/pixel
00:00:04 296MB | 75% done - 222 rays/pixel
00:00:04 297MB | 80% done - 513 rays/pixel
00:00:04 297MB | 85% done - 168 rays/pixel
00:00:04 298MB | 90% done - 170 rays/pixel
00:00:04 298MB | 95% done - 94 rays/pixel
00:00:04 298MB | 100% done - 80 rays/pixel
00:00:04 298MB | render done in 0:04.321
00:00:04 298MB | [driver_exr] writing file `arnold.exr'
00:00:04 298MB | render done
00:00:04 298MB |
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | scene creation time 0:00.03 machine utilization (1.29%)
00:00:04 298MB | unaccounted 0:00.03
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | frame time 0:04.88 machine utilization (86.92%)
00:00:04 298MB | driver init/close 0:00.02
00:00:04 298MB | rendering 0:04.32
00:00:04 298MB | output driver 0:00.02
00:00:04 298MB | pixel rendering 0:04.29
00:00:04 298MB | unaccounted 0:00.53
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | top session self-times by category
00:00:04 298MB | LightSampling (MALight_light) 0:00.77 (18.00%)
00:00:04 298MB | accumulateBucketSamples 0:00.67 (15.53%)
00:00:04 298MB | polymesh::intersect 0:00.66 (15.30%)
00:00:04 298MB | MEcornell_box 0:00.58 (13.45%)
00:00:04 298MB | MElarge_box 0:00.03 ( 0.71%)
00:00:04 298MB | MELight 0:00.02 ( 0.61%)
00:00:04 298MB | MEsmall_box 0:00.02 ( 0.53%)
00:00:04 298MB | surface closure 0:00.64 (14.86%)
00:00:04 298MB | MAcbox_Material 0:00.30 ( 7.04%)
g00:00:04 298MB | MAbox_Material 0:00.11 ( 2.72%)
00:00:04 298MB | MAcbox_red 0:00.11 ( 2.56%)
00:00:04 298MB | MAcbox_green 0:00.10 ( 2.53%)
00:00:04 298MB | BVH::intersect 0:00.33 ( 7.81%)
00:00:04 298MB | root 0:00.23 ( 5.55%)
00:00:04 298MB | MEcornell_box 0:00.08 ( 1.87%)
00:00:04 298MB | AiLightsPrepare 0:00.29 ( 6.85%)
00:00:04 298MB | MEcornell_box 0:00.25 ( 5.85%)
00:00:04 298MB | MElarge_box 0:00.03 ( 0.78%)
00:00:04 298MB | TraceCameraRay 0:00.18 ( 4.38%)
00:00:04 298MB | ray traversal+intersection 0:00.13 ( 3.20%)
00:00:04 298MB | TraceShadow 0:00.11 ( 2.62%)
00:00:04 298MB | sampleNextBatch 0:00.11 ( 2.57%)
00:00:04 298MB | processBucketSamples 0:00.11 ( 2.55%)
00:00:04 298MB | standard_surface 0:00.09 ( 2.27%)
00:00:04 298MB | MAcbox_Material 0:00.05 ( 1.20%)
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | top session self-times by node
00:00:04 298MB | mesh_light:MALight_light 0:00.98 (22.84%)
00:00:04 298MB | LightSampling 0:00.77 (18.00%)
00:00:04 298MB | TraceShadow 0:00.11 ( 2.60%)
00:00:04 298MB | ray traversal+intersection 0:00.09 ( 2.24%)
00:00:04 298MB | polymesh:MEcornell_box 0:00.91 (21.19%)
00:00:04 298MB | polymesh::intersect 0:00.58 (13.45%)
00:00:04 298MB | AiLightsPrepare 0:00.25 ( 5.85%)
00:00:04 298MB | BVH::intersect 0:00.08 ( 1.87%)
00:00:04 298MB | accumulateBucketSamples 0:00.67 (15.53%)
00:00:04 298MB | standard_surface:MAcbox_Material 0:00.42 ( 9.83%)
00:00:04 298MB | surface closure 0:00.30 ( 7.04%)
00:00:04 298MB | AiLightsTrace 0:00.03 ( 0.72%)
00:00:04 298MB | list_aggregate:root (BVH::intersect) 0:00.23 ( 5.55%)
00:00:04 298MB | TraceCameraRay 0:00.18 ( 4.38%)
00:00:04 298MB | standard_surface:MAbox_Material 0:00.16 ( 3.73%)
00:00:04 298MB | surface closure 0:00.11 ( 2.72%)
00:00:04 298MB | standard_surface:MAcbox_red 0:00.14 ( 3.46%)
00:00:04 298MB | surface closure 0:00.11 ( 2.56%)
00:00:04 298MB | standard_surface:MAcbox_green 0:00.14 ( 3.37%)
00:00:04 298MB | surface closure 0:00.10 ( 2.53%)
00:00:04 298MB | sampleNextBatch 0:00.11 ( 2.57%)
00:00:04 298MB | processBucketSamples 0:00.11 ( 2.55%)
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | peak CPU memory used 298.84MB
00:00:04 298MB | at startup 126.46MB
00:00:04 298MB | AOV samples 30.81MB
00:00:04 298MB | output buffers 2.63MB
00:00:04 298MB | framebuffers 24.00MB
00:00:04 298MB | node overhead 0.01MB
00:00:04 298MB | message passing 0.05MB
00:00:04 298MB | memory pools 43.10MB
00:00:04 298MB | geometry 0.00MB
00:00:04 298MB | polymesh 0.00MB
00:00:04 298MB | accel structs 0.01MB
00:00:04 298MB | mesh importance map 0.00MB
00:00:04 298MB | strings 24.50MB
00:00:04 298MB | profiler 1.68MB
00:00:04 298MB | unaccounted 45.58MB
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | ray counts ( /pixel, /sample) (% total) (avg. hits) (max hits)
00:00:04 298MB | camera 6656400 ( 26.63, 1.00) ( 10.63%) ( 0.94) ( 1)
00:00:04 298MB | shadow 45478079 ( 181.91, 6.83) ( 72.60%) ( 0.10) ( 1)
00:00:04 298MB | diffuse_reflect 10510438 ( 42.04, 1.58) ( 16.78%) ( 0.77) ( 1)
00:00:04 298MB | total 62644917 ( 250.58, 9.41) (100.00%) ( 0.30) ( 1)
00:00:04 298MB | by ray depth: 0 1 2 3
00:00:04 298MB | total 74.1% 14.8% 7.3% 3.7%
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | shader calls ( /pixel, /sample) (% total)
00:00:04 298MB | primary 14349282 ( 57.40, 2.16) (100.00%)
00:00:04 298MB | total 14349282 ( 57.40, 2.16) (100.00%)
00:00:04 298MB | by ray depth: 0 1 2 3
00:00:04 298MB | total 43.5% 31.4% 16.5% 8.6%
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | geometry (% hit ) (instances) ( init mem, final mem)
00:00:04 298MB | lists 1 (100.0%) ( 0) ( 0.00, 0.00)
00:00:04 298MB | polymeshes 4 (100.0%) ( 0) ( 0.00, 0.00)
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | geometric elements ( min) ( avg.) ( max)
00:00:04 298MB | polygons 18 ( 1) ( 4.5) ( 6)
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | triangle tessellation ( min) ( avg.) ( max) (/ element) (% total)
00:00:04 298MB | polymeshes 36 ( 2) ( 9.0) ( 12) ( 2.00) (100.00%)
00:00:04 298MB | unique triangles 36
00:00:04 298MB | CPU memory use 0.00MB
00:00:04 298MB | vertices 0.00MB
00:00:04 298MB | vertex indices 0.00MB
00:00:04 298MB | uniform indices 0.00MB
00:00:04 298MB | largest polymeshes by triangle count
00:00:04 298MB | 12 tris -- MEsmall_box
00:00:04 298MB | 12 tris -- MElarge_box
00:00:04 298MB | 10 tris -- MEcornell_box
00:00:04 298MB | 2 tris -- MELight
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 298MB | acceleration structures: (% total)
00:00:04 298MB | list 1 ( 20.00%)
00:00:04 298MB | bvh 4 ( 80.00%)
00:00:04 298MB | total 5 (100.00%)
00:00:04 298MB | -----------------------------------------------------------------------------------
00:00:04 299MB |
00:00:04 299MB | releasing resources
00:00:04 228MB |
00:00:04 228MB | releasing resources
00:00:04 228MB | unloading 3 plugins
00:00:04 228MB | closing cryptomatte.so ...
00:00:04 228MB | closing alembic_proc.so ...
00:00:04 227MB | closing usd_proc.so ...
00:00:04 227MB | unloading plugins done
00:00:04 227MB | Arnold shutdown
/usr/local/Arnold/bin/noice -i arnold.exr -o noice.exr
noice 7.2.4.1 [1fee86c4] - the Arnold denoiser
Using 28 threads.
Loading images...
Loading file "arnold.exr".
Using feature AOV 'diffuse_albedo' with filter 'gaussian_filter'
Using feature AOV 'N' with filter 'gaussian_filter'
Using feature AOV 'Z' with filter 'gaussian_filter'
Working with 1 frame at 500x500
Will denoise AOV "RGBA", using associated variance
Output file will be "noice.exr"
Start denoising (patch radius 3, search radius 9, variance 0.5)
Denoising RGBA
Finished denoising
Saving image noice.exr (500 x 500 x 4)
PBRT v4
For pbrt-v4 we need a compiled version which supports using the GPU:
$ /media/datadisk3/git/github/pbrt-v4/build/pbrt --help |& grep gpu
--gpu Use the GPU for rendering. (Default: disabled)
--gpu-device <index> Use specified GPU for rendering.
$ /media/datadisk3/git/github/pbrt-v4/build/imgtool --help |& grep denoise-optix
denoise-optix: Denoises the image using NVIDIA's OptiX denoiser which is
$ /media/datadisk3/git/github/pbrt-v4/build/pbrt --stats --spp 64 cornell_box_v4.pbrt
pbrt version 4 (built Nov 11 2023 at 17:42:45)
Copyright (c)1998-2021 Matt Pharr, Wenzel Jakob, and Greg Humphreys.
The source code to pbrt (but *not* the book contents) is covered by the Apache 2.0 License.
See the file LICENSE.txt for the conditions of the license.
Rendering: [++++++++++++++++++++++++++++++++++++++++] (4.1s)
Statistics:
BVH
Interior nodes 29
Leaf nodes 30
Nodes visited 960612938
Primitives per leaf node 36 / 30 (1.20x)
Geometry
Buffer cache hits 5 / 14 (35.71%)
Triangles per mesh 38 / 7 (5.43x)
Integrator
Camera rays traced 16000000
Path length 1.852 avg [range 0 - 6]
Regularized BSDFs 0 / 29626740 (0.00%)
Zero-radiance paths 11192144 / 29470842 (37.98%)
Intersections
Regular ray intersection tests 35417428
Shadow ray intersection tests 20590679
Ray-Triangle intersection tests 35192020 / 106903889 (0.33x)
Memory
BVH 2.17 kB
Film pixels 45.78 MiB
Light BVH 0.14 kB
Primitives 0.62 kB
Redundant vertex and index buffers 0.26 kB
Tokenizer buffers 4.78 kB
Triangles 0.73 kB
Unreported / unused 20.27 MiB
Scene
AreaLights 2
Lights 2
Materials 6
$ /media/datadisk3/git/github/pbrt-v4/build/imgtool denoise-optix noisy.exr --outfile pbrt-v4.exr
Take only 64 samples per pixel (--spp 64) and use the imgtool
to denoise via
OptiX.

All the files (except the Blender scene mentioned above) you can find
on my
wahn-rnd-org
sourcehut repository. I also remodelled the Cornell Box for the
latest Blender version (3.6.5) to compare the old Cycles vs. the
newest Cycles version, but that will be done in another blog post.
