diff --git a/CMakeLists.txt b/CMakeLists.txt index c473e2c0..3efed928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,8 @@ set(headers src/ImGui/imgui_internal.h src/ImGui/imstb_rectpack.h src/ImGui/imstb_textedit.h - src/ImGui/imstb_truetype.h + src/ImGui/imstb_truetype.h + ) set(sources @@ -110,6 +111,9 @@ list(SORT sources) source_group(Headers FILES ${headers}) source_group(Sources FILES ${sources}) +set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) +set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) +add_subdirectory(external/include/tinygltf) #add_subdirectory(src/ImGui) #add_subdirectory(stream_compaction) # TODO: uncomment if using your stream compaction @@ -117,5 +121,6 @@ source_group(Sources FILES ${sources}) cuda_add_executable(${CMAKE_PROJECT_NAME} ${sources} ${headers}) target_link_libraries(${CMAKE_PROJECT_NAME} ${LIBRARIES} + tinygltf #stream_compaction # TODO: uncomment if using your stream compaction ) diff --git a/README.md b/README.md index 110697ce..d6cd6249 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,110 @@ CUDA Path Tracer **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3** -* (TODO) YOUR NAME HERE -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +![](img/cover.png) +An implementation of a path tracer including simulated diffuse, specular, and refractive materials, loading from checkpoints, Anti-Aliasing, and Depth of Field. +* Tom Donnelly + * [LinkedIn](https://www.linkedin.com/in/the-tom-donnelly/) +* Tested on: Windows 11, AMD Ryzen 9 5900X, NVIDIA GeForce RTX 3070 (Personal Desktop) -### (TODO: Your README) +--- +## Materials +Materials are able to be loaded from a scene including RGB color, specular color, diffuse, specular, and refraction interactions with light. -*DO NOT* leave the README to the last minute! It is a crucial part of the -project, and we will not be able to grade you without a good README. +### Diffuse: +![](img/diffuse.png) + +### Perfectly Specular: +![](img/reflect.png) + +### Imperfect Specular: +![](img/imperfect.png) + +### Refraction with Fresnel Effects: +![](img/refract.png) + +--- + +## Stream Compaction +An optional flag can be set to stream compact terminated threads in the path tracer after they've reached their bounce limit, hit a light, or exited the scene. We can examine how this affects performance for a number of scenes. +Cornell | No Walls | Big Light | Small Light +:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------: +![](img/reflect.png) | ![](img/no_walls.png) | ![](img/big_light.png) | ![](img/small_light.png) + +![](img/compaction_graph1.png) +Stream compaction greatly reduces the number of running rays in a iteration of pathtracing for open or well lit scenes as seen in No Walls and Big Light. When there are not early opportunities for rays to terminate then stream compaction does not have a large impact, as seen in Small Light and Cornell. +![](img/compaction_graph2.png) +When rays can terminate early, stream compaction greatly reduces running time for higher depth ray tracing. No Walls with compaction average iteration time stayed constant for all tested bounces as it was able to terminate early. Cornell achieved better running time without compaction at 128 bounces where the tradeoff between the stream compaction overhead and simulating terminated rays became favorable. This could be optimized in the future to reduce runtime in stream compaction leading to better runtimes at smaller depths. + +--- +## First Bounce Cache +An optional flag can be set to cache the first intersection a ray will have with objects in the scene. As the rays path and direction are deterministic until the first bounce we can reuse this cache for subsequent iterations. We can examine the performance impact of this feature. + +![](img/Cache_graph.png) +Caching the first bounce does not have a large impact on performance, with the average iteration time being about the same for multiple iteration depths. This is surprising as caching the first bounce would likely have a larger impact on low depths and small impact at high depths. It may be that this affect is only visible over very long iteration times or that there is enough overhead in copying the cache memory to counteract any performance benefits + +--- +## Material Sorting +Materials can be sorted to be contiguous in memory using a flag. This may improve performance by allowing threads in the same warp to not be divergent due to different material shading requirements. + +![](img/material_graph.png) + +Material sorting did not improve performance and greatly slowed the average iteration time when enabled. This may be because the scene tested is too simple and does not have enough materials for sorting to give any benefits over the overhead of sorting the materials buffer. This can be improved by testing on a more expensive scene when mesh loading is created and seeing if there is any performance increase. + +--- +## Anti-Aliasing +| No AA | AA | +|:-------------------------:|:-------------------------:| +|![](img/no_aa.png) | ![](img/aa.png) | +| ![](img/zoom_no_aa.png) | ![](img/zoom_aa.png) | + +Anti-Aliasing was implemented by jittering the ray inside a pixel as it is generated, creating noise that softens aliased edges. This option can be enabled by a flag but cannot be used with First Bounce Caching due to the randomness needed for implementation + +![](img/aa_graph.png) + +Anti-aliasing does not have a significant impact on performance. + +--- +## Depth of Field + + +| DOF 0.1 Radius | DOF 0.5 Radius | DOF 1.0 Radius | DOF 10.0 Radius | No DOF | +|--- |--- |--- |--- |--- | +|![](img/dof_p1r.png) | ![](img/dof_p5r.png) |![](img/dof_1r.png) | ![](img/dof_10r.png) | ![](img/no_dof.png) | + +Depth of field was implemented by jittering the rays origin in the camera to an offset focal point and then updating the rays direction. The blurriness can be set by adjusting the lens radius in the scenes camera option and the focal length and DOF flag can also be set.This option can be enabled by a flag but cannot be used with First Bounce Caching due to the randomness needed for implementation . + +![](img/dof_graph.png) +DOF does not have a significant impact on performance. + +--- +## Saving and Loading Checkpoints +Saving and reloading of the current path tracing iteration and camera angle can be done by pressing C at any point during the pathtracing iterations. The checkpoint documents are saved in the build folder under ./checkpoint. To load a checkpoint, pass the path to the checkpoint folder as the second argument to the pathtracer program. +![](img/checkpoint_graph1.png) +![](img/checkpoint_graph2.png) +Checkpoint filesize and time to load are based on the initial resolution of your path traced image. The image buffer as well as metadata is written to a text file and must be reloaded in order to load state. This can lead to a significant load time and file size for high resolution images. This could be optimized in the future by using a serialization library like boost or converting to a more compressed file format. + +### Install Instruction +git clone this repo +Add [tinygltf](https://github.com/syoyo/tinygltf) to external/include/tinygltf +mkdir build +cd build +cmake .. + +Flags can be found in pathtracer.cu +DOF options are included in scene files under camera +Save a checkpoint by pressing c when running the program +Load a checkpoint by passing the path to the checkpoint as the second argument of the program +### Bloopers +![](img/blooper_1.png) +Issues with ray bounces + +![](img/blooper_2.png) +Not offsetting intersection causing noise + +![](img/blooper_3.png) +Strange Refractions + +![](img/blooper_4.png) +Super zoomed in spheres getting DOF to work diff --git a/img/Cache_graph.png b/img/Cache_graph.png new file mode 100644 index 00000000..7d29afaa Binary files /dev/null and b/img/Cache_graph.png differ diff --git a/img/aa.png b/img/aa.png new file mode 100644 index 00000000..4a6676f4 Binary files /dev/null and b/img/aa.png differ diff --git a/img/aa_graph.png b/img/aa_graph.png new file mode 100644 index 00000000..bbeb1086 Binary files /dev/null and b/img/aa_graph.png differ diff --git a/img/big_light.png b/img/big_light.png new file mode 100644 index 00000000..c84d9ce6 Binary files /dev/null and b/img/big_light.png differ diff --git a/img/blooper_1.png b/img/blooper_1.png new file mode 100644 index 00000000..24ab9716 Binary files /dev/null and b/img/blooper_1.png differ diff --git a/img/blooper_2.png b/img/blooper_2.png new file mode 100644 index 00000000..d5af3efe Binary files /dev/null and b/img/blooper_2.png differ diff --git a/img/blooper_3.png b/img/blooper_3.png new file mode 100644 index 00000000..3499df6c Binary files /dev/null and b/img/blooper_3.png differ diff --git a/img/blooper_4.png b/img/blooper_4.png new file mode 100644 index 00000000..565da14f Binary files /dev/null and b/img/blooper_4.png differ diff --git a/img/checkpoint_graph1.png b/img/checkpoint_graph1.png new file mode 100644 index 00000000..51e109f7 Binary files /dev/null and b/img/checkpoint_graph1.png differ diff --git a/img/checkpoint_graph2.png b/img/checkpoint_graph2.png new file mode 100644 index 00000000..2bfbeb93 Binary files /dev/null and b/img/checkpoint_graph2.png differ diff --git a/img/compaction_graph1.png b/img/compaction_graph1.png new file mode 100644 index 00000000..7d1f39e6 Binary files /dev/null and b/img/compaction_graph1.png differ diff --git a/img/compaction_graph2.png b/img/compaction_graph2.png new file mode 100644 index 00000000..19e65e6c Binary files /dev/null and b/img/compaction_graph2.png differ diff --git a/img/cover.png b/img/cover.png new file mode 100644 index 00000000..9f9ff902 Binary files /dev/null and b/img/cover.png differ diff --git a/img/diffuse.png b/img/diffuse.png new file mode 100644 index 00000000..efa03342 Binary files /dev/null and b/img/diffuse.png differ diff --git a/img/dof_10r.png b/img/dof_10r.png new file mode 100644 index 00000000..4b599849 Binary files /dev/null and b/img/dof_10r.png differ diff --git a/img/dof_1r.png b/img/dof_1r.png new file mode 100644 index 00000000..19d0000b Binary files /dev/null and b/img/dof_1r.png differ diff --git a/img/dof_graph.png b/img/dof_graph.png new file mode 100644 index 00000000..6770bbc3 Binary files /dev/null and b/img/dof_graph.png differ diff --git a/img/dof_p1r.png b/img/dof_p1r.png new file mode 100644 index 00000000..35e88b32 Binary files /dev/null and b/img/dof_p1r.png differ diff --git a/img/dof_p5r.png b/img/dof_p5r.png new file mode 100644 index 00000000..6330d4a5 Binary files /dev/null and b/img/dof_p5r.png differ diff --git a/img/imperfect.png b/img/imperfect.png new file mode 100644 index 00000000..d0f75550 Binary files /dev/null and b/img/imperfect.png differ diff --git a/img/material_graph.png b/img/material_graph.png new file mode 100644 index 00000000..f903710d Binary files /dev/null and b/img/material_graph.png differ diff --git a/img/no_aa.png b/img/no_aa.png new file mode 100644 index 00000000..5cabe698 Binary files /dev/null and b/img/no_aa.png differ diff --git a/img/no_dof.png b/img/no_dof.png new file mode 100644 index 00000000..7ae4cde3 Binary files /dev/null and b/img/no_dof.png differ diff --git a/img/no_walls.png b/img/no_walls.png new file mode 100644 index 00000000..0cfc0f1f Binary files /dev/null and b/img/no_walls.png differ diff --git a/img/reflect.png b/img/reflect.png new file mode 100644 index 00000000..afebb129 Binary files /dev/null and b/img/reflect.png differ diff --git a/img/refract.png b/img/refract.png new file mode 100644 index 00000000..3e446484 Binary files /dev/null and b/img/refract.png differ diff --git a/img/small_light.png b/img/small_light.png new file mode 100644 index 00000000..d3635fec Binary files /dev/null and b/img/small_light.png differ diff --git a/img/zoom_aa.png b/img/zoom_aa.png new file mode 100644 index 00000000..f89731b9 Binary files /dev/null and b/img/zoom_aa.png differ diff --git a/img/zoom_no_aa.png b/img/zoom_no_aa.png new file mode 100644 index 00000000..783402f5 Binary files /dev/null and b/img/zoom_no_aa.png differ diff --git a/scenes/DOF.txt b/scenes/DOF.txt new file mode 100644 index 00000000..08dc9bf1 --- /dev/null +++ b/scenes/DOF.txt @@ -0,0 +1,494 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 5 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL .75 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + + +// Start Here +// Specular white +MATERIAL 6 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 7 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL .66 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 8 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL .33 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +MATERIAL 9 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +MATERIAL 10 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 0 +REFR 1 +REFRIOR 1.5 +EMITTANCE 0 + + +//Second row + +MATERIAL 11 +RGB 0 1 .624 +SPECEX 0 +SPECRGB 0 1 .624 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +MATERIAL 12 +RGB 0 1 .624 +SPECEX 0 +SPECRGB 0 1 .624 +REFL .66 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 13 +RGB 0 1 .624 +SPECEX 0 +SPECRGB 0 1 .624 +REFL .33 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 14 +RGB 0 1 .624 +SPECEX 0 +SPECRGB 0 1 .624 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 15 +RGB 0 1 .624 +SPECEX 0 +SPECRGB 0 1 .624 +REFL 0 +REFR 1 +REFRIOR 1.5 +EMITTANCE 0 + +//Third Row + +MATERIAL 16 +RGB 1 .063 .941 +SPECEX 0 +SPECRGB 1 .063 .941 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +MATERIAL 17 +RGB 1 .063 .941 +SPECEX 0 +SPECRGB 1 .063 .941 +REFL .66 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 18 +RGB 1 .063 .941 +SPECEX 0 +SPECRGB 1 .063 .941 +REFL .33 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 19 +RGB 1 .063 .941 +SPECEX 0 +SPECRGB 1 .063 .941 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 20 +RGB 1 .063 .941 +SPECEX 0 +SPECRGB 1 .063 .941 +REFL 0 +REFR 1 +REFRIOR 1.5 +EMITTANCE 0 + +//Fourth Row +MATERIAL 21 +RGB .012 .847 .953 +SPECEX 0 +SPECRGB .012 .847 .953 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +MATERIAL 22 +RGB .012 .847 .953 +SPECEX 0 +SPECRGB .012 .847 .953 +REFL .66 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 23 +RGB .012 .847 .953 +SPECEX 0 +SPECRGB .012 .847 .953 +REFL .33 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 24 +RGB .012 .847 .953 +SPECEX 0 +SPECRGB .012 .847 .953 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 25 +RGB .012 .847 .953 +SPECEX 0 +SPECRGB .012 .847 .953 +REFL 0 +REFR 1 +REFRIOR 1.5 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 8 +FILE cornell +EYE 10 1 7 +LOOKAT 4 5 0 +UP 0 1 0 +DOF 1 +LENSR 10.0 +FOCAL 10.0 + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 30 0 +ROTAT 0 0 0 +SCALE 10 .3 10 + +// Ceiling light +OBJECT 1 +cube +material 0 +TRANS -10 30 -10 +ROTAT 0 0 0 +SCALE 10 .3 10 + +// Ceiling light +OBJECT 2 +cube +material 0 +TRANS -20 30 -20 +ROTAT 0 0 0 +SCALE 10 .3 10 + +// Ceiling light +OBJECT 3 +cube +material 0 +TRANS 0 30 -30 +ROTAT 0 0 0 +SCALE 10 .3 10 + +// Floor +OBJECT 4 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 100 .01 100 + +// Ceiling +OBJECT 5 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE 0 0 0 + + +// Sphere +OBJECT 6 +sphere +material 6 +TRANS -1 4 -14 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 7 +sphere +material 7 +TRANS -1 4 -10 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 8 +sphere +material 8 +TRANS -1 4 -6 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 9 +sphere +material 9 +TRANS -1 4 -2 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 10 +sphere +material 10 +TRANS -1 4 2 +ROTAT 0 0 0 +SCALE 3 3 3 + +//Second Row +// Sphere +OBJECT 11 +sphere +material 11 +TRANS 3 4 -14 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 12 +sphere +material 12 +TRANS 3 4 -10 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 13 +sphere +material 13 +TRANS 3 4 -6 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 14 +sphere +material 14 +TRANS 3 4 -2 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 15 +sphere +material 15 +TRANS 3 4 2 +ROTAT 0 0 0 +SCALE 3 3 3 + +/Third Row +// Sphere +OBJECT 16 +sphere +material 16 +TRANS 7 4 -14 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 17 +sphere +material 17 +TRANS 7 4 -10 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 18 +sphere +material 18 +TRANS 7 4 -6 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 19 +sphere +material 19 +TRANS 7 4 -2 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 20 +sphere +material 20 +TRANS 7 4 2 +ROTAT 0 0 0 +SCALE 3 3 3 + +//Fourth Row +// Sphere +OBJECT 21 +sphere +material 21 +TRANS -5 4 -14 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 22 +sphere +material 22 +TRANS -5 4 -10 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 23 +sphere +material 23 +TRANS -5 4 -6 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 24 +sphere +material 24 +TRANS -5 4 -2 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 25 +sphere +material 25 +TRANS -5 4 2 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Big +OBJECT 26 +sphere +material 9 +TRANS -50 4 -50 +ROTAT 0 0 0 +SCALE 100 100 100 \ No newline at end of file diff --git a/scenes/city.txt b/scenes/city.txt new file mode 100644 index 00000000..f4d933c7 --- /dev/null +++ b/scenes/city.txt @@ -0,0 +1,157 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 5 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 0.0 +REFR 1.0 +REFRIOR 1.5 +EMITTANCE 3 + +// Water +MATERIAL 6 +RGB .83 .94 .97 +SPECEX 0 +SPECRGB .83 .94 .97 +REFL 0.0 +REFR 1.0 +REFRIOR 1.333 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 8 +FILE city +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 + + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 6 .3 6 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 20 0.1 20 + +// Ceiling +OBJECT 2 +sphere +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE 0 0 0 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE .01 10 10 + +// Pole 1 Trunk +OBJECT 4 +cube +material 2 +TRANS -5 3 2 +ROTAT 0 0 0 +SCALE 1 8 1 + +// Pole 1 Arm +OBJECT 5 +cube +material 2 +TRANS -2.5 7 2 +ROTAT 0 0 0 +SCALE 3 0.8 0.8 + +// Right wall +OBJECT 6 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Sphere +OBJECT 7 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 8 +sphere +material 5 +TRANS 1 3 1 +ROTAT 0 0 0 +SCALE 3 3 3 \ No newline at end of file diff --git a/scenes/cornell.txt b/scenes/cornell.txt index 83ff8202..2dedfd06 100644 --- a/scenes/cornell.txt +++ b/scenes/cornell.txt @@ -58,6 +58,9 @@ FILE cornell EYE 0.0 5 10.5 LOOKAT 0 5 0 UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 // Ceiling light @@ -114,4 +117,4 @@ sphere material 4 TRANS -1 4 -1 ROTAT 0 0 0 -SCALE 3 3 3 +SCALE 3 3 3 \ No newline at end of file diff --git a/scenes/cornell_big_light.txt b/scenes/cornell_big_light.txt new file mode 100644 index 00000000..460d0a0b --- /dev/null +++ b/scenes/cornell_big_light.txt @@ -0,0 +1,120 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 64 +FILE cornell_big_light +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 10 .3 10 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 10 .01 10 + +// Ceiling +OBJECT 2 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE .01 10 10 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE .01 10 10 + +// Left wall +OBJECT 4 +cube +material 2 +TRANS -5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Right wall +OBJECT 5 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Sphere +OBJECT 6 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 \ No newline at end of file diff --git a/scenes/cornell_lil_light.txt b/scenes/cornell_lil_light.txt new file mode 100644 index 00000000..aea4974e --- /dev/null +++ b/scenes/cornell_lil_light.txt @@ -0,0 +1,120 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 64 +FILE cornell_big_light +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 1 .3 1 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 10 .01 10 + +// Ceiling +OBJECT 2 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE .01 10 10 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE .01 10 10 + +// Left wall +OBJECT 4 +cube +material 2 +TRANS -5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Right wall +OBJECT 5 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Sphere +OBJECT 6 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 diff --git a/scenes/cornell_no_walls.txt b/scenes/cornell_no_walls.txt new file mode 100644 index 00000000..dbc44b7f --- /dev/null +++ b/scenes/cornell_no_walls.txt @@ -0,0 +1,120 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 8 +FILE cornell_nowalls +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 3 .3 3 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 10 .01 10 + +// Ceiling +OBJECT 2 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE .01 10 10 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE 0 0 0 + +// Left wall +OBJECT 4 +cube +material 2 +TRANS -5 5 0 +ROTAT 0 0 0 +SCALE 0 0 0 + +// Right wall +OBJECT 5 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE 0 0 0 + +// Sphere +OBJECT 6 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 \ No newline at end of file diff --git a/scenes/cornell_original.txt b/scenes/cornell_original.txt new file mode 100644 index 00000000..ce91d487 --- /dev/null +++ b/scenes/cornell_original.txt @@ -0,0 +1,117 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 0 +REFR 1 +REFRIOR 1.5 +EMITTANCE 0 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 8 +FILE cornell +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 3 .3 3 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 10 .01 10 + +// Ceiling +OBJECT 2 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE .01 10 10 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE .01 10 10 + +// Left wall +OBJECT 4 +cube +material 2 +TRANS -5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Right wall +OBJECT 5 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Sphere +OBJECT 6 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 diff --git a/scenes/refract.txt b/scenes/refract.txt new file mode 100644 index 00000000..cb7276a3 --- /dev/null +++ b/scenes/refract.txt @@ -0,0 +1,139 @@ +// Emissive material (light) +MATERIAL 0 +RGB 1 1 1 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 5 + +// Diffuse white +MATERIAL 1 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse red +MATERIAL 2 +RGB .85 .35 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Diffuse green +MATERIAL 3 +RGB .35 .85 .35 +SPECEX 0 +SPECRGB 0 0 0 +REFL 0 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 4 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + +// Specular white +MATERIAL 5 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 0.0 +REFR 1.0 +REFRIOR 1.5 +EMITTANCE 3 + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 8 +FILE cornell +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +DOF 0 +LENSR 0.1 +FOCAL 4.5 + + + +// Ceiling light +OBJECT 0 +cube +material 0 +TRANS 0 10 0 +ROTAT 0 0 0 +SCALE 3 .3 3 + +// Floor +OBJECT 1 +cube +material 1 +TRANS 0 0 0 +ROTAT 0 0 0 +SCALE 10 .01 10 + +// Ceiling +OBJECT 2 +cube +material 1 +TRANS 0 10 0 +ROTAT 0 0 90 +SCALE .01 10 10 + +// Back wall +OBJECT 3 +cube +material 1 +TRANS 0 5 -5 +ROTAT 0 90 0 +SCALE .01 10 10 + +// Left wall +OBJECT 4 +cube +material 2 +TRANS -5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Right wall +OBJECT 5 +cube +material 3 +TRANS 5 5 0 +ROTAT 0 0 0 +SCALE .01 10 10 + +// Sphere +OBJECT 6 +sphere +material 4 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 + +// Sphere +OBJECT 7 +sphere +material 5 +TRANS 1 3 1 +ROTAT 0 0 0 +SCALE 3 3 3 diff --git a/scenes/scene.bin b/scenes/scene.bin new file mode 100644 index 00000000..351b5861 Binary files /dev/null and b/scenes/scene.bin differ diff --git a/scenes/scene.gltf b/scenes/scene.gltf new file mode 100644 index 00000000..3a81363d --- /dev/null +++ b/scenes/scene.gltf @@ -0,0 +1,662 @@ +{ + "accessors": [ + { + "bufferView": 1, + "componentType": 5126, + "count": 4, + "max": [ + 1.0, + 1.0399999618530273, + 1.9900000095367432 + ], + "min": [ + -1.0199999809265137, + 1.0399999618530273, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 48, + "componentType": 5126, + "count": 4, + "max": [ + 0.0, + -1.0, + 0.0 + ], + "min": [ + 0.0, + -1.0, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 96, + "componentType": 5126, + "count": 4, + "max": [ + 1.0, + 1.0399999618530273, + 1.9900000095367432 + ], + "min": [ + -1.0199999809265137, + -0.9900000095367432, + 1.9900000095367432 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 144, + "componentType": 5126, + "count": 4, + "max": [ + 0.0, + 0.0, + -1.0 + ], + "min": [ + 0.0, + 0.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 24, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 192, + "componentType": 5126, + "count": 4, + "max": [ + 1.0, + 1.0399999618530273, + 0.0 + ], + "min": [ + -1.0099999904632568, + -0.9900000095367432, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 240, + "componentType": 5126, + "count": 4, + "max": [ + 0.0, + 0.0, + 1.0 + ], + "min": [ + 0.0, + 0.0, + 1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 48, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 4, + "max": [ + -0.9900000095367432, + 1.0399999618530273, + 1.9900000095367432 + ], + "min": [ + -1.0199999809265137, + -0.9900000095367432, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 336, + "componentType": 5126, + "count": 4, + "max": [ + 0.9999874234199524, + 0.0, + 0.015072920359671116 + ], + "min": [ + 0.9998379945755005, + -0.009850610978901386, + 0.005025057587772608 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 72, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 384, + "componentType": 5126, + "count": 4, + "max": [ + 0.23000000417232513, + 0.2199999988079071, + 1.9800000190734863 + ], + "min": [ + -0.23999999463558197, + -0.1599999964237213, + 1.9800000190734863 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 432, + "componentType": 5126, + "count": 4, + "max": [ + 0.0, + 0.0, + -1.0 + ], + "min": [ + 0.0, + 0.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 96, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 480, + "componentType": 5126, + "count": 4, + "max": [ + 1.0, + 1.0399999618530273, + 1.9900000095367432 + ], + "min": [ + 1.0, + -0.9900000095367432, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 528, + "componentType": 5126, + "count": 4, + "max": [ + -1.0, + 0.0, + 0.0 + ], + "min": [ + -1.0, + 0.0, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 120, + "componentType": 5125, + "count": 6, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 576, + "componentType": 5126, + "count": 20, + "max": [ + 0.699999988079071, + -0.0, + 0.6000000238418579 + ], + "min": [ + -0.05000000074505806, + -0.75, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 816, + "componentType": 5126, + "count": 20, + "max": [ + 0.9596285223960876, + 0.95828777551651, + 1.0 + ], + "min": [ + -0.9535826444625854, + -0.9550641179084778, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 144, + "componentType": 5125, + "count": 30, + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 1056, + "componentType": 5126, + "count": 20, + "max": [ + 0.03999999910593033, + 0.6700000166893005, + 1.2000000476837158 + ], + "min": [ + -0.7099999785423279, + -0.09000000357627869, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 1296, + "componentType": 5126, + "count": 20, + "max": [ + 0.9550641775131226, + 0.9535826444625854, + 1.0 + ], + "min": [ + -0.9550641775131226, + -0.9535826444625854, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 0, + "byteOffset": 264, + "componentType": 5125, + "count": 30, + "type": "SCALAR" + } + ], + "asset": { + "extras": { + "author": "t-ly (https://sketchfab.com/t-ly)", + "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)", + "source": "https://sketchfab.com/3d-models/cornell-box-original-0d18de8d108c4c9cab1a4405698cc6b6", + "title": "Cornell Box- Original" + }, + "generator": "Sketchfab-12.66.0", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 384, + "name": "floatBufferViews", + "target": 34963 + }, + { + "buffer": 0, + "byteLength": 1536, + "byteOffset": 384, + "byteStride": 12, + "name": "floatBufferViews", + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 1920, + "uri": "scene.bin" + } + ], + "materials": [ + { + "doubleSided": true, + "name": "backWall", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.725, + 0.71, + 0.68, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "ceiling", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.725, + 0.71, + 0.68, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "floor", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.725, + 0.71, + 0.68, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "leftWall", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.63, + 0.065, + 0.05, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "light", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.78, + 0.78, + 0.78, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "rightWall", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.14, + 0.45, + 0.091, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "shortBox", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.725, + 0.71, + 0.68, + 1.0 + ], + "metallicFactor": 0.0 + } + }, + { + "doubleSided": true, + "name": "tallBox", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.725, + 0.71, + 0.68, + 1.0 + ], + "metallicFactor": 0.0 + } + } + ], + "meshes": [ + { + "name": "Object_0", + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 0 + }, + "indices": 2, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Object_1", + "primitives": [ + { + "attributes": { + "NORMAL": 4, + "POSITION": 3 + }, + "indices": 5, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Object_2", + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 6 + }, + "indices": 8, + "material": 2, + "mode": 4 + } + ] + }, + { + "name": "Object_3", + "primitives": [ + { + "attributes": { + "NORMAL": 10, + "POSITION": 9 + }, + "indices": 11, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Object_4", + "primitives": [ + { + "attributes": { + "NORMAL": 13, + "POSITION": 12 + }, + "indices": 14, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Object_5", + "primitives": [ + { + "attributes": { + "NORMAL": 16, + "POSITION": 15 + }, + "indices": 17, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Object_6", + "primitives": [ + { + "attributes": { + "NORMAL": 19, + "POSITION": 18 + }, + "indices": 20, + "material": 6, + "mode": 4 + } + ] + }, + { + "name": "Object_7", + "primitives": [ + { + "attributes": { + "NORMAL": 22, + "POSITION": 21 + }, + "indices": 23, + "material": 7, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.220446049250313e-16, + -1.0, + 0.0, + 0.0, + 1.0, + 2.220446049250313e-16, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Sketchfab_model" + }, + { + "children": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "name": "CornellBox-Original.obj.cleaner.materialmerger.gles" + }, + { + "mesh": 0, + "name": "Object_2" + }, + { + "mesh": 1, + "name": "Object_3" + }, + { + "mesh": 2, + "name": "Object_4" + }, + { + "mesh": 3, + "name": "Object_5" + }, + { + "mesh": 4, + "name": "Object_6" + }, + { + "mesh": 5, + "name": "Object_7" + }, + { + "mesh": 6, + "name": "Object_8" + }, + { + "mesh": 7, + "name": "Object_9" + } + ], + "scene": 0, + "scenes": [ + { + "name": "Sketchfab_Scene", + "nodes": [ + 0 + ] + } + ] +} diff --git a/src/interactions.h b/src/interactions.h index f969e458..724ee46a 100644 --- a/src/interactions.h +++ b/src/interactions.h @@ -72,8 +72,58 @@ void scatterRay( glm::vec3 intersect, glm::vec3 normal, const Material &m, - thrust::default_random_engine &rng) { + thrust::default_random_engine &rng, bool outside) { // TODO: implement this. // A basic implementation of pure-diffuse shading will just call the // calculateRandomDirectionInHemisphere defined above. + thrust::uniform_real_distribution u01(0, 1); + auto rand = u01(rng); + if (m.hasReflective > rand) + { + pathSegment.ray.direction = glm::reflect(pathSegment.ray.direction, normal); + pathSegment.ray.origin = intersect; + pathSegment.color *= (m.specular.color); //* glm::dot(normal, pathSegment.ray.direction); + + } + //Adopted from PBRT and How to raytrace in a weekend + else if (m.hasRefractive) + { + //FRESNEL + float cosTheta = (glm::dot(-pathSegment.ray.direction, normal)); + float r_zero = ((1.0f - m.indexOfRefraction) / (1.0f + m.indexOfRefraction)) * ((1.0f - m.indexOfRefraction) / (1.0f + m.indexOfRefraction)); + float r_theta = r_zero + (1.0f - r_zero) * glm::pow((1.0f - cosTheta), 5.0f); + float sinTheta = sqrt(1 - cosTheta * cosTheta); + bool interal_reflection = false; + float rior = (outside ? 1.0f / m.indexOfRefraction : m.indexOfRefraction); + if (sinTheta * rior > 1.0f) + { + interal_reflection = true; + } + if (rand > r_theta && !interal_reflection) + { + //refract + pathSegment.color *= (m.color); + pathSegment.ray.origin = intersect + (0.001f * pathSegment.ray.direction); + pathSegment.ray.direction = glm::refract(pathSegment.ray.direction, normal, rior); + } + else + { + //reflect + pathSegment.ray.direction = glm::reflect(pathSegment.ray.direction, normal); + pathSegment.ray.origin = intersect; + pathSegment.color *= (m.specular.color); + + } + + } + else + { + auto random = calculateRandomDirectionInHemisphere(normal, rng); + + pathSegment.ray.direction = random; + pathSegment.ray.origin = intersect; + pathSegment.color *= (m.color); + + } + pathSegment.remainingBounces--; } diff --git a/src/main.cpp b/src/main.cpp index 96127b6d..29b1756d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,21 @@ #include "main.h" #include "preview.h" #include - +#include "glm/gtx/string_cast.hpp" +#define TINYGLTF_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION +//#define TINYGLTF_NO_INCLUDE_STB_IMAGE +//#define TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE +#include "tiny_gltf.h" static std::string startTimeString; // For camera controls static bool leftMousePressed = false; static bool rightMousePressed = false; static bool middleMousePressed = false; +static bool hasCheckpoint = false; +static bool saveCheckpoint = false; static double lastX; static double lastY; @@ -40,15 +48,40 @@ int main(int argc, char** argv) { } const char* sceneFile = argv[1]; + char* checkpoint_folder = ""; + if (argc == 3) + { + checkpoint_folder = argv[2]; + hasCheckpoint = true; + } + + tinygltf::Model model; + tinygltf::TinyGLTF loader; + std::string err; + std::string warn; + + bool gltf = loader.LoadASCIIFromFile(&model, &err, &warn, argv[1]); + //bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, argv[1]); // for binary glTF(.glb) // Load scene file - scene = new Scene(sceneFile); + if (gltf) + { + scene = new Scene(model); + } + else { + scene = new Scene(sceneFile); + } //Create Instance for ImGUIData guiData = new GuiDataContainer(); // Set up camera stuff from loaded path tracer settings iteration = 0; + Camera old = scene->state.camera; + if (hasCheckpoint) + { + loadState(checkpoint_folder); + } renderState = &scene->state; Camera& cam = renderState->camera; width = cam.resolution.x; @@ -107,8 +140,11 @@ void saveImage() { } void runCuda() { - if (camchanged) { - iteration = 0; + if (camchanged && !hasCheckpoint) { + if (!hasCheckpoint) + { + iteration = 0; + } Camera& cam = renderState->camera; cameraPosition.x = zoom * sin(phi) * sin(theta); cameraPosition.y = zoom * cos(theta); @@ -134,6 +170,18 @@ void runCuda() { pathtraceFree(); pathtraceInit(scene); } + if (hasCheckpoint) { + pathtraceFree(); + pathtraceInit(scene); + pathtraceInitCheckpoint(scene); + hasCheckpoint = false; + camchanged = false; + } + if (saveCheckpoint) + { + saveState(); + saveCheckpoint = false; + } if (iteration < renderState->iterations) { uchar4* pbo_dptr = NULL; @@ -155,6 +203,74 @@ void runCuda() { } } + +void saveState() +{ + glm::io::precision(9); + std::cout << "Begining Checkpoint" << std::endl; + auto state = scene->state; + auto camera = state.camera; + std::ofstream image_output_file("./checkpoint/image.data"); + image_output_file<< std::fixed << std::setprecision(6) << glm::io::precision(6); + std::ostream_iterator output_iterator(image_output_file, ","); + std::copy(state.image.begin(), state.image.end(), output_iterator); + std::ofstream iterations_output_file("./checkpoint/iterations.data"); + iterations_output_file << iteration; + std::ofstream camera_output_file("./checkpoint/camera.data"); + camera_output_file << std::fixed << std::setprecision(6) << glm::io::precision(9); + camera_output_file << camera.resolution << camera.position << camera.lookAt << camera.view << camera.up << camera.right << camera.fov << camera.pixelLength; + //glm::ivec2 resolution; + //glm::vec3 position; + //glm::vec3 lookAt; + //glm::vec3 view; + //glm::vec3 up; + //glm::vec3 right; + //glm::vec2 fov; + //glm::vec2 pixelLength; + camera_output_file << " " << camera.dof << " " << camera.lens_radius << " " << camera.focal_length; + std::cout << "Checkpoint Complete" << std::endl; + +} + +void loadState(string checkpoint_folder) +{ + //GLM doesn't have an input stream operator + std::cout << "Loading Checkpoint" << std::endl; + std::ifstream image_file(checkpoint_folder + "/image.data"); + char first_bracket; + double x_value; + double y_value; + double z_value; + char second_bracket; + char comma; + std::vector image; + while (image_file >> first_bracket) + { + + image_file >> x_value >> comma >> y_value >> comma >> z_value >> second_bracket >> comma; + glm::vec3 temp(x_value, y_value, z_value); + image.push_back(temp); + } + scene->state.image = image; + std::ifstream iterations_file(checkpoint_folder + "/iterations.data"); + iterations_file >> iteration; + std::ifstream camera_file(checkpoint_folder + "/camera.data"); + glm::ivec2 resolution = utilityCore::readIVec2(camera_file); + glm::vec3 position = utilityCore::readVec3(camera_file); + glm::vec3 lookAt = utilityCore::readVec3(camera_file); + glm::vec3 view = utilityCore::readVec3(camera_file); + glm::vec3 up = utilityCore::readVec3(camera_file); + glm::vec3 right = utilityCore::readVec3(camera_file); + glm::vec2 fov = utilityCore::readVec2(camera_file); + glm::vec2 pixelLength = utilityCore::readVec2(camera_file); + bool dof; + float lens_radius; + float focal_length; + camera_file >> dof >> lens_radius >> focal_length; + scene->state.camera = { resolution, position, lookAt, view, up, right, fov, pixelLength, dof, lens_radius, focal_length}; + std::cout << "Loading Checkpoint Complete" << std::endl; +} + void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS) { switch (key) { @@ -165,6 +281,9 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods case GLFW_KEY_S: saveImage(); break; + case GLFW_KEY_C: + saveCheckpoint = true; + break; case GLFW_KEY_SPACE: camchanged = true; renderState = &scene->state; diff --git a/src/main.h b/src/main.h index fdb7d5d1..cccfb67d 100644 --- a/src/main.h +++ b/src/main.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "glslUtility.hpp" #include #include @@ -36,3 +37,6 @@ void runCuda(); void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); void mousePositionCallback(GLFWwindow* window, double xpos, double ypos); void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +void saveState(); +void loadState(string checkpointFolder); + diff --git a/src/pathtrace.cu b/src/pathtrace.cu index fd2a4641..29527398 100644 --- a/src/pathtrace.cu +++ b/src/pathtrace.cu @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "sceneStructs.h" #include "scene.h" @@ -15,6 +17,9 @@ #include "interactions.h" #define ERRORCHECK 1 +#define SORTMATERIALS 1 +#define CACHE 0 +#define ANTIALIAS 1 #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) @@ -70,12 +75,18 @@ __global__ void sendImageToPBO(uchar4* pbo, glm::ivec2 resolution, static Scene* hst_scene = NULL; static GuiDataContainer* guiData = NULL; static glm::vec3* dev_image = NULL; +static glm::vec3* dev_image_buffer = NULL; static Geom* dev_geoms = NULL; static Material* dev_materials = NULL; static PathSegment* dev_paths = NULL; static ShadeableIntersection* dev_intersections = NULL; + // TODO: static variables for device memory, any extra info you need, etc // ... +#if CACHE +static bool hasCache = false; +static ShadeableIntersection* dev_intersectionsFirstCache = NULL; +#endif void InitDataContainer(GuiDataContainer* imGuiData) { @@ -91,6 +102,9 @@ void pathtraceInit(Scene* scene) { cudaMalloc(&dev_image, pixelcount * sizeof(glm::vec3)); cudaMemset(dev_image, 0, pixelcount * sizeof(glm::vec3)); + cudaMalloc(&dev_image_buffer, pixelcount * sizeof(glm::vec3)); + cudaMemset(dev_image_buffer, 0, pixelcount * sizeof(glm::vec3)); + cudaMalloc(&dev_paths, pixelcount * sizeof(PathSegment)); cudaMalloc(&dev_geoms, scene->geoms.size() * sizeof(Geom)); @@ -103,17 +117,38 @@ void pathtraceInit(Scene* scene) { cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection)); // TODO: initialize any extra device memeory you need +#if CACHE + cudaMalloc(&dev_intersectionsFirstCache, pixelcount * sizeof(ShadeableIntersection)); + +#endif checkCUDAError("pathtraceInit"); } +void pathtraceInitCheckpoint(Scene* scene) +{ + hst_scene = scene; + + const Camera& cam = hst_scene->state.camera; + const int pixelcount = cam.resolution.x * cam.resolution.y; + + cudaMemcpy(dev_image, hst_scene->state.image.data(), + pixelcount * sizeof(glm::vec3), cudaMemcpyHostToDevice); + checkCUDAError("pathtraceCheckpointInit"); + +} + void pathtraceFree() { cudaFree(dev_image); // no-op if dev_image is null + cudaFree(dev_image_buffer); cudaFree(dev_paths); cudaFree(dev_geoms); cudaFree(dev_materials); cudaFree(dev_intersections); // TODO: clean up any extra device memory you created +#if CACHE + cudaFree(dev_intersectionsFirstCache); +#endif checkCUDAError("pathtraceFree"); } @@ -126,23 +161,73 @@ void pathtraceFree() { * motion blur - jitter rays "in time" * lens effect - jitter ray origin positions based on a lens */ + +__device__ __host__ glm::vec2 concentricDisc(glm::vec2 u, thrust::default_random_engine rng) +{ + thrust::uniform_real_distribution uNeg11(-1, 1); + glm::vec2 offset(uNeg11(rng), uNeg11(rng)); + float theta; + float r; + if (offset.x == 0.0f && offset.y == 0.0f) + { + return glm::vec2(0, 0); + } + if (std::abs(offset.x) > std::abs(offset.y)) + { + r = offset.x; + theta = PI / 4.0f * (offset.y / offset.x); + + } + else + { + r = offset.y; + theta = PI / 2.0f - PI / 4.0f * (offset.x / offset.y); + } + return r * glm::vec2(cos(theta), sin(theta)); +} + __global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth, PathSegment* pathSegments) { int x = (blockIdx.x * blockDim.x) + threadIdx.x; int y = (blockIdx.y * blockDim.y) + threadIdx.y; - + float lens_radius = cam.lens_radius; + float focal_length = cam.focal_length; + bool dof = cam.dof; if (x < cam.resolution.x && y < cam.resolution.y) { int index = x + (y * cam.resolution.x); PathSegment& segment = pathSegments[index]; - + thrust::uniform_real_distribution u01(0, 1); + thrust::uniform_real_distribution uNeg11(-1, 1); + auto rng = makeSeededRandomEngine(iter, index, traceDepth); +; segment.ray.origin = cam.position; segment.color = glm::vec3(1.0f, 1.0f, 1.0f); - // TODO: implement antialiasing by jittering the ray + // implemented antialiasing by jittering the ray +#if ANTIALIAS && !CACHE + segment.ray.direction = glm::normalize(cam.view + - cam.right * cam.pixelLength.x * ((float)x + u01(rng) - (float)cam.resolution.x * 0.5f) + - cam.up * cam.pixelLength.y * ((float)y + u01(rng) - (float)cam.resolution.y * 0.5f) + ); +#else segment.ray.direction = glm::normalize(cam.view - cam.right * cam.pixelLength.x * ((float)x - (float)cam.resolution.x * 0.5f) - - cam.up * cam.pixelLength.y * ((float)y - (float)cam.resolution.y * 0.5f) + - cam.up * cam.pixelLength.y * ((float)y - (float)cam.resolution.y * 0.5f) ); +#endif +#if !CACHE + if (dof) + { + auto lens = makeSeededRandomEngine(iter, index, focal_length); + glm::vec2 offset = concentricDisc(glm::vec2(), lens) * lens_radius; + glm::vec3 focal_point = getPointOnRay(segment.ray, focal_length); + segment.ray.origin.x += offset.x; + segment.ray.origin.y += offset.y; + segment.ray.direction = glm::normalize(focal_point - segment.ray.origin); + } + +#endif + segment.pixelIndex = index; segment.remainingBounces = traceDepth; @@ -205,7 +290,7 @@ __global__ void computeIntersections( } } - if (hit_geom_index == -1) + if (hit_geom_index == -1 ) { intersections[path_index].t = -1.0f; } @@ -215,6 +300,8 @@ __global__ void computeIntersections( intersections[path_index].t = t_min; intersections[path_index].materialId = geoms[hit_geom_index].materialid; intersections[path_index].surfaceNormal = normal; + intersections[path_index].outside = outside; + } } } @@ -239,12 +326,13 @@ __global__ void shadeFakeMaterial( int idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < num_paths) { + ShadeableIntersection intersection = shadeableIntersections[idx]; if (intersection.t > 0.0f) { // if the intersection exists... // Set up the RNG // LOOK: this is how you use thrust's RNG! Please look at // makeSeededRandomEngine as well. - thrust::default_random_engine rng = makeSeededRandomEngine(iter, idx, 0); + thrust::default_random_engine rng = makeSeededRandomEngine(iter, idx, pathSegments[idx].remainingBounces); thrust::uniform_real_distribution u01(0, 1); Material material = materials[intersection.materialId]; @@ -253,14 +341,18 @@ __global__ void shadeFakeMaterial( // If the material indicates that the object was a light, "light" the ray if (material.emittance > 0.0f) { pathSegments[idx].color *= (materialColor * material.emittance); + pathSegments[idx].remainingBounces = 0; } // Otherwise, do some pseudo-lighting computation. This is actually more // like what you would expect from shading in a rasterizer like OpenGL. // TODO: replace this! you should be able to start with basically a one-liner else { - float lightTerm = glm::dot(intersection.surfaceNormal, glm::vec3(0.0f, 1.0f, 0.0f)); - pathSegments[idx].color *= (materialColor * lightTerm) * 0.3f + ((1.0f - intersection.t * 0.02f) * materialColor) * 0.7f; - pathSegments[idx].color *= u01(rng); // apply some noise because why not + //float lightTerm = glm::dot(intersection.surfaceNormal, glm::vec3(0.0f, 1.0f, 0.0f)); + //pathSegments[idx].color *= (materialColor * lightTerm) * 0.3f + ((1.0f - intersection.t * 0.02f) * materialColor) * 0.7f; + //pathSegments[idx].color *= u01(rng); // apply some noise because why not + //glm::vec3 intersection_point = pathSegments[idx].ray.origin + (intersection.t * pathSegments[idx].ray.direction); + glm::vec3 intersection_point = getPointOnRay(pathSegments[idx].ray, intersection.t); + scatterRay(pathSegments[idx], intersection_point, intersection.surfaceNormal, material, rng, intersection.outside); } // If there was no intersection, color the ray black. // Lots of renderers use 4 channel color, RGBA, where A = alpha, often @@ -274,7 +366,7 @@ __global__ void shadeFakeMaterial( } // Add the current iteration's output to the overall image -__global__ void finalGather(int nPaths, glm::vec3* image, PathSegment* iterationPaths) +__global__ void finalGather(int nPaths, glm::vec3* image, glm::vec3* image_buffer, PathSegment* iterationPaths, int iter) { int index = (blockIdx.x * blockDim.x) + threadIdx.x; @@ -333,10 +425,8 @@ void pathtrace(uchar4* pbo, int frame, int iter) { // for you. // TODO: perform one iteration of path tracing - generateRayFromCamera << > > (cam, iter, traceDepth, dev_paths); checkCUDAError("generate camera ray"); - int depth = 0; PathSegment* dev_path_end = dev_paths + pixelcount; int num_paths = dev_path_end - dev_paths; @@ -345,24 +435,52 @@ void pathtrace(uchar4* pbo, int frame, int iter) { // Shoot ray into scene, bounce between objects, push shading chunks bool iterationComplete = false; + int running_paths = num_paths; while (!iterationComplete) { - // clean shading chunks cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection)); // tracing - dim3 numblocksPathSegmentTracing = (num_paths + blockSize1d - 1) / blockSize1d; + dim3 numblocksPathSegmentTracing = (running_paths + blockSize1d - 1) / blockSize1d; + + +#if CACHE + if (hasCache && depth == 0) + { + cudaMemcpy(dev_intersections, dev_intersectionsFirstCache, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice); + } + else + { + computeIntersections << > > ( + depth + , running_paths + , dev_paths + , dev_geoms + , hst_scene->geoms.size() + , dev_intersections + ); + } + if (!hasCache && depth == 0) + { + cudaMemcpy(dev_intersectionsFirstCache, dev_intersections, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice); + } +#else computeIntersections << > > ( depth - , num_paths + , running_paths , dev_paths , dev_geoms , hst_scene->geoms.size() , dev_intersections ); +#endif checkCUDAError("trace one bounce"); cudaDeviceSynchronize(); depth++; + +#if SORTMATERIALS //IF SORTMATERIALS + sortMaterials(dev_intersections, dev_paths, running_paths); +#endif // TODO: // --- Shading Stage --- @@ -375,12 +493,18 @@ void pathtrace(uchar4* pbo, int frame, int iter) { shadeFakeMaterial << > > ( iter, - num_paths, + running_paths, dev_intersections, dev_paths, dev_materials ); - iterationComplete = true; // TODO: should be based off stream compaction results. + + running_paths = streamCompact(dev_intersections, dev_paths, running_paths); + if (running_paths == 0 ) + { + iterationComplete = true; // TODO: should be based off stream compaction results. + } + if (guiData != NULL) { @@ -390,7 +514,7 @@ void pathtrace(uchar4* pbo, int frame, int iter) { // Assemble this iteration and apply it to the image dim3 numBlocksPixels = (pixelcount + blockSize1d - 1) / blockSize1d; - finalGather << > > (num_paths, dev_image, dev_paths); + finalGather << > > (num_paths, dev_image, dev_image_buffer, dev_paths, iter); /////////////////////////////////////////////////////////////////////////// @@ -403,3 +527,50 @@ void pathtrace(uchar4* pbo, int frame, int iter) { checkCUDAError("pathtrace"); } +struct is_not_terminated +{ + __host__ __device__ bool operator() (const ShadeableIntersection& x) + { + return(x.t != -1.0f); + } + +}; + +struct bounces_not_terminated +{ + __host__ __device__ bool operator() (const PathSegment& x) + { + return(x.remainingBounces > 0); + } + +}; +int streamCompact(ShadeableIntersection* intersections, PathSegment* paths, int num_paths) +{ + thrust::device_ptr dev_thrust_paths(paths); + thrust::device_ptr dev_thrust_intersections(intersections); + + //Stencil + auto new_end = thrust::partition(dev_thrust_paths, dev_thrust_paths + num_paths, dev_thrust_intersections, is_not_terminated()); + //No Stencil + int num = (new_end - dev_thrust_paths); + new_end = thrust::partition(dev_thrust_paths, dev_thrust_paths + num, bounces_not_terminated()); + num = (new_end - dev_thrust_paths); + return num; +} + +struct material_id_greater +{ + __host__ __device__ bool operator() (const ShadeableIntersection& x, const ShadeableIntersection& y) + { + return(x.materialId > y.materialId); + } + +}; + +void sortMaterials(ShadeableIntersection* intersections, PathSegment* paths, int num_paths) +{ + thrust::device_ptr dev_thrust_paths(paths); + thrust::device_ptr dev_thrust_intersections(intersections); + + thrust::sort_by_key(dev_thrust_intersections, dev_thrust_intersections + num_paths, dev_thrust_paths, material_id_greater()); +} \ No newline at end of file diff --git a/src/pathtrace.h b/src/pathtrace.h index e767d0ef..68f4cd48 100644 --- a/src/pathtrace.h +++ b/src/pathtrace.h @@ -5,5 +5,8 @@ void InitDataContainer(GuiDataContainer* guiData); void pathtraceInit(Scene *scene); +void pathtraceInitCheckpoint(Scene* scene); void pathtraceFree(); void pathtrace(uchar4 *pbo, int frame, int iteration); +int streamCompact(ShadeableIntersection* intersections, PathSegment* paths, int num_paths); +void sortMaterials(ShadeableIntersection* intersections, PathSegment* paths, int num_paths); \ No newline at end of file diff --git a/src/scene.cpp b/src/scene.cpp index 3fb6239a..f33c4e5f 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -4,6 +4,23 @@ #include #include +Scene::Scene(tinygltf::Model model) { + int id = 0; + for (auto m : model.materials) + { + loadMaterial(m, id); + id++; + } + id = 0; + for (auto g : model.meshes) + { + loadGeom(g, id); + } +} + + + + Scene::Scene(string filename) { cout << "Reading scene from " << filename << " ..." << endl; cout << " " << endl; @@ -32,6 +49,17 @@ Scene::Scene(string filename) { } } +int Scene::loadGeom(tinygltf::Mesh mesh, int id) +{ + Geom newGeom; + cout << "Creating new mesh..." << endl; + newGeom.type = MESH; + newGeom.materialid = mesh.primitives[0].material; + + return 1; + +} + int Scene::loadGeom(string objectid) { int id = atoi(objectid.c_str()); if (id != geoms.size()) { @@ -125,7 +153,15 @@ int Scene::loadCamera() { } else if (strcmp(tokens[0].c_str(), "UP") == 0) { camera.up = glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str())); } - + else if (strcmp(tokens[0].c_str(), "DOF") == 0) { + camera.dof = atof(tokens[1].c_str()); + } + else if (strcmp(tokens[0].c_str(), "LENSR") == 0) { + camera.lens_radius = atof(tokens[1].c_str()); + } + else if (strcmp(tokens[0].c_str(), "FOCAL") == 0) { + camera.focal_length = atof(tokens[1].c_str()); + } utilityCore::safeGetline(fp_in, line); } @@ -186,3 +222,28 @@ int Scene::loadMaterial(string materialid) { return 1; } } + +int Scene::loadMaterial(tinygltf::Material gltf_mat, int id) { + if (id != materials.size()) { + cout << "ERROR: MATERIAL ID does not match expected number of materials" << endl; + return -1; + } + else { + cout << "Loading Material " << id << "..." << endl; + Material newMaterial; + + //load static properties + newMaterial.color.r = gltf_mat.pbrMetallicRoughness.baseColorFactor[0]; + newMaterial.color.g = gltf_mat.pbrMetallicRoughness.baseColorFactor[1]; + newMaterial.color.b = gltf_mat.pbrMetallicRoughness.baseColorFactor[2]; + newMaterial.specular.exponent = 0; + newMaterial.specular.color = newMaterial.color; + newMaterial.hasReflective = 0; + newMaterial.hasRefractive = 0; + newMaterial.indexOfRefraction = 0; + newMaterial.emittance = gltf_mat.emissiveFactor[0]; + + materials.push_back(newMaterial); + return 1; + } +} diff --git a/src/scene.h b/src/scene.h index f29a9171..7f2ca11b 100644 --- a/src/scene.h +++ b/src/scene.h @@ -7,6 +7,7 @@ #include "glm/glm.hpp" #include "utilities.h" #include "sceneStructs.h" +#include "tiny_gltf.h" using namespace std; @@ -14,10 +15,13 @@ class Scene { private: ifstream fp_in; int loadMaterial(string materialid); + int loadMaterial(tinygltf::Material, int id); int loadGeom(string objectid); + int loadGeom(tinygltf::Mesh mesh, int id); int loadCamera(); public: Scene(string filename); + Scene(tinygltf::Model model); ~Scene(); std::vector geoms; diff --git a/src/sceneStructs.h b/src/sceneStructs.h index da4dbf30..0bcef96e 100644 --- a/src/sceneStructs.h +++ b/src/sceneStructs.h @@ -10,6 +10,7 @@ enum GeomType { SPHERE, CUBE, + MESH }; struct Ray { @@ -49,6 +50,9 @@ struct Camera { glm::vec3 right; glm::vec2 fov; glm::vec2 pixelLength; + bool dof; + float lens_radius; + float focal_length; }; struct RenderState { @@ -73,4 +77,5 @@ struct ShadeableIntersection { float t; glm::vec3 surfaceNormal; int materialId; + bool outside; }; diff --git a/src/stb.cpp b/src/stb.cpp index 08bf6ef6..cf908594 100644 --- a/src/stb.cpp +++ b/src/stb.cpp @@ -1,5 +1,5 @@ -#define STB_IMAGE_IMPLEMENTATION -#include +//#define STB_IMAGE_IMPLEMENTATION +//#include -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include +//#define STB_IMAGE_WRITE_IMPLEMENTATION +//#include diff --git a/src/utilities.cpp b/src/utilities.cpp index 9c06c686..a9f4c12e 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -110,3 +110,37 @@ std::istream& utilityCore::safeGetline(std::istream& is, std::string& t) { } } } +glm::vec3 utilityCore::readVec3(std::ifstream& is) +{ + char first_bracket; + double x_value; + double y_value; + double z_value; + char second_bracket; + char comma; + is >> first_bracket >> x_value >> comma >> y_value >> comma >> z_value >> second_bracket; + return glm::vec3(x_value, y_value, z_value); + +} +glm::vec2 utilityCore::readVec2(std::ifstream& is) +{ + char first_bracket; + double x_value; + double y_value; + char second_bracket; + char comma; + is >> first_bracket >> x_value >> comma >> y_value >> second_bracket; + return glm::vec2(x_value, y_value); +} +//Make this a template +glm::ivec2 utilityCore::readIVec2(std::ifstream& is) +{ + char first_bracket; + int x_value; + int y_value; + char second_bracket; + char comma; + is >> first_bracket >> x_value >> comma >> y_value>> second_bracket; + return glm::ivec2(x_value, y_value); + +} diff --git a/src/utilities.h b/src/utilities.h index d459e335..bbb7041d 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -8,6 +8,7 @@ #include #include #include +#include #define PI 3.1415926535897932384626422832795028841971f #define TWO_PI 6.2831853071795864769252867665590057683943f @@ -21,6 +22,7 @@ class GuiDataContainer int TracedDepth; }; + namespace utilityCore { extern float clamp(float f, float min, float max); extern bool replaceString(std::string& str, const std::string& from, const std::string& to); @@ -30,4 +32,7 @@ namespace utilityCore { extern glm::mat4 buildTransformationMatrix(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale); extern std::string convertIntToString(int number); extern std::istream& safeGetline(std::istream& is, std::string& t); //Thanks to http://stackoverflow.com/a/6089413 + extern glm::vec3 readVec3(std::ifstream& is); + extern glm::vec2 readVec2(std::ifstream& is); + extern glm::ivec2 readIVec2(std::ifstream& is); }