diff --git a/README.md b/README.md index 110697ce..3461cf04 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,116 @@ 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) +* ADITHYA RAJEEV + * [LinkedIn](https://www.linkedin.com/in/adithyar262/) +* Tested on: Windows 11, i7 13th Gen @ 2.40GHz 16GB, GeForce RTX 4050 8GB (Personal) -### (TODO: Your README) +### Overview -*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. +This project implements a CUDA-based path tracer with various advanced rendering features. The path tracer is capable of simulating complex light interactions in 3D scenes, producing physically-based, photorealistic images. +![](img/testRuns/Presentation1.png) + +![](img/testRuns/Presentation2.png) + +![](img/testRuns/Presentation3.png) + + +## Features + +### Core Functionality + +* **BSDF Evaluation**: + * Ideal diffuse surfaces (Lambertian reflection) + +![](img/testRuns/Cornell_Box.png) + + * Perfectly specular-reflective surfaces (mirrors) + +![](img/testRuns/Specular_Scene.png) + +* **Path continuation/termination** using Stream Compaction +* **Material-based ray sorting** for optimized performance + +I implemented material sorting for my path segments and intersections before calling the material shading kernel, expecting it to improve performance. +However, I was surprised to find that this actually made my path tracer slower. Upon reflection, I realized that this might be due to the lack of diversity in my material types. It seems that in my current scene setup, the overhead from sorting is greater than any performance gains from reducing warp divergence. This suggests that the effectiveness of material sorting might depend heavily on the complexity and variety of materials in the scene. + +![](img/testRuns/MaterialSortTable.png) + +* **Stochastic sampled antialiasing** + +#### With Anti-Aliasing + +![](img/testRuns/WithoutAntiAliasing.png) + +#### Without Anti-Aliasing + +![](img/testRuns/WithAntiAliasing.png) + + +### Advanced Features + +* **Refraction** with Fresnel effects (e.g., glass, water) + +![](img/testRuns/Diffuse_Reflection_Refraction.png) + +* **Physically-based depth-of-field** + +#### Depth of Field Enabled + +![](img/testRuns/depth_of_field1.png) + +#### Depth of Field Disabled + +![](img/testRuns/depth_of_field_disabled1.png) + +* **Direct lighting simulation** + +#### Direct Lighting Enabled + +![](img/testRuns/DirectLightingEnabled.png) + +#### Direct Lighting Disabled + +![](img/testRuns/DirectLightingDisabled.png) + +### Russian Roulette Path Termination + +Russian Roulette technique was implemented to terminate unimportant paths early. Our analysis shows: + +* fps with Russian Roulette Enabled - 43.2 fps +* fps with Russian Roulette Enabled - 34.9 fps +* 23.78% Increase in FPS +* Negligible impact on image quality + +#### Russian Roulette Enabled + +![](img/testRuns/RussianRouletteEnabled.png) + +#### Russian Roulette Disabled + +![](img/testRuns/RussianRouletteDisabled.png) + +* **Physically-based rendering with Metallic and Platic materials** + +![](img/testRuns/materials.png) + +## Bloopers + +![](img/testRuns/Blooper1.png) + +![](img/testRuns/Blooper2.png) + +![](img/testRuns/Blooper3.png) + +![](img/testRuns/Blooper4.png) + +![](img/testRuns/Blooper5.png) + +![](img/testRuns/Blooper6.png) + +## References + +* [PBRT-v3 Book](https://www.pbrt.org/) +* [Physically Based Rendering: From Theory To Implementation](http://www.pbr-book.org/) +* [NVIDIA CUDA Documentation](https://docs.nvidia.com/cuda/) diff --git a/img/testRuns/Blooper1.png b/img/testRuns/Blooper1.png new file mode 100644 index 00000000..4aa80830 Binary files /dev/null and b/img/testRuns/Blooper1.png differ diff --git a/img/testRuns/Blooper2.png b/img/testRuns/Blooper2.png new file mode 100644 index 00000000..c2404120 Binary files /dev/null and b/img/testRuns/Blooper2.png differ diff --git a/img/testRuns/Blooper3.png b/img/testRuns/Blooper3.png new file mode 100644 index 00000000..139b8036 Binary files /dev/null and b/img/testRuns/Blooper3.png differ diff --git a/img/testRuns/Blooper4.png b/img/testRuns/Blooper4.png new file mode 100644 index 00000000..265d4a39 Binary files /dev/null and b/img/testRuns/Blooper4.png differ diff --git a/img/testRuns/Blooper5.png b/img/testRuns/Blooper5.png new file mode 100644 index 00000000..04fd3d10 Binary files /dev/null and b/img/testRuns/Blooper5.png differ diff --git a/img/testRuns/Blooper6.png b/img/testRuns/Blooper6.png new file mode 100644 index 00000000..2f758d6d Binary files /dev/null and b/img/testRuns/Blooper6.png differ diff --git a/img/testRuns/Cornell_Box.png b/img/testRuns/Cornell_Box.png new file mode 100644 index 00000000..3902b3c5 Binary files /dev/null and b/img/testRuns/Cornell_Box.png differ diff --git a/img/testRuns/Diffuse_Reflection_Refraction.png b/img/testRuns/Diffuse_Reflection_Refraction.png new file mode 100644 index 00000000..4a4e9cf3 Binary files /dev/null and b/img/testRuns/Diffuse_Reflection_Refraction.png differ diff --git a/img/testRuns/DirectLightingDisabled.png b/img/testRuns/DirectLightingDisabled.png new file mode 100644 index 00000000..d318bb56 Binary files /dev/null and b/img/testRuns/DirectLightingDisabled.png differ diff --git a/img/testRuns/DirectLightingEnabled.png b/img/testRuns/DirectLightingEnabled.png new file mode 100644 index 00000000..65a98c2d Binary files /dev/null and b/img/testRuns/DirectLightingEnabled.png differ diff --git a/img/testRuns/Direct_Lighting.png b/img/testRuns/Direct_Lighting.png new file mode 100644 index 00000000..e5d6dbf3 Binary files /dev/null and b/img/testRuns/Direct_Lighting.png differ diff --git a/img/testRuns/MaterialSortTable.png b/img/testRuns/MaterialSortTable.png new file mode 100644 index 00000000..4e22c173 Binary files /dev/null and b/img/testRuns/MaterialSortTable.png differ diff --git a/img/testRuns/Presentation1.png b/img/testRuns/Presentation1.png new file mode 100644 index 00000000..d8acd108 Binary files /dev/null and b/img/testRuns/Presentation1.png differ diff --git a/img/testRuns/Presentation2.png b/img/testRuns/Presentation2.png new file mode 100644 index 00000000..bbcdcd29 Binary files /dev/null and b/img/testRuns/Presentation2.png differ diff --git a/img/testRuns/Presentation3.png b/img/testRuns/Presentation3.png new file mode 100644 index 00000000..b2b8d8e3 Binary files /dev/null and b/img/testRuns/Presentation3.png differ diff --git a/img/testRuns/RenderWithMaterialSort.png b/img/testRuns/RenderWithMaterialSort.png new file mode 100644 index 00000000..be053edf Binary files /dev/null and b/img/testRuns/RenderWithMaterialSort.png differ diff --git a/img/testRuns/RenderWithoutMaterialSort.png b/img/testRuns/RenderWithoutMaterialSort.png new file mode 100644 index 00000000..ed4ebac8 Binary files /dev/null and b/img/testRuns/RenderWithoutMaterialSort.png differ diff --git a/img/testRuns/RussianRouletteDisabled.png b/img/testRuns/RussianRouletteDisabled.png new file mode 100644 index 00000000..8723a311 Binary files /dev/null and b/img/testRuns/RussianRouletteDisabled.png differ diff --git a/img/testRuns/RussianRouletteEnabled.png b/img/testRuns/RussianRouletteEnabled.png new file mode 100644 index 00000000..5db8cdaf Binary files /dev/null and b/img/testRuns/RussianRouletteEnabled.png differ diff --git a/img/testRuns/Specular_Scene.png b/img/testRuns/Specular_Scene.png new file mode 100644 index 00000000..68166af2 Binary files /dev/null and b/img/testRuns/Specular_Scene.png differ diff --git a/img/testRuns/SurfaceIneraction.png b/img/testRuns/SurfaceIneraction.png new file mode 100644 index 00000000..4a4e9cf3 Binary files /dev/null and b/img/testRuns/SurfaceIneraction.png differ diff --git a/img/testRuns/WithoutAntiAliasing.png b/img/testRuns/WithoutAntiAliasing.png new file mode 100644 index 00000000..58ce596c Binary files /dev/null and b/img/testRuns/WithoutAntiAliasing.png differ diff --git a/img/testRuns/colorful_room.2024-10-08_02-00-43z.5000samp.png b/img/testRuns/colorful_room.2024-10-08_02-00-43z.5000samp.png new file mode 100644 index 00000000..de0d86e9 Binary files /dev/null and b/img/testRuns/colorful_room.2024-10-08_02-00-43z.5000samp.png differ diff --git a/img/testRuns/colorful_room.2024-10-08_02-06-43z.5000samp.png b/img/testRuns/colorful_room.2024-10-08_02-06-43z.5000samp.png new file mode 100644 index 00000000..b46bd78d Binary files /dev/null and b/img/testRuns/colorful_room.2024-10-08_02-06-43z.5000samp.png differ diff --git a/img/testRuns/colorful_room.2024-10-08_02-07-36z.5000samp.png b/img/testRuns/colorful_room.2024-10-08_02-07-36z.5000samp.png new file mode 100644 index 00000000..7e353afc Binary files /dev/null and b/img/testRuns/colorful_room.2024-10-08_02-07-36z.5000samp.png differ diff --git a/img/testRuns/colorful_spheres.2024-10-08_01-50-59z.5000samp.png b/img/testRuns/colorful_spheres.2024-10-08_01-50-59z.5000samp.png new file mode 100644 index 00000000..2698a695 Binary files /dev/null and b/img/testRuns/colorful_spheres.2024-10-08_01-50-59z.5000samp.png differ diff --git a/img/testRuns/colorful_spheres.2024-10-08_01-52-16z.5000samp.png b/img/testRuns/colorful_spheres.2024-10-08_01-52-16z.5000samp.png new file mode 100644 index 00000000..2bee8204 Binary files /dev/null and b/img/testRuns/colorful_spheres.2024-10-08_01-52-16z.5000samp.png differ diff --git a/img/testRuns/colorful_spheres_light_floor.2024-10-08_01-57-19z.5000samp.png b/img/testRuns/colorful_spheres_light_floor.2024-10-08_01-57-19z.5000samp.png new file mode 100644 index 00000000..592b8f51 Binary files /dev/null and b/img/testRuns/colorful_spheres_light_floor.2024-10-08_01-57-19z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-25_23-49-00z.5000samp.png b/img/testRuns/cornell.2024-09-25_23-49-00z.5000samp.png new file mode 100644 index 00000000..83bc9e21 Binary files /dev/null and b/img/testRuns/cornell.2024-09-25_23-49-00z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_00-02-21z.5000samp.png b/img/testRuns/cornell.2024-09-26_00-02-21z.5000samp.png new file mode 100644 index 00000000..dcc33aba Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_00-02-21z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_01-13-57z.5000samp.png b/img/testRuns/cornell.2024-09-26_01-13-57z.5000samp.png new file mode 100644 index 00000000..5eea47a9 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_01-13-57z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_01-32-18z.5000samp.png b/img/testRuns/cornell.2024-09-26_01-32-18z.5000samp.png new file mode 100644 index 00000000..755f270c Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_01-32-18z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_02-41-54z.240samp.png b/img/testRuns/cornell.2024-09-26_02-41-54z.240samp.png new file mode 100644 index 00000000..224a3934 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_02-41-54z.240samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_02-43-39z.76samp.png b/img/testRuns/cornell.2024-09-26_02-43-39z.76samp.png new file mode 100644 index 00000000..63fcb93b Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_02-43-39z.76samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_02-51-39z.348samp.png b/img/testRuns/cornell.2024-09-26_02-51-39z.348samp.png new file mode 100644 index 00000000..e15a72d9 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_02-51-39z.348samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_02-51-39z.5000samp.png b/img/testRuns/cornell.2024-09-26_02-51-39z.5000samp.png new file mode 100644 index 00000000..eba6a835 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_02-51-39z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_02-51-39z.50samp.png b/img/testRuns/cornell.2024-09-26_02-51-39z.50samp.png new file mode 100644 index 00000000..dbda5ea5 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_02-51-39z.50samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_03-06-13z.5000samp.png b/img/testRuns/cornell.2024-09-26_03-06-13z.5000samp.png new file mode 100644 index 00000000..446e5076 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_03-06-13z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-26_23-53-02z.5000samp.png b/img/testRuns/cornell.2024-09-26_23-53-02z.5000samp.png new file mode 100644 index 00000000..80f5e200 Binary files /dev/null and b/img/testRuns/cornell.2024-09-26_23-53-02z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-27_00-02-44z.5000samp.png b/img/testRuns/cornell.2024-09-27_00-02-44z.5000samp.png new file mode 100644 index 00000000..abe986d0 Binary files /dev/null and b/img/testRuns/cornell.2024-09-27_00-02-44z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-27_16-31-51z.5000samp.png b/img/testRuns/cornell.2024-09-27_16-31-51z.5000samp.png new file mode 100644 index 00000000..130d2001 Binary files /dev/null and b/img/testRuns/cornell.2024-09-27_16-31-51z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-28_17-06-32z.171samp.png b/img/testRuns/cornell.2024-09-28_17-06-32z.171samp.png new file mode 100644 index 00000000..daeb4c28 Binary files /dev/null and b/img/testRuns/cornell.2024-09-28_17-06-32z.171samp.png differ diff --git a/img/testRuns/cornell.2024-09-28_19-30-02z.126samp.png b/img/testRuns/cornell.2024-09-28_19-30-02z.126samp.png new file mode 100644 index 00000000..341d9bee Binary files /dev/null and b/img/testRuns/cornell.2024-09-28_19-30-02z.126samp.png differ diff --git a/img/testRuns/cornell.2024-09-28_19-44-59z.5000samp.png b/img/testRuns/cornell.2024-09-28_19-44-59z.5000samp.png new file mode 100644 index 00000000..35e9ce84 Binary files /dev/null and b/img/testRuns/cornell.2024-09-28_19-44-59z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-29_01-14-48z.5000samp.png b/img/testRuns/cornell.2024-09-29_01-14-48z.5000samp.png new file mode 100644 index 00000000..09436578 Binary files /dev/null and b/img/testRuns/cornell.2024-09-29_01-14-48z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-09-29_05-06-24z.274samp.png b/img/testRuns/cornell.2024-09-29_05-06-24z.274samp.png new file mode 100644 index 00000000..034ea9ac Binary files /dev/null and b/img/testRuns/cornell.2024-09-29_05-06-24z.274samp.png differ diff --git a/img/testRuns/cornell.2024-09-30_02-02-05z.5000samp.png b/img/testRuns/cornell.2024-09-30_02-02-05z.5000samp.png new file mode 100644 index 00000000..c5285f70 Binary files /dev/null and b/img/testRuns/cornell.2024-09-30_02-02-05z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-04_01-55-17z.5000samp.png b/img/testRuns/cornell.2024-10-04_01-55-17z.5000samp.png new file mode 100644 index 00000000..f5b6cdcb Binary files /dev/null and b/img/testRuns/cornell.2024-10-04_01-55-17z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-04_04-30-15z.1279samp.png b/img/testRuns/cornell.2024-10-04_04-30-15z.1279samp.png new file mode 100644 index 00000000..46c4c35c Binary files /dev/null and b/img/testRuns/cornell.2024-10-04_04-30-15z.1279samp.png differ diff --git a/img/testRuns/cornell.2024-10-04_19-57-36z.2405samp.png b/img/testRuns/cornell.2024-10-04_19-57-36z.2405samp.png new file mode 100644 index 00000000..bba94352 Binary files /dev/null and b/img/testRuns/cornell.2024-10-04_19-57-36z.2405samp.png differ diff --git a/img/testRuns/cornell.2024-10-04_20-16-53z.640samp.png b/img/testRuns/cornell.2024-10-04_20-16-53z.640samp.png new file mode 100644 index 00000000..368ae30f Binary files /dev/null and b/img/testRuns/cornell.2024-10-04_20-16-53z.640samp.png differ diff --git a/img/testRuns/cornell.2024-10-04_20-33-30z.387samp.png b/img/testRuns/cornell.2024-10-04_20-33-30z.387samp.png new file mode 100644 index 00000000..d46b1cad Binary files /dev/null and b/img/testRuns/cornell.2024-10-04_20-33-30z.387samp.png differ diff --git a/img/testRuns/cornell.2024-10-05_02-18-42z.1616samp.png b/img/testRuns/cornell.2024-10-05_02-18-42z.1616samp.png new file mode 100644 index 00000000..01916ef3 Binary files /dev/null and b/img/testRuns/cornell.2024-10-05_02-18-42z.1616samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_01-24-12z.5000samp.png b/img/testRuns/cornell.2024-10-08_01-24-12z.5000samp.png new file mode 100644 index 00000000..3040de7e Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_01-24-12z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_01-26-30z.5000samp.png b/img/testRuns/cornell.2024-10-08_01-26-30z.5000samp.png new file mode 100644 index 00000000..5ac54ddc Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_01-26-30z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_01-32-50z.5000samp.png b/img/testRuns/cornell.2024-10-08_01-32-50z.5000samp.png new file mode 100644 index 00000000..1746e130 Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_01-32-50z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_02-39-51z.5000samp.png b/img/testRuns/cornell.2024-10-08_02-39-51z.5000samp.png new file mode 100644 index 00000000..b63e60e6 Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_02-39-51z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_02-45-14z.5000samp.png b/img/testRuns/cornell.2024-10-08_02-45-14z.5000samp.png new file mode 100644 index 00000000..b63e60e6 Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_02-45-14z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_03-19-18z.5000samp.png b/img/testRuns/cornell.2024-10-08_03-19-18z.5000samp.png new file mode 100644 index 00000000..45a35f98 Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_03-19-18z.5000samp.png differ diff --git a/img/testRuns/cornell.2024-10-08_03-25-19z.5000samp.png b/img/testRuns/cornell.2024-10-08_03-25-19z.5000samp.png new file mode 100644 index 00000000..8b588a92 Binary files /dev/null and b/img/testRuns/cornell.2024-10-08_03-25-19z.5000samp.png differ diff --git a/img/testRuns/depth_of_field.png b/img/testRuns/depth_of_field.png new file mode 100644 index 00000000..08ad5d3d Binary files /dev/null and b/img/testRuns/depth_of_field.png differ diff --git a/img/testRuns/depth_of_field1.png b/img/testRuns/depth_of_field1.png new file mode 100644 index 00000000..c70dd385 Binary files /dev/null and b/img/testRuns/depth_of_field1.png differ diff --git a/img/testRuns/depth_of_field_disabled.png b/img/testRuns/depth_of_field_disabled.png new file mode 100644 index 00000000..9c3930a9 Binary files /dev/null and b/img/testRuns/depth_of_field_disabled.png differ diff --git a/img/testRuns/depth_of_field_disabled1.png b/img/testRuns/depth_of_field_disabled1.png new file mode 100644 index 00000000..a4f74ba3 Binary files /dev/null and b/img/testRuns/depth_of_field_disabled1.png differ diff --git a/img/testRuns/materials.png b/img/testRuns/materials.png new file mode 100644 index 00000000..548c3745 Binary files /dev/null and b/img/testRuns/materials.png differ diff --git a/img/testRuns/materials_showcase.2024-10-04_20-42-37z.90samp.png b/img/testRuns/materials_showcase.2024-10-04_20-42-37z.90samp.png new file mode 100644 index 00000000..f337fedd Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-04_20-42-37z.90samp.png differ diff --git a/img/testRuns/materials_showcase.2024-10-04_20-43-54z.8samp.png b/img/testRuns/materials_showcase.2024-10-04_20-43-54z.8samp.png new file mode 100644 index 00000000..45c2f259 Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-04_20-43-54z.8samp.png differ diff --git a/img/testRuns/materials_showcase.2024-10-04_20-53-21z.386samp.png b/img/testRuns/materials_showcase.2024-10-04_20-53-21z.386samp.png new file mode 100644 index 00000000..d3132da0 Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-04_20-53-21z.386samp.png differ diff --git a/img/testRuns/materials_showcase.2024-10-04_20-53-21z.5000samp.png b/img/testRuns/materials_showcase.2024-10-04_20-53-21z.5000samp.png new file mode 100644 index 00000000..87460ab7 Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-04_20-53-21z.5000samp.png differ diff --git a/img/testRuns/materials_showcase.2024-10-04_20-58-22z.5000samp.png b/img/testRuns/materials_showcase.2024-10-04_20-58-22z.5000samp.png new file mode 100644 index 00000000..de61f330 Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-04_20-58-22z.5000samp.png differ diff --git a/img/testRuns/materials_showcase.2024-10-08_01-44-12z.5000samp.png b/img/testRuns/materials_showcase.2024-10-08_01-44-12z.5000samp.png new file mode 100644 index 00000000..b2d2ae90 Binary files /dev/null and b/img/testRuns/materials_showcase.2024-10-08_01-44-12z.5000samp.png differ diff --git a/img/testRuns/surface.2024-10-04_04-36-42z.111samp.png b/img/testRuns/surface.2024-10-04_04-36-42z.111samp.png new file mode 100644 index 00000000..56645a3c Binary files /dev/null and b/img/testRuns/surface.2024-10-04_04-36-42z.111samp.png differ diff --git a/img/testRuns/surface.2024-10-04_04-36-42z.446samp.png b/img/testRuns/surface.2024-10-04_04-36-42z.446samp.png new file mode 100644 index 00000000..f79a5924 Binary files /dev/null and b/img/testRuns/surface.2024-10-04_04-36-42z.446samp.png differ diff --git a/scenes/cornell.json b/scenes/cornell.json index e7419885..6fbe545b 100644 --- a/scenes/cornell.json +++ b/scenes/cornell.json @@ -22,6 +22,11 @@ "TYPE":"Diffuse", "RGB":[0.35, 0.85, 0.35] }, + "diffuse_test": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.35, 0.35] + }, "specular_white": { "TYPE":"Specular", @@ -86,7 +91,7 @@ }, { "TYPE":"sphere", - "MATERIAL":"specular_white", + "MATERIAL":"diffuse_test", "TRANS":[-1.0,4.0,-1.0], "ROTAT":[0.0,0.0,0.0], "SCALE":[3.0,3.0,3.0] diff --git a/scenes/depth_of_field.json b/scenes/depth_of_field.json new file mode 100644 index 00000000..42eafa81 --- /dev/null +++ b/scenes/depth_of_field.json @@ -0,0 +1,106 @@ +{ + "Materials": { + "light": { + "TYPE": "Emitting", + "RGB": [1.0, 1.0, 1.0], + "EMITTANCE": 5.0 + }, + "diffuse_white": { + "TYPE": "Diffuse", + "RGB": [0.98, 0.98, 0.98] + }, + "diffuse_red": { + "TYPE": "Diffuse", + "RGB": [0.85, 0.35, 0.35] + }, + "diffuse_green": { + "TYPE": "Diffuse", + "RGB": [0.35, 0.85, 0.35] + }, + "diffuse_blue": { + "TYPE": "Diffuse", + "RGB": [0.35, 0.35, 0.85] + }, + "specular_white": + { + "TYPE":"Specular", + "RGB":[0.98, 0.98, 0.98], + "ROUGHNESS":0.0 + } + }, + "Camera": { + "RES": [800, 800], + "FOVY": 45.0, + "ITERATIONS": 5000, + "DEPTH": 8, + "FILE": "depth_of_field", + "EYE": [0.0, 5.0, 10.5], + "LOOKAT": [0.0, 5.0, 0.0], + "UP": [0.0, 1.0, 0.0] + }, + "Objects": [ + { + "TYPE": "cube", + "MATERIAL": "light", + "TRANS": [0.0, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.0, 0.3, 3.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,0.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[10.0,0.01,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,90.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,5.0,-5.0], + "ROTAT":[0.0,90.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_red", + "TRANS":[-5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_green", + "TRANS":[5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "diffuse_red", + "TRANS": [-4.0, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "specular_white", + "TRANS": [0.0, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "diffuse_blue", + "TRANS": [4.0, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + } + ] +} diff --git a/scenes/dof_test_scene.json b/scenes/dof_test_scene.json new file mode 100644 index 00000000..fcc4e766 --- /dev/null +++ b/scenes/dof_test_scene.json @@ -0,0 +1,151 @@ +{ + "Materials": + { + "light": + { + "TYPE":"Emitting", + "RGB":[1.0, 1.0, 1.0], + "EMITTANCE":15.0 + }, + "diffuse_white": + { + "TYPE":"Diffuse", + "RGB":[0.98, 0.98, 0.98] + }, + "diffuse_red": + { + "TYPE":"Diffuse", + "RGB":[0.85, 0.35, 0.35] + }, + "diffuse_green": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.85, 0.35] + }, + "diffuse_blue": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.35, 0.85] + }, + "diffuse_gray": + { + "TYPE":"Diffuse", + "RGB":[0.15, 0.15, 0.15] + }, + "diffuse_test": + { + "TYPE":"Diffuse", + "RGB":[0.90, 0.68, 0.05] + }, + "specular_white": + { + "TYPE":"Specular", + "RGB":[0.98, 0.98, 0.98], + "ROUGHNESS":0.0 + }, + "glass": { + "TYPE": "Dielectric", + "RGB": [0.9, 0.9, 1.0], + "IOR": 1.5, + "ROUGHNESS": 0.01 + } + }, + "Camera": + { + "RES":[800,800], + "FOVY":45.0, + "ITERATIONS":5000, + "DEPTH":8, + "FILE":"cornell", + "EYE":[0.0,5.0,10.5], + "LOOKAT":[0.0,5.0,0.0], + "UP":[0.0,1.0,0.0] + }, + "Objects": + [ + { + "TYPE":"cube", + "MATERIAL":"light", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[3.0,0.3,3.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,0.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[10.0,0.01,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_blue", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,90.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,5.0,-5.0], + "ROTAT":[0.0,90.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_red", + "TRANS":[-5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_green", + "TRANS":[5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"diffuse_test", + "TRANS":[1.0,5.0,-2.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"specular_white", + "TRANS":[-2.0,2.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"glass", + "TRANS":[2.0,2.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"diffuse_test", + "TRANS":[0.0,2.0,7.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"specular_white", + "TRANS":[-4.0,2.0,3.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"glass", + "TRANS":[1.0,1.0,-1.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[2.0,2.0,2.0] + } + ] +} \ No newline at end of file diff --git a/scenes/mario.json b/scenes/mario.json new file mode 100644 index 00000000..010d3e80 --- /dev/null +++ b/scenes/mario.json @@ -0,0 +1,64 @@ +{ + "Materials": { + "white_light": { + "TYPE": "Emitting", + "RGB": [1.0, 1.0, 1.0], + "EMITTANCE": 10.0 + }, + "diffuse_white": { + "TYPE": "Diffuse", + "RGB": [0.98, 0.98, 0.98] + }, + "metallic_gold": { + "TYPE": "Metallic", + "RGB": [1.0, 0.86, 0.57], + "METALLIC": 1.0, + "ROUGHNESS": 0.1 + }, + "mesh_material": { + "TYPE": "Diffuse", + "RGB": [0.7, 0.3, 0.3] + } + }, + "Camera": { + "RES": [800, 600], + "FOVY": 45.0, + "ITERATIONS": 5000, + "DEPTH": 8, + "FILE": "mesh_scene", + "EYE": [0.0, 5.0, 15.0], + "LOOKAT": [0.0, 0.0, 0.0], + "UP": [0.0, 1.0, 0.0] + }, + "Objects": [ + { + "TYPE": "cube", + "MATERIAL": "white_light", + "TRANS": [0.0, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [5.0, 0.5, 5.0] + }, + { + "TYPE": "cube", + "MATERIAL": "diffuse_white", + "TRANS": [0.0, -1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [20.0, 1.0, 20.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-3.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "mesh", + "MATERIAL": "mesh_material", + "FILE": "../scenes/cube.obj", + "TRANS": [3.0, 0.0, 0.0], + "ROTAT": [0.0, 45.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + } + ] +} diff --git a/scenes/materials.json b/scenes/materials.json new file mode 100644 index 00000000..a176ae42 --- /dev/null +++ b/scenes/materials.json @@ -0,0 +1,142 @@ +{ + "Materials": { + "white_light": { + "TYPE": "Emitting", + "RGB": [1.0, 1.0, 1.0], + "EMITTANCE": 50.0 + }, + "red_light": { + "TYPE": "Emitting", + "RGB": [1.0, 0.2, 0.2], + "EMITTANCE": 50.0 + }, + "blue_light": { + "TYPE": "Emitting", + "RGB": [0.2, 0.2, 1.0], + "EMITTANCE": 50.0 + }, + "floor": { + "TYPE": "Diffuse", + "RGB": [0.9, 0.9, 0.9] + }, + "metallic_gold": { + "TYPE": "Metallic", + "RGB": [1.0, 0.86, 0.57], + "METALLIC": 1.0, + "ROUGHNESS": 0.1 + }, + "brushed_aluminum": { + "TYPE": "Metallic", + "RGB": [0.91, 0.92, 0.92], + "METALLIC": 0.8, + "ROUGHNESS": 0.4 + }, + "shiny_plastic_teal": { + "TYPE": "Plastic", + "RGB": [0.0, 0.5, 0.5], + "ROUGHNESS": 0.05, + "SPECULAR": 0.8, + "IOR": 1.5 + }, + "matte_plastic_purple": { + "TYPE": "Plastic", + "RGB": [0.5, 0.0, 0.5], + "ROUGHNESS": 0.8, + "SPECULAR": 0.1, + "IOR": 1.45 + }, + "glass": { + "TYPE": "Dielectric", + "RGB": [0.95, 0.95, 1.0], + "IOR": 1.52, + "ROUGHNESS": 0.01 + }, + "mirror": { + "TYPE": "Specular", + "RGB": [0.99, 0.99, 0.99], + "ROUGHNESS": 0.001 + } + }, + "Camera": { + "RES": [800,800], + "FOVY": 50.0, + "ITERATIONS": 5000, + "DEPTH": 8, + "FILE": "materials_showcase", + "EYE": [0.0, 10.0, 5.0], + "LOOKAT": [0.0, 3.0, 0.0], + "UP": [0.0, 1.0, 0.0] + }, + "Objects": [ + { + "TYPE": "cube", + "MATERIAL": "floor", + "TRANS": [0.0, -0.5, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [20.0, 1.0, 20.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "white_light", + "TRANS": [0.0, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "red_light", + "TRANS": [-5.0, 5.0, -5.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "blue_light", + "TRANS": [5.0, 5.0, -5.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-4.0, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + }, + { + "TYPE": "cube", + "MATERIAL": "brushed_aluminum", + "TRANS": [0.0, 2.0, 0.0], + "ROTAT": [0.0, 45.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_plastic_teal", + "TRANS": [4.0, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + }, + { + "TYPE": "cube", + "MATERIAL": "matte_plastic_purple", + "TRANS": [-2.0, 1.0, 3.0], + "ROTAT": [0.0, 30.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [2.0, 2.0, 3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + }, + { + "TYPE": "cube", + "MATERIAL": "mirror", + "TRANS": [0.0, 2.0, -4.0], + "ROTAT": [0.0, -15.0, 0.0], + "SCALE": [4.0, 4.0, 0.1] + } + ] +} diff --git a/scenes/microfacet_scene.json b/scenes/microfacet_scene.json new file mode 100644 index 00000000..539bcab1 --- /dev/null +++ b/scenes/microfacet_scene.json @@ -0,0 +1,173 @@ +{ + "Materials": + { + "light_white": + { + "TYPE":"Emitting", + "RGB":[1.0, 1.0, 1.0], + "EMITTANCE":15.0 + }, + "light_blue": + { + "TYPE":"Emitting", + "RGB":[0.10, 0.10, 0.85], + "EMITTANCE":15.0 + }, + "light_yellow": + { + "TYPE":"Emitting", + "RGB":[0.85, 0.85, 0.10], + "EMITTANCE":25.0 + }, + "diffuse_white": + { + "TYPE":"Diffuse", + "RGB":[0.98, 0.98, 0.98] + }, + "diffuse_red": + { + "TYPE":"Diffuse", + "RGB":[0.85, 0.35, 0.35] + }, + "diffuse_green": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.85, 0.35] + }, + "diffuse_test": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.35, 0.35] + }, + "specular_white": + { + "TYPE":"Specular", + "RGB":[0.98, 0.98, 0.98], + "ROUGHNESS":0.0 + }, + "metallic_gold": { + "TYPE": "Metallic", + "RGB": [1.0, 0.86, 0.57], + "METALLIC": 1.0, + "ROUGHNESS": 0.1 + }, + "brushed_aluminum": { + "TYPE": "Metallic", + "RGB": [0.91, 0.92, 0.92], + "METALLIC": 0.8, + "ROUGHNESS": 0.4 + }, + "glossy_plastic_teal": { + "TYPE": "Plastic", + "RGB": [0.0, 0.5, 0.5], + "ROUGHNESS": 0.02, + "SPECULAR": 0.9, + "IOR": 1.5 + }, + "matte_plastic_blue": { + "TYPE": "Plastic", + "RGB": [0.2, 0.2, 0.8], + "ROUGHNESS": 0.8, + "SPECULAR": 0.1, + "IOR": 1.45 + } + }, + "Camera": + { + "RES":[800,800], + "FOVY":45.0, + "ITERATIONS":5000, + "DEPTH":8, + "FILE":"cornell", + "EYE":[0.0,5.0,10.5], + "LOOKAT":[0.0,5.0,0.0], + "UP":[0.0,1.0,0.0] + }, + "Objects": + [ + { + "TYPE":"cube", + "MATERIAL":"light_blue", + "TRANS":[0.0,10.0,3.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.7,0.3,3.0] + }, + { + "TYPE":"cube", + "MATERIAL":"light_white", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.7,0.3,3.0] + }, + { + "TYPE":"cube", + "MATERIAL":"light_blue", + "TRANS":[0.0,10.0,-3.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.7,0.3,3.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,0.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[10.0,0.01,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,90.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,5.0,-5.0], + "ROTAT":[0.0,90.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_red", + "TRANS":[-5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_green", + "TRANS":[5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-2.5, 2.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.0, 3.0, 3.0] + }, + { + "TYPE": "cube", + "MATERIAL": "brushed_aluminum", + "TRANS": [2.5, 2.0, 0.0], + "ROTAT": [0.0, 45.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "glossy_plastic_teal", + "TRANS": [-2.5, 6.0, 1.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.0, 3.0, 3.0] + }, + { + "TYPE": "cube", + "MATERIAL": "matte_plastic_blue", + "TRANS": [2.5, 6.0, 1.0], + "ROTAT": [0.0, 45.0, 0.0], + "SCALE": [2.0, 2.0, 2.0] + } + ] +} \ No newline at end of file diff --git a/scenes/refraction.json b/scenes/refraction.json new file mode 100644 index 00000000..d59971ac --- /dev/null +++ b/scenes/refraction.json @@ -0,0 +1,482 @@ +{ + "Materials": { + "light_red": { + "TYPE": "Emitting", + "RGB": [1.0, 0.2, 0.2], + "EMITTANCE": 5.0 + }, + "light_green": { + "TYPE": "Emitting", + "RGB": [0.2, 1.0, 0.2], + "EMITTANCE": 5.0 + }, + "light_blue": { + "TYPE": "Emitting", + "RGB": [0.2, 0.2, 1.0], + "EMITTANCE": 5.0 + }, + "light_yellow": { + "TYPE": "Emitting", + "RGB": [1.0, 1.0, 0.2], + "EMITTANCE": 5.0 + }, + "light_cyan": { + "TYPE": "Emitting", + "RGB": [0.2, 1.0, 1.0], + "EMITTANCE": 5.0 + }, + "light_magenta": { + "TYPE": "Emitting", + "RGB": [1.0, 0.2, 1.0], + "EMITTANCE": 5.0 + }, + "wall": { + "TYPE": "Glass", + "RGB": [0.9, 0.9, 0.9] + }, + "metallic_gold": { + "TYPE": "Metallic", + "RGB": [1.0, 0.86, 0.57], + "METALLIC": 1.0, + "ROUGHNESS": 0.1 + }, + "shiny_Specular_teal": { + "TYPE": "Specular", + "RGB": [0.0, 0.7, 0.7], + "ROUGHNESS": 0.05, + "SPECULAR": 0.8, + "IOR": 1.5 + }, + "matte_Specular_purple": { + "TYPE": "Specular", + "RGB": [0.7, 0.0, 0.7], + "ROUGHNESS": 0.8, + "SPECULAR": 0.1, + "IOR": 1.45 + }, + "glass": { + "TYPE": "Dielectric", + "RGB": [0.95, 0.95, 1.0], + "IOR": 1.52, + "ROUGHNESS": 0.01 + }, + "mirror": { + "TYPE": "Specular", + "RGB": [0.99, 0.99, 0.99], + "ROUGHNESS": 0.001 + }, + "Glass_white": { + "TYPE": "Glass", + "RGB": [0.9, 0.9, 0.9] + }, + "Glass_red": { + "TYPE": "Glass", + "RGB": [0.9, 0.1, 0.1] + }, + "Glass_green": { + "TYPE": "Glass", + "RGB": [0.1, 0.9, 0.1] + }, + "Glass_blue": { + "TYPE": "Glass", + "RGB": [0.1, 0.1, 0.9] + } + }, + "Camera": { + "RES": [800, 800], + "FOVY": 50.0, + "ITERATIONS": 5000, + "DEPTH": 8, + "FILE": "colorful_room", + "EYE": [0.0, 5.0, 10.0], + "LOOKAT": [0.0, 5.0, 0.0], + "UP": [0.0, 1.0, 0.0] + }, + "Objects": [ + { + "TYPE": "cube", + "MATERIAL": "light_red", + "TRANS": [-3.33, 0.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_green", + "TRANS": [0.0, 0.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_blue", + "TRANS": [3.33, 0.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_yellow", + "TRANS": [-3.33, 0.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_cyan", + "TRANS": [0.0, 0.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_magenta", + "TRANS": [3.33, 0.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_red", + "TRANS": [-3.33, 0.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_green", + "TRANS": [0.0, 0.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_blue", + "TRANS": [3.33, 0.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_red", + "TRANS": [-3.33, 10.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_green", + "TRANS": [0.0, 10.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_blue", + "TRANS": [3.33, 10.0, -3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_yellow", + "TRANS": [-3.33, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_cyan", + "TRANS": [0.0, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_magenta", + "TRANS": [3.33, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.33] + }, + { + "TYPE": "cube", + "MATERIAL": "light_red", + "TRANS": [-3.33, 10.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_green", + "TRANS": [0.0, 10.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.33, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "light_blue", + "TRANS": [3.33, 10.0, 3.33], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.34, 0.1, 3.34] + }, + { + "TYPE": "cube", + "MATERIAL": "wall", + "TRANS": [-5.0, 5.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.1, 10.0, 10.0] + }, + { + "TYPE": "cube", + "MATERIAL": "wall", + "TRANS": [5.0, 5.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.1, 10.0, 10.0] + }, + { + "TYPE": "cube", + "MATERIAL": "wall", + "TRANS": [0.0, 5.0, -5.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [10.0, 10.0, 0.1] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-4.0, 1.0, -4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_Specular_teal", + "TRANS": [0.0, 1.0, -4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "matte_Specular_purple", + "TRANS": [4.0, 1.0, -4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [-4.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "mirror", + "TRANS": [0.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_red", + "TRANS": [4.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_green", + "TRANS": [-4.0, 1.0, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_blue", + "TRANS": [0.0, 1.0, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_white", + "TRANS": [4.0, 1.0, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-2.0, 3.0, -2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [2.0, 3.0, -2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_Specular_teal", + "TRANS": [-2.0, 3.0, 2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "matte_Specular_purple", + "TRANS": [2.0, 3.0, 2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "mirror", + "TRANS": [0.0, 5.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_red", + "TRANS": [-3.0, 5.0, -3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_green", + "TRANS": [3.0, 5.0, -3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_blue", + "TRANS": [0.0, 5.0, 3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [0.5, 0.5, 0.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-1.0, 3.0, -3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.9, 1.9, 1.9] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_Specular_teal", + "TRANS": [2.0, 9.0, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.3, 1.3, 1.3] + }, + { + "TYPE": "sphere", + "MATERIAL": "matte_Specular_purple", + "TRANS": [4.0, 1.0, -4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [-4.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "mirror", + "TRANS": [0.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_red", + "TRANS": [4.0, 8.5, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_green", + "TRANS": [-4.0, 7.5, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_blue", + "TRANS": [0.0, 5.5, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_white", + "TRANS": [4.0, 6.0, 4.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-2.0, 9.0, -2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [-2.0, 7.0, -2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.75, 1.75, 1.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_Specular_teal", + "TRANS": [-4.0, 1.0, -2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [3.75, 3.75, 3.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "matte_Specular_purple", + "TRANS": [-2.0, 3.0, 2.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.75, 2.75, 2.75] + }, + { + "TYPE": "sphere", + "MATERIAL": "mirror", + "TRANS": [6.0, 3.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_red", + "TRANS": [-3.0, 2.0, -1.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [4.5, 4.5, 4.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_green", + "TRANS": [2.0, 5.0, -3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [2.5, 2.5, 2.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "Glass_blue", + "TRANS": [2.0, 5.0, 3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + } + ] +} diff --git a/scenes/test_scene1.json b/scenes/test_scene1.json new file mode 100644 index 00000000..35cd6273 --- /dev/null +++ b/scenes/test_scene1.json @@ -0,0 +1,116 @@ +{ + "Materials": + { + "light": + { + "TYPE":"Emitting", + "RGB":[1.0, 1.0, 1.0], + "EMITTANCE":1025.0 + }, + "diffuse_white": + { + "TYPE":"Diffuse", + "RGB":[0.98, 0.98, 0.98] + }, + "diffuse_red": + { + "TYPE":"Diffuse", + "RGB":[0.85, 0.35, 0.35] + }, + "diffuse_green": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.85, 0.35] + }, + "diffuse_blue": + { + "TYPE":"Diffuse", + "RGB":[0.35, 0.35, 0.85] + }, + "diffuse_gray": + { + "TYPE":"Diffuse", + "RGB":[0.15, 0.15, 0.15] + }, + "diffuse_test": + { + "TYPE":"Diffuse", + "RGB":[0.90, 0.68, 0.05] + }, + "specular_white": + { + "TYPE":"Specular", + "RGB":[0.98, 0.98, 0.98], + "ROUGHNESS":0.0 + }, + "glass": { + "TYPE": "Dielectric", + "RGB": [0.9, 0.9, 1.0], + "IOR": 1.5, + "ROUGHNESS": 0.01 + } + }, + "Camera": + { + "RES":[800,800], + "FOVY":45.0, + "ITERATIONS":5000, + "DEPTH":8, + "FILE":"cornell", + "EYE":[0.0,5.0,10.5], + "LOOKAT":[0.0,5.0,0.0], + "UP":[0.0,1.0,0.0] + }, + "Objects": + [ + { + "TYPE":"cube", + "MATERIAL":"light", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.1,0.1,0.1] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,0.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[10.0,0.01,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_blue", + "TRANS":[0.0,10.0,0.0], + "ROTAT":[0.0,0.0,90.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_white", + "TRANS":[0.0,5.0,-5.0], + "ROTAT":[0.0,90.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_red", + "TRANS":[-5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"cube", + "MATERIAL":"diffuse_green", + "TRANS":[5.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[0.01,10.0,10.0] + }, + { + "TYPE":"sphere", + "MATERIAL":"diffuse_test", + "TRANS":[0.0,5.0,0.0], + "ROTAT":[0.0,0.0,0.0], + "SCALE":[3.0,3.0,3.0] + } + ] +} \ No newline at end of file diff --git a/scenes/texture_test.json b/scenes/texture_test.json new file mode 100644 index 00000000..9bc864fa --- /dev/null +++ b/scenes/texture_test.json @@ -0,0 +1,154 @@ +{ + "TEXTURES": { + "checkerboard": { + "PROCEDURAL": "CHECKERBOARD", + "WIDTH": 512, + "HEIGHT": 512, + "SQUARES": 8, + "COLOR1": [1.0, 1.0, 1.0], + "COLOR2": [0.2, 0.2, 0.2] + }, + "wood": { + "FILENAME": "../scenes/textures/wood.png" + } + }, + "Materials": { + "white_light": { + "TYPE": "Emitting", + "RGB": [1.0, 1.0, 1.0], + "EMITTANCE": 5.0 + }, + "red_light": { + "TYPE": "Emitting", + "RGB": [1.0, 0.2, 0.2], + "EMITTANCE": 3.0 + }, + "blue_light": { + "TYPE": "Emitting", + "RGB": [0.2, 0.2, 1.0], + "EMITTANCE": 3.0 + }, + "floor": { + "TYPE": "Diffuse", + "RGB": [0.9, 0.9, 0.9], + "TEXTURE": "checkerboard" + }, + "metallic_gold": { + "TYPE": "Metallic", + "RGB": [1.0, 0.86, 0.57], + "METALLIC": 1.0, + "ROUGHNESS": 0.1 + }, + "brushed_aluminum": { + "TYPE": "Metallic", + "RGB": [0.91, 0.92, 0.92], + "METALLIC": 0.8, + "ROUGHNESS": 0.4 + }, + "shiny_plastic_teal": { + "TYPE": "Plastic", + "RGB": [0.0, 0.5, 0.5], + "ROUGHNESS": 0.05, + "SPECULAR": 0.8, + "IOR": 1.5 + }, + "matte_plastic_purple": { + "TYPE": "Plastic", + "RGB": [0.5, 0.0, 0.5], + "ROUGHNESS": 0.8, + "SPECULAR": 0.1, + "IOR": 1.45 + }, + "glass": { + "TYPE": "Dielectric", + "RGB": [0.95, 0.95, 1.0], + "IOR": 1.52, + "ROUGHNESS": 0.01 + }, + "mirror": { + "TYPE": "Specular", + "RGB": [0.99, 0.99, 0.99], + "ROUGHNESS": 0.001 + }, + "wood": { + "TYPE": "Diffuse", + "RGB": [1.0, 1.0, 1.0], + "TEXTURE": "wood" + } + }, + "Camera": { + "RES": [800, 600], + "FOVY": 45.0, + "ITERATIONS": 5000, + "DEPTH": 8, + "FILE": "texture_test_scene", + "EYE": [0.0, 5.0, 15.0], + "LOOKAT": [0.0, 3.0, 0.0], + "UP": [0.0, 1.0, 0.0] + }, + "Objects": [ + { + "TYPE": "cube", + "MATERIAL": "white_light", + "TRANS": [0.0, 10.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [5.0, 0.5, 5.0] + }, + { + "TYPE": "cube", + "MATERIAL": "floor", + "TRANS": [0.0, -1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [20.0, 1.0, 20.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "metallic_gold", + "TRANS": [-3.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "cube", + "MATERIAL": "brushed_aluminum", + "TRANS": [0.0, 2.0, 0.0], + "ROTAT": [0.0, 45.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + }, + { + "TYPE": "sphere", + "MATERIAL": "shiny_plastic_teal", + "TRANS": [3.0, 1.0, 0.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "cube", + "MATERIAL": "matte_plastic_purple", + "TRANS": [-2.0, 1.0, 3.0], + "ROTAT": [0.0, 30.0, 0.0], + "SCALE": [1.0, 1.0, 1.0] + }, + { + "TYPE": "sphere", + "MATERIAL": "glass", + "TRANS": [2.0, 2.0, 3.0], + "ROTAT": [0.0, 0.0, 0.0], + "SCALE": [1.5, 1.5, 1.5] + }, + { + "TYPE": "cube", + "MATERIAL": "mirror", + "TRANS": [0.0, 2.0, -4.0], + "ROTAT": [0.0, -15.0, 0.0], + "SCALE": [4.0, 4.0, 0.1] + }, + { + "TYPE": "cube", + "MATERIAL": "wood", + "TRANS": [4.0, 1.0, -2.0], + "ROTAT": [0.0, -30.0, 0.0], + "SCALE": [1.5, 2.0, 1.5] + } + ] +} diff --git a/scenes/textures/wood.png b/scenes/textures/wood.png new file mode 100644 index 00000000..368ae30f Binary files /dev/null and b/scenes/textures/wood.png differ diff --git a/src/interactions.cu b/src/interactions.cu index 1837e713..d4e22116 100644 --- a/src/interactions.cu +++ b/src/interactions.cu @@ -40,14 +40,191 @@ __host__ __device__ glm::vec3 calculateRandomDirectionInHemisphere( + sin(around) * over * perpendicularDirection2; } +__host__ __device__ glm::vec3 samplePointOnLight(const Geom& geom, thrust::default_random_engine& rng) +{ + thrust::uniform_real_distribution u01(0, 1); + + if (geom.type == SPHERE) + { + float theta = 2 * PI * u01(rng); + float phi = acos(2 * u01(rng) - 1); + float r = geom.scale.x; // Assuming uniform scale for sphere + + glm::vec3 localPoint( + r * sin(phi) * cos(theta), + r * sin(phi) * sin(theta), + r * cos(phi) + ); + + return geom.translation + glm::vec3(geom.transform * glm::vec4(localPoint, 1.0f)); + } + else if (geom.type == CUBE) + { + // Randomly choose one of the 6 faces + int face = int(u01(rng) * 6); + float u = u01(rng); + float v = u01(rng); + + glm::vec3 localPoint; + switch (face) + { + case 0: localPoint = glm::vec3(-0.5f, u - 0.5f, v - 0.5f); break; // Left + case 1: localPoint = glm::vec3(0.5f, u - 0.5f, v - 0.5f); break; // Right + case 2: localPoint = glm::vec3(u - 0.5f, -0.5f, v - 0.5f); break; // Bottom + case 3: localPoint = glm::vec3(u - 0.5f, 0.5f, v - 0.5f); break; // Top + case 4: localPoint = glm::vec3(u - 0.5f, v - 0.5f, -0.5f); break; // Back + case 5: localPoint = glm::vec3(u - 0.5f, v - 0.5f, 0.5f); break; // Front + } + + return geom.translation + glm::vec3(geom.transform * glm::vec4(localPoint, 1.0f)); + } + + // Default case (shouldn't happen) + return geom.translation; +} + + __host__ __device__ void scatterRay( - PathSegment & pathSegment, + PathSegment& pathSegment, glm::vec3 intersect, glm::vec3 normal, - const Material &m, - thrust::default_random_engine &rng) + const Material& m, + thrust::default_random_engine& rng, + Geom* geoms, + int geoms_size, + Material* materials) { - // TODO: implement this. - // A basic implementation of pure-diffuse shading will just call the - // calculateRandomDirectionInHemisphere defined above. + if (pathSegment.remainingBounces == 0) + return; + + normal = glm::normalize(normal); + glm::vec3 viewDir = -pathSegment.ray.direction; + + thrust::uniform_real_distribution u01(0, 1); + float rand = u01(rng); + + glm::vec3 newDirection; + glm::vec3 indirectLight(0.0f); + glm::vec3 directLight(0.0f); + + if (m.plasticSpecular > 0.0f) + { + float F0 = pow((m.indexOfRefraction - 1) / (m.indexOfRefraction + 1), 2); + float cosTheta = glm::max(glm::dot(normal, viewDir), 0.0f); + float fresnel = F0 + (1.0f - F0) * pow(1.0f - cosTheta, 5.0f); + + if (rand < fresnel) + { + // Specular reflection + newDirection = glm::reflect(-viewDir, normal); + + if (m.roughness > 0.0f) + { + glm::vec3 randomDir = calculateRandomDirectionInHemisphere(normal, rng); + newDirection = glm::normalize(glm::mix(newDirection, randomDir, m.roughness)); + } + + pathSegment.color *= m.specular.color; + } + else + { + // Diffuse reflection + newDirection = calculateRandomDirectionInHemisphere(normal, rng); + pathSegment.color *= m.color; + } + } + else if (m.hasReflective > 0.0f) + { + // Metallic reflection + newDirection = glm::reflect(-viewDir, normal); + + if (m.roughness > 0.0f) + { + glm::vec3 randomDir = calculateRandomDirectionInHemisphere(normal, rng); + newDirection = glm::normalize(glm::mix(newDirection, randomDir, m.roughness)); + } + + pathSegment.color *= glm::mix(m.specular.color, m.color * glm::dot(newDirection, normal), m.metallic); + } + else if (m.hasRefractive > 0.0f) + { + // Refractive surface + float n1 = 1.0f; // Assume air as the surrounding medium + float n2 = m.indexOfRefraction; + float eta = n1 / n2; + float cosThetaI = glm::dot(-pathSegment.ray.direction, normal); + float k = 1.0f - eta * eta * (1.0f - cosThetaI * cosThetaI); + + if (k >= 0.0f) + { + newDirection = eta * pathSegment.ray.direction + (eta * cosThetaI - sqrtf(k)) * normal; + pathSegment.color *= m.color; + } + else + { + newDirection = glm::reflect(pathSegment.ray.direction, normal); + pathSegment.color *= m.specular.color; + } + } + else + { + // Diffuse reflection + newDirection = calculateRandomDirectionInHemisphere(normal, rng); + pathSegment.color *= m.color; + } + + indirectLight = pathSegment.color; + +#if DIRECT_LIGHTING + // Compute direct lighting + for (int i = 0; i < geoms_size; ++i) + { + if (materials[geoms[i].materialid].emittance > 0.0f) + { + glm::vec3 lightPoint = samplePointOnLight(geoms[i], rng); + glm::vec3 lightDir = glm::normalize(lightPoint - intersect); + float lightDistance = glm::length(lightPoint - intersect); + + Ray shadowRay; + shadowRay.origin = intersect + normal * 0.001f; // Offset to avoid self-intersection + shadowRay.direction = lightDir; + bool occluded = false; + + for (int j = 0; j < geoms_size; ++j) + { + if (j != i) // Don't check intersection with the light itself + { + float t; + glm::vec3 tmpIntersect, tmpNormal; + bool tmpOutside; + if (geoms[j].type == CUBE) + t = boxIntersectionTest(geoms[j], shadowRay, tmpIntersect, tmpNormal, tmpOutside); + else if (geoms[j].type == SPHERE) + t = sphereIntersectionTest(geoms[j], shadowRay, tmpIntersect, tmpNormal, tmpOutside); + + if (t > 0 && t < lightDistance) + { + occluded = true; + break; + } + } + } + + if (!occluded) + { + float cosTheta = glm::max(glm::dot(normal, lightDir), 0.0f); + glm::vec3 lightColor = materials[geoms[i].materialid].color; + float lightIntensity = materials[geoms[i].materialid].emittance; + + glm::vec3 brdf = m.color / PI; + + directLight += (brdf * lightColor * lightIntensity * cosTheta) / (lightDistance * lightDistance); + } + } + } +#endif + pathSegment.color = indirectLight + directLight; + pathSegment.ray.origin = intersect + newDirection * 0.001f; + pathSegment.ray.direction = glm::normalize(newDirection); + pathSegment.remainingBounces--; } diff --git a/src/interactions.h b/src/interactions.h index bfe4cbbb..507f8b99 100644 --- a/src/interactions.h +++ b/src/interactions.h @@ -37,9 +37,14 @@ __host__ __device__ glm::vec3 calculateRandomDirectionInHemisphere( * * You may need to change the parameter list for your purposes! */ +#define DIRECT_LIGHTING 1 + __host__ __device__ void scatterRay( PathSegment& pathSegment, glm::vec3 intersect, glm::vec3 normal, const Material& m, - thrust::default_random_engine& rng); + thrust::default_random_engine& rng, + Geom* geoms, + int geoms_size, + Material* materials); diff --git a/src/main.cpp b/src/main.cpp index 31bdaab4..5ef36479 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,7 +104,7 @@ void saveImage() std::string filename = renderState->imageName; std::ostringstream ss; ss << filename << "." << startTimeString << "." << samples << "samp"; - filename = ss.str(); + filename = "../img/testRuns/" + ss.str(); // CHECKITOUT img.savePNG(filename); diff --git a/src/pathtrace.cu b/src/pathtrace.cu index 709c231b..1c70e45f 100644 --- a/src/pathtrace.cu +++ b/src/pathtrace.cu @@ -14,6 +14,7 @@ #include "utilities.h" #include "intersections.h" #include "interactions.h" +#include #define ERRORCHECK 1 @@ -88,6 +89,17 @@ void InitDataContainer(GuiDataContainer* imGuiData) guiData = imGuiData; } +#if MATERIAL_SORT +struct SortMaterialById +{ + __host__ __device__ + bool operator()(const ShadeableIntersection& intersections1, const ShadeableIntersection& intersections2) + { + return intersections1.materialId < intersections2.materialId; + } +}; +#endif + void pathtraceInit(Scene* scene) { hst_scene = scene; @@ -146,12 +158,60 @@ __global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth, Path segment.ray.origin = cam.position; segment.color = glm::vec3(1.0f, 1.0f, 1.0f); + // TODO: implement antialiasing by jittering the ray - 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) +//#if ANTI_ALIASING +// float dx = 0, dy = 0; +// thrust::default_random_engine rng = makeSeededRandomEngine(iter, index, traceDepth); +// thrust::uniform_real_distribution ux(0, 1); +// thrust::uniform_real_distribution uy(0, 1); +// dx= ux(rng); dy = uy(rng); +// segment.ray.direction = glm::normalize(cam.view +// - cam.right * cam.pixelLength.x * ((float)(x + dx) - (float)cam.resolution.x * 0.5f) +// - cam.up * cam.pixelLength.y * ((float)(y + dy) - (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) +// ); +//#endif +// segment.pixelIndex = index; +// segment.remainingBounces = traceDepth; +#if ANTI_ALIASING + float dx = 0, dy = 0; + thrust::default_random_engine rng = makeSeededRandomEngine(iter, index, traceDepth); + thrust::uniform_real_distribution ux(0, 1); + thrust::uniform_real_distribution uy(0, 1); + dx = ux(rng); dy = uy(rng); +#endif + glm::vec3 direction = glm::normalize(cam.view + - cam.right * cam.pixelLength.x * ((float)x + (ANTI_ALIASING ? dx : 0.0f) - (float)cam.resolution.x * 0.5f) + - cam.up * cam.pixelLength.y * ((float)y + (ANTI_ALIASING ? dy : 0.0f) - (float)cam.resolution.y * 0.5f) ); +#if DEPTH_OF_FIELD + thrust::default_random_engine rngDOF = makeSeededRandomEngine(iter, index, traceDepth); + thrust::uniform_real_distribution u01(-0.5f, 0.5f); + + //0.0, 5.0, 10.5 - eye + glm::vec3 sphereCenter(-2.0, 0.0, 5.0); + float focalDistance = glm::length(sphereCenter - cam.position); // Distance to the focal plane - Some sphere in scene + + //float focalDistance = 2.0f; // Distance to the focal plane + float apertureRadius = 0.2f; // Radius of the aperture + + glm::vec3 focalPoint = cam.position + direction * focalDistance; + + glm::vec3 apertureOffset = cam.right * apertureRadius * u01(rngDOF) + cam.up * apertureRadius * u01(rngDOF); + segment.ray.origin = cam.position + apertureOffset; + + segment.ray.direction = glm::normalize(focalPoint - segment.ray.origin); +#else + segment.ray.origin = cam.position; + segment.ray.direction = direction; +#endif + segment.pixelIndex = index; segment.remainingBounces = traceDepth; } @@ -222,6 +282,7 @@ __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].intersectionPoint = intersect_point; } } } @@ -248,9 +309,9 @@ __global__ void shadeFakeMaterial( 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. + // 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::uniform_real_distribution u01(0, 1); @@ -280,6 +341,76 @@ __global__ void shadeFakeMaterial( } } +__global__ void shadeMaterial( + int iter, + int num_paths, + ShadeableIntersection* shadeableIntersections, + PathSegment* pathSegments, + Material* materials, + Geom* geoms, + int geoms_size) +{ + 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... + { + thrust::default_random_engine rng = makeSeededRandomEngine(iter, idx, 0); + thrust::uniform_real_distribution u01(0, 1); + + Material material = materials[intersection.materialId]; + + // If the material is emissive, terminate the path + if (material.emittance > 0.0f) { + pathSegments[idx].remainingBounces = 0; + pathSegments[idx].color *= (material.color * material.emittance); + } + else { +#if RUSSIAN_ROULETTE + // Russian Roulette path termination + float continueProbability = glm::min(glm::max(pathSegments[idx].color.r, + glm::max(pathSegments[idx].color.g, + pathSegments[idx].color.b)), 0.95f); + + if (u01(rng) > continueProbability) { + // Terminate the path + pathSegments[idx].remainingBounces = 0; + } + else { + // Continue the path, but adjust the color to account for terminated paths + pathSegments[idx].color /= continueProbability; + + // Call scatterRay to generate a new ray direction + scatterRay(pathSegments[idx], + intersection.intersectionPoint, + intersection.surfaceNormal, + material, + rng, + geoms, + geoms_size, + materials); + } +#else + scatterRay(pathSegments[idx], + intersection.intersectionPoint, + intersection.surfaceNormal, + material, + rng, + geoms, + geoms_size, + materials); +#endif + } + } + else { + // No intersection, terminate the path + pathSegments[idx].remainingBounces = 0; + pathSegments[idx].color = glm::vec3(0.0f); + } + } +} + // Add the current iteration's output to the overall image __global__ void finalGather(int nPaths, glm::vec3* image, PathSegment* iterationPaths) { @@ -342,7 +473,7 @@ void pathtrace(uchar4* pbo, int frame, int iter) // TODO: perform one iteration of path tracing - generateRayFromCamera<<>>(cam, iter, traceDepth, dev_paths); + generateRayFromCamera << > > (cam, iter, traceDepth, dev_paths); checkCUDAError("generate camera ray"); int depth = 0; @@ -360,14 +491,14 @@ void pathtrace(uchar4* pbo, int frame, int iter) // tracing dim3 numblocksPathSegmentTracing = (num_paths + blockSize1d - 1) / blockSize1d; - computeIntersections<<>> ( + computeIntersections << > > ( depth, num_paths, dev_paths, dev_geoms, hst_scene->geoms.size(), dev_intersections - ); + ); checkCUDAError("trace one bounce"); cudaDeviceSynchronize(); depth++; @@ -381,14 +512,32 @@ void pathtrace(uchar4* pbo, int frame, int iter) // TODO: compare between directly shading the path segments and shading // path segments that have been reshuffled to be contiguous in memory. - shadeFakeMaterial<<>>( + /*shadeFakeMaterial<<>>( iter, num_paths, dev_intersections, dev_paths, dev_materials - ); - iterationComplete = true; // TODO: should be based off stream compaction results. + );*/ + +#if MATERIAL_SORT + thrust::sort_by_key(thrust::device, dev_intersections, dev_intersections + num_paths, dev_paths, SortMaterialById()); +#endif + + shadeMaterial << > > ( + iter, + num_paths, + dev_intersections, + dev_paths, + dev_materials, + dev_geoms, + hst_scene->geoms.size() + ); + + //iterationComplete = true; // TODO: should be based off stream compaction results. + dev_path_end = thrust::partition(thrust::device, dev_paths, dev_path_end, RayHasIntersected()); + num_paths = dev_path_end - dev_paths; + iterationComplete = (num_paths <= 0 || depth >= traceDepth); if (guiData != NULL) { @@ -398,12 +547,12 @@ 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 << > > (pixelcount, dev_image, dev_paths); /////////////////////////////////////////////////////////////////////////// // Send results to OpenGL buffer for rendering - sendImageToPBO<<>>(pbo, cam.resolution, iter, dev_image); + sendImageToPBO << > > (pbo, cam.resolution, iter, dev_image); // Retrieve image from GPU cudaMemcpy(hst_scene->state.image.data(), dev_image, diff --git a/src/pathtrace.h b/src/pathtrace.h index e767d0ef..9187b615 100644 --- a/src/pathtrace.h +++ b/src/pathtrace.h @@ -3,6 +3,18 @@ #include #include "scene.h" +#define STREAM_COMPACTION 1 +#define MATERIAL_SORT 0 +#define ANTI_ALIASING 1 +#define DEPTH_OF_FIELD 0 +#define RUSSIAN_ROULETTE 1 + +struct RayHasIntersected { + __host__ __device__ bool operator()(const PathSegment& path) const { + return path.remainingBounces != 0; + } +}; + void InitDataContainer(GuiDataContainer* guiData); void pathtraceInit(Scene *scene); void pathtraceFree(); diff --git a/src/scene.cpp b/src/scene.cpp index 706bf85b..f0ffd0a2 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -35,26 +35,59 @@ void Scene::loadFromJSON(const std::string& jsonName) const auto& name = item.key(); const auto& p = item.value(); Material newMaterial{}; - // TODO: handle materials loading differently + const auto& col = p["RGB"]; + newMaterial.color = glm::vec3(col[0], col[1], col[2]); + + // Initialize default values + newMaterial.hasReflective = 0.0f; + newMaterial.hasRefractive = 0.0f; + newMaterial.metallic = 0.0f; + newMaterial.roughness = 0.5f; + newMaterial.plasticSpecular = 0.0f; + newMaterial.indexOfRefraction = 1.5f; + if (p["TYPE"] == "Diffuse") { - const auto& col = p["RGB"]; - newMaterial.color = glm::vec3(col[0], col[1], col[2]); + // Keep default values } else if (p["TYPE"] == "Emitting") { - const auto& col = p["RGB"]; - newMaterial.color = glm::vec3(col[0], col[1], col[2]); newMaterial.emittance = p["EMITTANCE"]; } else if (p["TYPE"] == "Specular") { - const auto& col = p["RGB"]; - newMaterial.color = glm::vec3(col[0], col[1], col[2]); + newMaterial.hasReflective = 1.0f; + newMaterial.specular.color = newMaterial.color; } + else if (p["TYPE"] == "Dielectric") + { + newMaterial.hasRefractive = 1.0f; + newMaterial.indexOfRefraction = p["IOR"]; + } + else if (p["TYPE"] == "Metallic") + { + newMaterial.metallic = p["METALLIC"]; + newMaterial.hasReflective = newMaterial.metallic; + newMaterial.specular.color = glm::mix(glm::vec3(0.04f), newMaterial.color, newMaterial.metallic); + } + else if (p["TYPE"] == "Plastic") + { + newMaterial.plasticSpecular = p["SPECULAR"]; + newMaterial.hasReflective = 1.0f; // Always have some reflection for plastics + newMaterial.indexOfRefraction = p["IOR"]; + } + + // Handle Roughness + if (p.contains("ROUGHNESS")) + { + newMaterial.roughness = p["ROUGHNESS"].get(); + } + newMaterial.specular.exponent = 1.0f - newMaterial.roughness; + MatNameToID[name] = materials.size(); materials.emplace_back(newMaterial); } + const auto& objectsData = data["Objects"]; for (const auto& p : objectsData) { @@ -80,7 +113,9 @@ void Scene::loadFromJSON(const std::string& jsonName) newGeom.inverseTransform = glm::inverse(newGeom.transform); newGeom.invTranspose = glm::inverseTranspose(newGeom.transform); + geoms.push_back(newGeom); + } const auto& cameraData = data["Camera"]; Camera& camera = state.camera; @@ -114,4 +149,5 @@ void Scene::loadFromJSON(const std::string& jsonName) int arraylen = camera.resolution.x * camera.resolution.y; state.image.resize(arraylen); std::fill(state.image.begin(), state.image.end(), glm::vec3()); -} + +} \ No newline at end of file diff --git a/src/sceneStructs.h b/src/sceneStructs.h index ab46f6f6..37f30784 100644 --- a/src/sceneStructs.h +++ b/src/sceneStructs.h @@ -43,6 +43,9 @@ struct Material float hasRefractive; float indexOfRefraction; float emittance; + float metallic; + float roughness; + float plasticSpecular; }; struct Camera @@ -81,5 +84,6 @@ struct ShadeableIntersection { float t; glm::vec3 surfaceNormal; + glm::vec3 intersectionPoint; int materialId; };