diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..260bf49
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+PROJ1_WIN/565Pathtracer/Debug/
+PROJ1_WIN/565Pathtracer/Release/
+PROJ1_WIN/Debug/
+PROJ1_WIN/Release/
+PROJ1_WIN/ipch/565pathtracer-beee273d/565pathtracer-d00238b4.ipch
+PROJ1_WIN/565Pathtracer/tmpxft_00001eac_00000000-6_raytraceKernel.cpp3.o
+*.opensdf
+*.sdf
+*.obj
+*.pdb
+*.o
+*.ipch
diff --git a/PROJ1_WIN/565Pathtracer.suo b/PROJ1_WIN/565Pathtracer.suo
new file mode 100644
index 0000000..8a29eca
Binary files /dev/null and b/PROJ1_WIN/565Pathtracer.suo differ
diff --git a/PROJ1_WIN/565Pathtracer/565Pathtracer.vcxproj.user b/PROJ1_WIN/565Pathtracer/565Pathtracer.vcxproj.user
index dfd9f6c..7f6b7fb 100755
--- a/PROJ1_WIN/565Pathtracer/565Pathtracer.vcxproj.user
+++ b/PROJ1_WIN/565Pathtracer/565Pathtracer.vcxproj.user
@@ -16,4 +16,12 @@
scene=../../scenes/sampleScene.txt
WindowsLocalDebugger
-
+
+ scene=../../scenes/sampleScene.txt
+ WindowsLocalDebugger
+
+
+ scene=../../scenes/sampleScene.txt
+ WindowsLocalDebugger
+
+
\ No newline at end of file
diff --git a/PROJ1_WIN/565Pathtracer/test.0 - Copy.bmp b/PROJ1_WIN/565Pathtracer/test.0 - Copy.bmp
new file mode 100644
index 0000000..8cb6ad0
Binary files /dev/null and b/PROJ1_WIN/565Pathtracer/test.0 - Copy.bmp differ
diff --git a/PROJ1_WIN/565Pathtracer/test.0.bmp b/PROJ1_WIN/565Pathtracer/test.0.bmp
new file mode 100644
index 0000000..1c723fe
Binary files /dev/null and b/PROJ1_WIN/565Pathtracer/test.0.bmp differ
diff --git a/PROJ1_WIN/565Pathtracer/test.1.bmp b/PROJ1_WIN/565Pathtracer/test.1.bmp
new file mode 100644
index 0000000..b11e638
Binary files /dev/null and b/PROJ1_WIN/565Pathtracer/test.1.bmp differ
diff --git a/README.md b/README.md
index 1e36dc5..fd439ec 100755
--- a/README.md
+++ b/README.md
@@ -6,142 +6,96 @@ Fall 2013
Due Wednesday, 10/02/13
-------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-NOTE:
--------------------------------------------------------------------------------
-This project requires an NVIDIA graphics card with CUDA capability! Any card after the Geforce 8xxx series will work. If you do not have an NVIDIA graphics card in the machine you are working on, feel free to use any machine in the SIG Lab or in Moore100 labs. All machines in the SIG Lab and Moore100 are equipped with CUDA capable NVIDIA graphics cards. If this too proves to be a problem, please contact Patrick or Liam as soon as possible.
-------------------------------------------------------------------------------
-INTRODUCTION:
+DESCRIPTION :
-------------------------------------------------------------------------------
-In this project, you will extend your raytracer from Project 1 into a full CUDA based global illumination pathtracer.
+In this Project a Path tracer is created by using the concept of GLobal Illumination. In thsi technique a bunch
+of rays are shooted into the scene and each ray is tracked until they hit the light, the color at every bounce
+is calculated and multiplied with the previous color. This process is repeated for every iteration ,and the color
+obtained at each iteration is averaged and added to the previous value.
-For this project, you may either choose to continue working off of your codebase from Project 1, or you may choose to use the included basecode in this repository. The basecode for Project 2 is the same as the basecode for Project 1, but with some missing components you will need filled in, such as the intersection testing and camera raycasting methods.
+All the basic requirements such as
+* Full global illumination
+* Properly accumulating emittance and colors to generate a final image
+* Supersampled antialiasing
+Have been implemented
-How you choose to extend your raytracer into a pathtracer is a fairly open-ended problem; the supplied basecode is meant to serve as one possible set of guidelines for doing so, but you may choose any approach you want in your actual implementation, including completely scrapping the provided basecode in favor of your own from-scratch solution.
+* Parallelization by ray instead of by pixel via stream compaction
+This was done using Thrust library and the function if_remove was used to compress the ray pool by removing
+the dead rays.
--------------------------------------------------------------------------------
-CONTENTS:
--------------------------------------------------------------------------------
-The Project2 root directory contains the following subdirectories:
-
-* src/ contains the source code for the project. Both the Windows Visual Studio solution and the OSX makefile reference this folder for all source; the base source code compiles on OSX and Windows without modification.
-* scenes/ contains an example scene description file.
-* renders/ contains two example renders: the raytraced render from Project 1 (GI_no.bmp), and the same scene rendered with global illumination (GI_yes.bmp).
-* PROJ1_WIN/ contains a Windows Visual Studio 2010 project and all dependencies needed for building and running on Windows 7.
-* PROJ1_OSX/ contains a OSX makefile, run script, and all dependencies needed for building and running on Mac OSX 10.8.
-* PROJ1_NIX/ contains a Linux makefile for building and running on Ubuntu
- 12.04 LTS. Note that you will need to set the following environment
- variables:
-
- - PATH=$PATH:/usr/local/cuda-5.5/bin
- - LD_LIBRARY_PATH=/usr/local/cuda-5.5/lib64:/lib
-
-The projects build and run exactly the same way as in Project0 and Project1.
+* Perfect specular reflection
+Was achieved by reflecting the rays when they hit the reflective surface
--------------------------------------------------------------------------------
-REQUIREMENTS:
--------------------------------------------------------------------------------
-In this project, you are given code for:
-* All of the basecode from Project 1, plus:
-* Intersection testing code for spheres and cubes
-* Code for raycasting from the camera
+The extra features that were implemented are :
-You will need to implement the following features. A number of these required features you may have already implemented in Project 1. If you have, you are ahead of the curve and have less work to do!
+* Translational motion blur
+ Here the object position was varied according to linear interpolated values of its start and end
+ position during each iteration
-* Full global illumination (including soft shadows, color bleeding, etc.) by pathtracing rays through the scene.
-* Properly accumulating emittance and colors to generate a final image
-* Supersampled antialiasing
-* Parallelization by ray instead of by pixel via stream compaction
-* Perfect specular reflection
+* Snell-based Refraction, i.e. glass
+ Here the basic Snells refraction was implemented using the Glm::refract function and a probability
+ was assigned to get both reflections and refractions on the material
-You are also required to implement at least two of the following features. Some of these features you may have already implemented in Project 1. If you have, you may NOT resubmit those features and instead must pick two new ones to implement.
+* OBJ Mesh loading and rendering with Bounding boxes
+ The Obj loading was implemented earlier for ray tracer , but in this assignmnet the maximum and minimum
+ co-ordinates of the mesh were calculated and sent to the GPU and hence a max min box intersection test
+ was done
-* Additional BRDF models, such as Cook-Torrance, Ward, etc. Each BRDF model may count as a separate feature.
-* Texture mapping
-* Bump mapping
-* Translational motion blur
-* Fresnel-based Refraction, i.e. glass
-* OBJ Mesh loading and rendering without KD-Tree
* Interactive camera
-* Integrate an existing stackless KD-Tree library, such as CUKD (https://github.com/unvirtual/cukd)
-* Depth of field
-
-Alternatively, implementing just one of the following features can satisfy the "pick two" feature requirement, since these are correspondingly more difficult problems:
-
-* Physically based subsurface scattering and transmission
-* Implement and integrate your own stackless KD-Tree from scratch.
-* Displacement mapping
-* Deformational motion blur
+ A interactive mouse has been implemented by imagining a camera attched to the sphere and hence the new
+ positions are calculated based on that. To do this feature CIS 563 cloth simulation assignmnet was referred,
+ and it partially acted as a guide for path tracer interaction feature.
-As yet another alternative, if you have a feature or features you really want to implement that are not on this list, let us know, and we'll probably say yes!
+* Depth of field
+ DOF was implemneted by selecting a depth plane away from the camera and jittering the camera position during
+ each iteration.
-------------------------------------------------------------------------------
-NOTES ON GLM:
+Working Video :
-------------------------------------------------------------------------------
-This project uses GLM, the GL Math library, for linear algebra. You need to know two important points on how GLM is used in this project:
-
-* In this project, indices in GLM vectors (such as vec3, vec4), are accessed via swizzling. So, instead of v[0], v.x is used, and instead of v[1], v.y is used, and so on and so forth.
-* GLM Matrix operations work fine on NVIDIA Fermi cards and later, but pre-Fermi cards do not play nice with GLM matrices. As such, in this project, GLM matrices are replaced with a custom matrix struct, called a cudaMat4, found in cudaMat4.h. A custom function for multiplying glm::vec4s and cudaMat4s is provided as multiplyMV() in intersections.h.
-
+[Path Tracer Video](http://www.youtube.com/watch?v=bA-7rGa7juM&feature=youtu.be)
-------------------------------------------------------------------------------
-README
+ScreenShots :
-------------------------------------------------------------------------------
-All students must replace or augment the contents of this Readme.md in a clear
-manner with the following:
+Here is the first image with the basic diffuse applied on all the materials
-* A brief description of the project and the specific features you implemented.
-* At least one screenshot of your project running.
-* A 30 second or longer video of your project running. To create the video you
- can use http://www.microsoft.com/expression/products/Encoder4_Overview.aspx
-* A performance evaluation (described in detail below).
+
--------------------------------------------------------------------------------
-PERFORMANCE EVALUATION
--------------------------------------------------------------------------------
-The performance evaluation is where you will investigate how to make your CUDA
-programs more efficient using the skills you've learned in class. You must have
-performed at least one experiment on your code to investigate the positive or
-negative effects on performance.
-One such experiment would be to investigate the performance increase involved
-with adding a spatial data-structure to your scene data.
+With Reflections applied
+
-Another idea could be looking at the change in timing between various block
-sizes.
+With refractions applied
+
-A good metric to track would be number of rays per second, or frames per
-second, or number of objects displayable at 60fps.
+With Depth of Field
+
-We encourage you to get creative with your tweaks. Consider places in your code
-that could be considered bottlenecks and try to improve them.
+With Motion Blur
+
-Each student should provide no more than a one page summary of their
-optimizations along with tables and or graphs to visually explain any
-performance differences.
+With OBJ loader and bounding boxes
+
+
+Other renders
+
--------------------------------------------------------------------------------
-THIRD PARTY CODE POLICY
--------------------------------------------------------------------------------
-* Use of any third-party code must be approved by asking on the Google group. If it is approved, all students are welcome to use it. Generally, we approve use of third-party code that is not a core part of the project. For example, for the ray tracer, we would approve using a third-party library for loading models, but would not approve copying and pasting a CUDA function for doing refraction.
-* Third-party code must be credited in README.md.
-* Using third-party code without its approval, including using another student's code, is an academic integrity violation, and will result in you receiving an F for the semester.
--------------------------------------------------------------------------------
-SELF-GRADING
--------------------------------------------------------------------------------
-* On the submission date, email your grade, on a scale of 0 to 100, to Liam, liamboone+cis565@gmail.com, with a one paragraph explanation. Be concise and realistic. Recall that we reserve 30 points as a sanity check to adjust your grade. Your actual grade will be (0.7 * your grade) + (0.3 * our grade). We hope to only use this in extreme cases when your grade does not realistically reflect your work - it is either too high or too low. In most cases, we plan to give you the exact grade you suggest.
-* Projects are not weighted evenly, e.g., Project 0 doesn't count as much as the path tracer. We will determine the weighting at the end of the semester based on the size of each project.
-------------------------------------------------------------------------------
-SUBMISSION
+PERFORMANCE EVALUATION
-------------------------------------------------------------------------------
-As with the previous project, you should fork this project and work inside of your fork. Upon completion, commit your finished project back to your fork, and make a pull request to the master repository.
-You should include a README.md file in the root directory detailing the following
-
-* A brief description of the project and specific features you implemented
-* At least one screenshot of your project running, and at least one screenshot of the final rendered output of your pathtracer
-* Instructions for building and running your project if they differ from the base code
-* A link to your blog post detailing the project
-* A list of all third-party code used
+
+
+
+In this Performance evaluation, the speeds or the time elapsed for with and without stream
+campaction is compared. Here initially when the number of bounces are less, without stream
+campaction would work better because of thrust remove_if overhead calculations for smaller
+bounces.
+Whereas it can be easily seen how the performance improves when the number of threads are reduced
+when we have more number of bounces and hence more number of rays that can be removed from the raypool
+
+
diff --git a/renders/2.png b/renders/2.png
new file mode 100644
index 0000000..d1fe7a7
Binary files /dev/null and b/renders/2.png differ
diff --git a/renders/3.png b/renders/3.png
new file mode 100644
index 0000000..f995b75
Binary files /dev/null and b/renders/3.png differ
diff --git a/renders/4.png b/renders/4.png
new file mode 100644
index 0000000..a1da02d
Binary files /dev/null and b/renders/4.png differ
diff --git a/renders/5.png b/renders/5.png
new file mode 100644
index 0000000..7ebd9ad
Binary files /dev/null and b/renders/5.png differ
diff --git a/renders/6.png b/renders/6.png
new file mode 100644
index 0000000..6dfd8e5
Binary files /dev/null and b/renders/6.png differ
diff --git a/renders/7.png b/renders/7.png
new file mode 100644
index 0000000..5afbca1
Binary files /dev/null and b/renders/7.png differ
diff --git a/renders/8.png b/renders/8.png
new file mode 100644
index 0000000..65e7d68
Binary files /dev/null and b/renders/8.png differ
diff --git a/renders/table.png b/renders/table.png
new file mode 100644
index 0000000..4a6fe8b
Binary files /dev/null and b/renders/table.png differ
diff --git a/scenes/backup_sample.txt b/scenes/backup_sample.txt
new file mode 100644
index 0000000..670736f
--- /dev/null
+++ b/scenes/backup_sample.txt
@@ -0,0 +1,229 @@
+MATERIAL 0 //white diffuse
+RGB 0.9 0.9 0.9
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 1 //red diffuse
+RGB .63 .06 .04
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 2 //green diffuse
+RGB .15 .48 .09
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 3 //red glossy
+RGB .63 .26 .24
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1.5
+REFRIOR 2
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 4 //white glossy
+RGB 1 1 1
+SPECEX 0
+SPECRGB 1 1 1
+REFL 1
+REFR 0
+REFRIOR 2
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 5 //glass
+RGB 0 0 0
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1
+REFRIOR 2.2
+SCATTER 0
+ABSCOEFF .02 5.1 5.7
+RSCTCOEFF 13
+EMITTANCE 0
+
+MATERIAL 6 //green glossy
+RGB .35 .48 .29
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 2.6
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 7 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 1
+
+MATERIAL 8 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 15
+
+CAMERA
+RES 800 800
+FOVY 25
+ITERATIONS 5000
+FILE test.bmp
+frame 0
+EYE 0 4.5 12
+VIEW 0 0 -1
+UP 0 1 0
+frame 1
+EYE 0 4.5 12
+VIEW 0 0 -1
+UP 0 1 0
+
+OBJECT 0
+cube
+material 0
+frame 0
+TRANS 0 0 0
+ROTAT 0 0 90
+SCALE .01 10 10
+frame 1
+TRANS 0 0 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 1
+cube
+material 0
+frame 0
+TRANS 0 5 -5
+ROTAT 0 90 0
+SCALE .01 10 10
+frame 1
+TRANS 0 5 -5
+ROTAT 0 90 0
+SCALE .01 10 10
+
+OBJECT 2
+cube
+material 0
+frame 0
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .01 10 10
+frame 1
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 3
+cube
+material 1
+frame 0
+TRANS -5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+frame 1
+TRANS -5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 4
+cube
+material 2
+frame 0
+TRANS 5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+frame 1
+TRANS 5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 5
+sphere
+material 4
+frame 0
+TRANS 0 2 0
+ROTAT 0 180 0
+SCALE 3 3 3
+frame 1
+TRANS 0 2 0
+ROTAT 0 180 0
+SCALE 3 3 3
+
+OBJECT 6
+sphere
+material 3
+frame 0
+TRANS 2 5 2
+ROTAT 0 180 0
+SCALE 2.5 2.5 2.5
+frame 1
+TRANS 2 5 2
+ROTAT 0 180 0
+SCALE 2.5 2.5 2.5
+
+OBJECT 7
+sphere
+material 6
+frame 0
+TRANS -2 5 -2
+ROTAT 0 180 0
+SCALE 3 3 3
+frame 1
+TRANS -2 5 -2
+ROTAT 0 180 0
+SCALE 3 3 3
+
+OBJECT 8
+cube
+material 8
+frame 0
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .3 3 3
+frame 1
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .3 3 3
diff --git a/scenes/sampleScene.txt b/scenes/sampleScene.txt
index 52d079e..670736f 100755
--- a/scenes/sampleScene.txt
+++ b/scenes/sampleScene.txt
@@ -38,8 +38,8 @@ MATERIAL 3 //red glossy
RGB .63 .26 .24
SPECEX 0
SPECRGB 1 1 1
-REFL 0
-REFR 0
+REFL 0
+REFR 1.5
REFRIOR 2
SCATTER 0
ABSCOEFF 0 0 0
@@ -50,7 +50,7 @@ MATERIAL 4 //white glossy
RGB 1 1 1
SPECEX 0
SPECRGB 1 1 1
-REFL 0
+REFL 1
REFR 0
REFRIOR 2
SCATTER 0
diff --git a/scenes/with object and refraction.txt b/scenes/with object and refraction.txt
new file mode 100644
index 0000000..8a9a789
--- /dev/null
+++ b/scenes/with object and refraction.txt
@@ -0,0 +1,229 @@
+MATERIAL 0 //white diffuse
+RGB 0.9 0.9 0.9
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 1 //red diffuse
+RGB .63 .06 .04
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 2 //green diffuse
+RGB .15 .48 .09
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 3 //red glossy
+RGB .63 .26 .24
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1.5
+REFRIOR 2
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 4 //white glossy
+RGB 1 1 1
+SPECEX 0
+SPECRGB 1 1 1
+REFL 1
+REFR 0
+REFRIOR 2
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 5 //glass
+RGB 0 0 0
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1
+REFRIOR 2.2
+SCATTER 0
+ABSCOEFF .02 5.1 5.7
+RSCTCOEFF 13
+EMITTANCE 0
+
+MATERIAL 6 //green glossy
+RGB .35 .48 .29
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 2.6
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 0
+
+MATERIAL 7 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 1
+
+MATERIAL 8 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+SCATTER 0
+ABSCOEFF 0 0 0
+RSCTCOEFF 0
+EMITTANCE 15
+
+CAMERA
+RES 800 800
+FOVY 25
+ITERATIONS 5000
+FILE test.bmp
+frame 0
+EYE 0 4.5 12
+VIEW 0 0 -1
+UP 0 1 0
+frame 1
+EYE 0 4.5 12
+VIEW 0 0 -1
+UP 0 1 0
+
+OBJECT 0
+cube
+material 0
+frame 0
+TRANS 0 0 0
+ROTAT 0 0 90
+SCALE .01 10 10
+frame 1
+TRANS 0 0 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 1
+cube
+material 0
+frame 0
+TRANS 0 5 -5
+ROTAT 0 90 0
+SCALE .01 10 10
+frame 1
+TRANS 0 5 -5
+ROTAT 0 90 0
+SCALE .01 10 10
+
+OBJECT 2
+cube
+material 0
+frame 0
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .01 10 10
+frame 1
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 3
+cube
+material 1
+frame 0
+TRANS -5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+frame 1
+TRANS -5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 4
+cube
+material 2
+frame 0
+TRANS 5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+frame 1
+TRANS 5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 5
+bunny.obj
+material 6
+frame 0
+TRANS 2 4 -2
+ROTAT 90 180 0
+SCALE 20 20 20
+frame 1
+TRANS 3 4 -2
+ROTAT 90 180 0
+SCALE 20 20 20
+
+OBJECT 6
+sphere
+material 4
+frame 0
+TRANS 0 2 0
+ROTAT 0 180 0
+SCALE 3 3 3
+frame 1
+TRANS 0 2 0
+ROTAT 0 180 0
+SCALE 3 3 3
+
+OBJECT 7
+sphere
+material 3
+frame 0
+TRANS -2 5 -2
+ROTAT 0 180 0
+SCALE 3 3 3
+frame 1
+TRANS -2 5 -2
+ROTAT 0 180 0
+SCALE 3 3 3
+
+OBJECT 8
+cube
+material 8
+frame 0
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .3 3 3
+frame 1
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .3 3 3
diff --git a/src/intersections.h b/src/intersections.h
index a6b9469..90cf859 100755
--- a/src/intersections.h
+++ b/src/intersections.h
@@ -19,6 +19,7 @@ __host__ __device__ glm::vec3 getSignOfRay(ray r);
__host__ __device__ glm::vec3 getInverseDirectionOfRay(ray r);
__host__ __device__ float boxIntersectionTest(staticGeom sphere, ray r, glm::vec3& intersectionPoint, glm::vec3& normal);
__host__ __device__ float boxIntersectionTest(glm::vec3 boxMin, glm::vec3 boxMax, staticGeom box, ray r, glm::vec3& intersectionPoint, glm::vec3& normal);
+__host__ __device__ float triangleIntersectionTest(staticGeom triangle, ray r,glm::vec3 p11,glm::vec3 p12,glm::vec3 p13, glm::vec3& intersectionPoint, glm::vec3& normal);
__host__ __device__ float sphereIntersectionTest(staticGeom sphere, ray r, glm::vec3& intersectionPoint, glm::vec3& normal);
__host__ __device__ glm::vec3 getRandomPointOnCube(staticGeom cube, float randomSeed);
@@ -203,6 +204,66 @@ __host__ __device__ float sphereIntersectionTest(staticGeom sphere, ray r, glm::
return glm::length(r.origin - realIntersectionPoint);
}
+// Triangle intersection test
+__host__ __device__ float triangleIntersectionTest(staticGeom triangle, ray r,glm::vec3 p1,glm::vec3 p2,glm::vec3 p3, glm::vec3& intersectionPoint, glm::vec3& normal){
+ glm::vec3 ro = multiplyMV(triangle.inverseTransform, glm::vec4(r.origin,1.0f));
+ glm::vec3 rd = glm::normalize(multiplyMV(triangle.inverseTransform, glm::vec4(r.direction,0.0f)));
+
+ ray rt; rt.origin = ro; rt.direction = rd;
+ glm::vec3 n ;
+ n = glm::normalize(glm::cross((p3-p1),(p2-p1)));
+
+
+ glm::vec3 nf = glm::normalize(glm::cross((p3-p1),(p2-p1))) ;
+ glm::vec3 onor = multiplyMV(triangle.inverseTransform, glm::vec4(nf,1.0f));
+ double thit ;
+ thit = (float)(glm::dot(p1,n) - glm::dot(ro,n))/(glm::dot(rd,n)) ;
+ if(thit < 0 )
+ return -1 ;
+
+ // check if the intersection with plane was inside triangle ,if not then output -1
+ float sa,ta ;
+ glm::vec3 w;
+ glm::vec3 rr = getPointOnRay(rt, thit) ;
+ w = rr - p1 ;
+ // Now using the parametric representation of a plane and finding the s and t values of the equation
+ // V(s,t) = V0 + s * ( V1 - V0) + t * (V2 - V0);
+ // Find the s and t values using the ray equation . If s >=0 , t >=0 & s+t <= 0 ,then the point lies inside the triangle
+ glm::vec3 u,v;
+ u = p2-p1;
+ v = p3-p1;
+ float den = pow(glm::dot(u,v),2) - (glm::dot(u,u) * glm::dot(v,v)) ;
+ sa = (glm::dot(u,v)*glm::dot(w,v) - glm::dot(v,v) * glm::dot(w,u))/den ;
+ ta = (glm::dot(u,v)*glm::dot(w,u) - glm::dot(u,u) * glm::dot(w,v))/den ;
+
+ glm::vec3 realIntersectionPoint = multiplyMV(triangle.transform, glm::vec4(getPointOnRay(rt, thit), 1.0));
+ glm::vec3 realOrigin = multiplyMV(triangle.transform, glm::vec4(0,0,0,1));
+ intersectionPoint = realIntersectionPoint;
+
+ //normal = glm::normalize(multiplyMV(triangle.transform, glm::vec4(n,0.0f)));
+
+ cudaMat4 itMat = triangle.inverseTransform ;
+ glm::vec4 r1(itMat.x.x,itMat.y.x,itMat.z.x,itMat.w.x);
+ glm::vec4 r2(itMat.x.y,itMat.y.y,itMat.z.y,itMat.w.y);
+ glm::vec4 r3(itMat.x.z,itMat.y.z,itMat.z.z,itMat.w.z);
+ glm::vec4 r4(itMat.x.w,itMat.y.w,itMat.z.w,itMat.w.w);
+
+ cudaMat4 ittrans;
+ ittrans.x = r1;
+ ittrans.y = r2;
+ ittrans.z = r3;
+ ittrans.w = r4;
+
+ normal = glm::normalize(multiplyMV(ittrans, glm::vec4(n,0.0f)));
+
+ if ((sa >= 0) && (ta >= 0) && (sa+ta <= 1+0.001) )
+ return glm::length(r.origin - realIntersectionPoint);
+ else
+ return -1;
+
+
+}
+
//returns x,y,z half-dimensions of tightest bounding box
__host__ __device__ glm::vec3 getRadiuses(staticGeom geom){
glm::vec3 origin = multiplyMV(geom.transform, glm::vec4(0,0,0,1));
diff --git a/src/main.cpp b/src/main.cpp
index 81836b1..bd77552 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -11,6 +11,19 @@
//-------------MAIN--------------
//-------------------------------
+typedef int BOOL;
+ #define TRUE 1
+ #define FALSE 0
+ // Set up mouse call back
+ static BOOL g_bButton1Down = FALSE;
+ static BOOL g_bButton2Down = FALSE;
+ static BOOL g_bButton3Down = FALSE;
+ int bottonMask = 0;
+ int mouse_old_x ;
+ int mouse_old_y ;
+ float spherex =0.0f,spherey = 0.0f,sphereRadius=12.0f ;
+ glm::vec3 sphereCenter = glm::vec3(0,4.0f,0) ;
+
int main(int argc, char** argv){
#ifdef __APPLE__
@@ -21,6 +34,8 @@ int main(int argc, char** argv){
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
+
+
// Set up pathtracer stuff
bool loadedScene = false;
finishedRender = false;
@@ -90,7 +105,8 @@ int main(int argc, char** argv){
#else
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
-
+ glutMouseFunc(MouseButton);
+ glutMotionFunc(MouseMotion);
glutMainLoop();
#endif
return 0;
@@ -121,9 +137,9 @@ void runCuda(){
materials[i] = renderScene->materials[i];
}
-
+ renderScene->mymainpoints;
// execute the kernel
- cudaRaytraceCore(dptr, renderCam, targetFrame, iterations, materials, renderScene->materials.size(), geoms, renderScene->objects.size() );
+ cudaRaytraceCore(dptr, renderCam, targetFrame, iterations, materials, renderScene->materials.size(), geoms, renderScene->objects.size(),renderScene->mymainpoints,renderScene->maxmin );
// unmap buffer object
cudaGLUnmapBufferObject(pbo);
@@ -229,6 +245,122 @@ void runCuda(){
}
}
+ void MouseButton(int button, int state, int x, int y)
+ {
+ mouse_old_x = x;
+ mouse_old_y = y;
+ // Respond to mouse button presses.
+ // If button1 pressed, mark this state so we know in motion function.
+ if (button == GLUT_LEFT_BUTTON)
+ {
+ g_bButton1Down = (state == GLUT_DOWN) ? TRUE : FALSE;
+ bottonMask= 1;
+ //g_yClick = y - 3 * g_fViewDistance;
+ }
+ else if (button == GLUT_RIGHT_BUTTON)
+ {
+ g_bButton2Down = (state == GLUT_DOWN) ? TRUE : FALSE;
+ bottonMask= 2;
+ //g_yClick = y - 3 * g_fViewDistance;
+ }
+ else if (button == GLUT_MIDDLE_BUTTON)
+ {
+ g_bButton3Down = (state == GLUT_DOWN) ? TRUE : FALSE;
+ bottonMask= 3;
+ //g_yClick = y - 3 * g_fViewDistance;
+ }
+ else
+ {
+ bottonMask= 0;
+ }
+ std::cout << button << ", " << state << std::endl;
+ }
+
+ void MouseMotion(int x, int y)
+ {
+
+ float dx, dy;
+ dx = (float)(x - mouse_old_x);
+ dy = (float)(y - mouse_old_y);
+ float r_head = 0.0f , r_pitch = 0.0f ;
+ if( g_bButton1Down || g_bButton2Down || g_bButton3Down)
+ {
+
+ // If button1 pressed, zoom in/out if mouse is moved up/down.
+ if (g_bButton1Down) //Left mouse click drag
+ {
+ spherex += dy * 0.2f;
+ spherey += dx * 0.2f;
+ iterations = 0;
+
+ r_head = glm::radians(spherex);
+ r_pitch = glm::radians(spherey);
+ //renderCam->positions[targetFrame].x = (sphereCenter.x + sphereRadius * glm::sin(r_head) * glm::cos(r_pitch));
+ //renderCam->views[targetFrame] = glm::normalize(glm::vec3(sphereCenter - renderCam->positions[targetFrame]));
+
+ }
+ if (g_bButton2Down) //Right mouse click drag
+ {
+ sphereRadius-= dy * 0.01f;
+ iterations = 0;
+ //int sign = 0 ;
+ // (dx>0)? sign=1 :sign = -1 ;
+ //renderCam->positions[targetFrame].z += sign * 0.2f; //(sphereCenter.z + sphereRadius * glm::cos(r_head) );
+ //renderCam->views[targetFrame] = glm::normalize(glm::vec3(sphereCenter - renderCam->positions[targetFrame]));
+ }
+ if (g_bButton3Down) // Middle mouse click drag
+ {
+
+ glm::vec3 vdir(sphereCenter - renderCam->positions[targetFrame]);
+ glm::vec3 u(glm::normalize(glm::cross(glm::normalize(vdir), renderCam->ups[targetFrame])));
+ glm::vec3 v(glm::normalize(glm::cross(u, glm::normalize(vdir))));
+
+ sphereCenter += 0.01f * (dy * v - dx * u);
+ iterations = 0;
+ //renderCam->positions[targetFrame].x += dx ;//(sphereCenter.x + sphereRadius * glm::sin(r_head) * glm::cos(r_pitch));
+ //renderCam->positions[targetFrame].y =(sphereCenter.y + sphereRadius * glm::sin(r_head) * glm::sin(r_pitch));
+ //renderCam->positions[targetFrame].z =sphereCenter.z + sphereRadius * glm::cos(r_head) );
+ //renderCam->views[targetFrame] = glm::normalize(glm::vec3(sphereCenter - renderCam->positions[targetFrame]));
+ //renderCam->positions[0] = renderCam->positions[0] + 2.0f;
+ }
+ //glutPostRedisplay();
+
+ renderCam->positions[targetFrame].x = (sphereCenter.x + sphereRadius* glm::sin(r_head) * glm::cos(r_pitch));
+ renderCam->positions[targetFrame].y = (sphereCenter.y + sphereRadius * glm::sin(r_head) * glm::sin(r_pitch));
+ renderCam->positions[targetFrame].z = (sphereCenter.z + sphereRadius * glm::cos(r_head) );
+
+ renderCam->views[targetFrame] = glm::normalize(glm::vec3(sphereCenter - renderCam->positions[targetFrame]));
+
+
+ //cam_pos.x = lookat.x + eye_distance * glm::cos(r_head) * glm::cos(r_pitch);
+ // cam_pos.y = lookat.y + eye_distance * glm::sin(r_head);
+ // cam_pos.z = lookat.z + eye_distance * glm::cos(r_head) * glm::sin(r_pitch);
+
+
+ /* renderCam->positions[targetFrame].x = (sphereCenter.x + sphereRadius * glm::sin(r_head) * glm::cos(r_pitch));
+ renderCam->positions[targetFrame].y = (sphereCenter.y + sphereRadius * glm::sin(r_head) * glm::sin(r_pitch));
+ renderCam->positions[targetFrame].z = (sphereCenter.z + sphereRadius * glm::cos(r_head) ); */
+
+
+ mouse_old_x = x;
+ mouse_old_y = y;
+ }
+ }
+
+ void mouseWheel(int button, int dir, int x, int y)
+{
+ if (dir > 0)
+ {
+ // Zoom in
+ }
+ else
+ {
+ // Zoom out
+ }
+
+ return;
+}
+
#endif
diff --git a/src/main.h b/src/main.h
index 0bab7cb..fe14c12 100755
--- a/src/main.h
+++ b/src/main.h
@@ -13,6 +13,7 @@
#else
#include
#include
+
#endif
#include
@@ -86,6 +87,8 @@ void runCuda();
#else
void display();
void keyboard(unsigned char key, int x, int y);
+ void MouseButton(int button, int state, int x, int y);
+ void MouseMotion(int x, int y);
#endif
//-------------------------------
diff --git a/src/raytraceKernel.cu b/src/raytraceKernel.cu
index 87a65a6..074697d 100755
--- a/src/raytraceKernel.cu
+++ b/src/raytraceKernel.cu
@@ -15,11 +15,18 @@
#include "interactions.h"
#include
#include "glm/glm.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
void checkCUDAError(const char *msg) {
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err) {
fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
+ std::cin.get();
exit(EXIT_FAILURE);
}
}
@@ -117,22 +124,112 @@ __global__ void sendImageToPBO(uchar4* PBOpos, glm::vec2 resolution, glm::vec3*
}
}
+__global__ void raytoColorbouncecopy(glm::vec2 resolution,glm::vec3* colBounce, ray* r, int num,int blockdim)
+{
+ int x = (blockIdx.x * blockDim.x) + threadIdx.x;
+ int y = (blockIdx.y * blockDim.y) + threadIdx.y;
+ int index = x + (y * blockdim* blockDim.x );
+ if(index < num)
+ {
+ int xx = r[index].x;
+ int yy = r[index].y;
+ int newindex = xx + (yy * resolution.x);
+
+ if(r[index].life == true && r[index].rcolor[0] !=0 && r[index].rcolor[1] !=0 && r[index].rcolor[2] !=0)
+ colBounce[newindex] = r[index].rcolor ;
+ //if(r[newindex].life == true)
+ /// r[newindex].rcolor = glm::vec3(1,1,1);
+ }
+
+}
+
+
+__global__ void finalizeraycolor(glm::vec2 resolution,glm::vec3* colBounce,glm::vec3* colors,float iters)
+{
+ int x = (blockIdx.x * blockDim.x) + threadIdx.x;
+ int y = (blockIdx.y * blockDim.y) + threadIdx.y;
+ int index = x + (y * resolution.x);
+ //int xx = r[index].x;
+ //int yy = r[index].y;
+ // int newindex = xx + (yy * resolution.x);
+ if(iters < 0.05)
+ iters = 1.0f;
+ if((x<=resolution.x && y<=resolution.y)){
+ /*colIters[index] = colIters[index] + colBounce[index];
+ colIters[index][0] = ((colIters[index][0] * (iters - 1)) + colBounce[index][0]) / iters ;
+ colIters[index][1] = ((colIters[index][1] * (iters - 1)) + colBounce[index][1]) / iters ;
+ colIters[index][2] = ((colIters[index][2] * (iters - 1)) + colBounce[index][2]) / iters ;*/
+ //colors[index ][0] = (colors[index][0] + colBounce[index][0] )/(iters+1) ; //colBounce[index] ;//
+ //colors[index ][1] = (colors[index][1] + colBounce[index][1] )/(iters+1) ;
+ //colors[index ][2] = (colors[index][2] + colBounce[index][2] )/(iters+1) ;
+
+ colors[index ] = (colors[index ] *(iters-1) + colBounce[index])/ (iters) ;
+ // colBounce[index ] = glm::vec3(1,1,1);
+ //r[index ].rcolor = glm::vec3(1,1,1);
+ }
+}
+
+__global__ void initializeray(glm::vec2 resolution, float time,cameraData cam, ray* r,glm::vec3* colBounce,glm::vec3* colIters){
+ int x = (blockIdx.x * blockDim.x) + threadIdx.x;
+ int y = (blockIdx.y * blockDim.y) + threadIdx.y;
+ int index = x + (y * resolution.x);
+ if((x<=resolution.x && y<=resolution.y)){
+ ray rnew = raycastFromCameraKernel(resolution, time, x, y, cam.position, cam.view, cam.up, cam.fov);
+
+ // Depth of Field
+// glm::vec3 dofRayPoint = rnew.origin + 14.0f * glm::normalize(rnew.direction) ;
+// thrust::default_random_engine rng (hash (time ));
+// thrust::uniform_real_distribution xi6(-1,1);
+// thrust::uniform_real_distribution xi7(-1,1);
+// thrust::uniform_real_distribution r1(-1.0,1.0);
+//// srand(time);
+// float dx = r1(rng) ;//* cos(xi6(rng)); //((int)xi6(rng) % 100 + 1 )/1000;//
+// float dy = r1(rng) ;//* sin(xi7(rng)); //((int)xi7(rng) % 100 + 1 )/1000; //
+//
+// rnew.origin = rnew.origin + glm::vec3(dx,dy,0.0f);
+// rnew.direction = glm::normalize(dofRayPoint - rnew.origin );
+
+
+
+
+
+ r[index].direction = glm::normalize(rnew.direction);
+ r[index].origin = rnew.origin;
+ r[index].x = x ;
+ r[index].y = y ;
+ r[index].life = false ;
+ r[index].rcolor = glm::vec3(1,1,1);
+ colBounce[index] = glm::vec3(0,0,0);
+ colIters[index] = glm::vec3(0,0,0);
+ }
+}
//TODO: IMPLEMENT THIS FUNCTION
//Core raytracer kernel
__global__ void raytraceRay(glm::vec2 resolution, float time, float bounce, cameraData cam, int rayDepth, glm::vec3* colors,
- staticGeom* geoms, int numberOfGeoms, material* materials, int numberOfMaterials){
+ staticGeom* geoms, int numberOfGeoms, material* materials, int numberOfMaterials,ray* newr, glm::vec3* colBounce, int bou,int num,int blockdim,glm::vec3* myvertex, int numVertices,float *m ){
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;
- int index = x + (y * resolution.x);
+ int index = x + (y * blockdim* blockDim.x );//
- ray r = raycastFromCameraKernel(resolution, time, x, y, cam.position, cam.view, cam.up, cam.fov);
- if((x<=resolution.x && y<=resolution.y)){
+if ( index < num )
+{
+
+ //ray r = raycastFromCameraKernel(resolution, time, x, y, cam.position, cam.view, cam.up, cam.fov);
+ ray r = newr[index];
+ int xx = r.x;
+ int yy = r.y;
+// int newindex = xx + (yy * blockdim);
+
+ glm::vec3 curIps;
+ glm::vec3 curNorm;
+ if((x<=resolution.x && y<=resolution.y)){
+
float MAX_DEPTH = 100000000000000000;
float depth = MAX_DEPTH;
-
+ int geoIndex = -1;
for(int i=0; i-EPSILON){
MAX_DEPTH = depth;
- colors[index] = materials[geoms[i].materialid].color;
+ geoIndex = i;
+ curIps = intersectionPoint;
+ curNorm = intersectionNormal;
}
}
+ // If you are hitting a object that is not light
+ if(geoIndex != -1 && materials[geoms[geoIndex].materialid].emittance < 0.01f && (r.life == false))
+ {
+
+ thrust::default_random_engine rng (hash (time * index * bou));
+ thrust::uniform_real_distribution xi1(0,1);
+ thrust::uniform_real_distribution xi2(0,1);
+
+ // If the object that you hit is not reflective
+ if ( materials[geoms[geoIndex].materialid].hasReflective < 0.01f && materials[geoms[geoIndex].materialid].hasRefractive < 0.01f)
+ {
+ newr[index].direction = glm::normalize(calculateRandomDirectionInHemisphere(glm::normalize(curNorm), (float)xi1(rng),(float)xi2(rng)));
+ newr[index].origin = curIps + newr[index].direction * 0.001f ; //glm::vec3 neyep = dips + ref1 * 0.001f ;
+ newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].color;
+ }
+ // If the object that you hit is reflective
+ else if ( materials[geoms[geoIndex].materialid].hasReflective > 0.01f && materials[geoms[geoIndex].materialid].hasRefractive < 0.01f)
+ {
+ // Reflectitivity works based on probabbility of the random number generated
+ thrust::uniform_real_distribution xi3(0,1);
+ float rtest = (float)xi3(rng) ;
+ if( rtest < materials[geoms[geoIndex].materialid].hasReflective)
+ {
+ glm::vec3 inc = glm::normalize(newr[index].direction) ;
+ newr[index].direction = inc - (2.0f * glm::normalize(curNorm) * (glm::dot(glm::normalize(curNorm),inc))); //glm::vec3 ref1 = lig - (2.0f * dnorm * (glm::dot(dnorm,lig)));
+ newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].specularColor;
+ }
+ else
+ {
+ newr[index].direction = glm::normalize(calculateRandomDirectionInHemisphere(glm::normalize(curNorm), (float)xi1(rng),(float)xi2(rng)));
+ newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].color;
+ }
+ newr[index].origin = curIps + newr[index].direction * 0.001f ; //glm::vec3 neyep = dips + ref1 * 0.001f ;
+
+ }
+
+ // If the object that you hit is refractive
+ if ( materials[geoms[geoIndex].materialid].hasRefractive > 0.01f)
+ {
+ thrust::uniform_real_distribution xi4(0,1);
+ float rfr = (float)xi4(rng) ;
+ if (rfr < 0.7)//materials[geoms[geoIndex].materialid].hasRefractive )
+ {
+ float n1 = 1.0f;
+ float n2 = materials[geoms[geoIndex].materialid].hasRefractive;
+ float angleofincidence = acos(glm::dot(newr[index].direction ,glm::normalize(curNorm))/(glm::length(newr[index].direction) * glm::length(newr[index].direction)));
+ angleofincidence = abs(angleofincidence * (180.0f/PI));
+ //float angleofreflection = asin(sin(angleofincidence) * (n1/n2));
+ float io = glm::dot( glm::normalize(newr[index].direction),glm::normalize(curNorm));
+ float criticalAngle = asin(n2/n1);// * (180.0f/PI) ;
+
+ if(io < 0.0f )
+ {
+ glm::vec3 refractedray = glm::refract(glm::normalize(newr[index].direction),glm::normalize(curNorm),(n1/n2));
+ newr[index].direction = glm::normalize(refractedray);
+ newr[index].origin = curIps + newr[index].direction * 0.001f ;
+ //newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].color;
+ }
+ else if(io >= 0.0f ) // && (angleofincidence < criticalAngle )
+ {
+ glm::vec3 refractedray = glm::refract(glm::normalize(newr[index].direction),-1.0f * glm::normalize(curNorm),(n2/n1));
+ newr[index].direction = glm::normalize(refractedray);
+ newr[index].origin = curIps + newr[index].direction * 0.001f ;
+ //newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].color;
+ }
+
+ }
+ else
+ {
+ glm::vec3 inc = glm::normalize(newr[index].direction) ;
+ newr[index].direction = inc - (2.0f * glm::normalize(curNorm) * (glm::dot(glm::normalize(curNorm),inc))); //glm::vec3 ref1 = lig - (2.0f * dnorm * (glm::dot(dnorm,lig)));
+ newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].specularColor;
+ newr[index].origin = curIps + newr[index].direction * 0.001f ;
+ }
+ }
+
+
+
+
+ }
+ // If the ray hits an object that is light
+ else if(geoIndex != -1 && materials[geoms[geoIndex].materialid].emittance > 0.01f && (r.life == false))
+ {
+
+ newr[index].rcolor = newr[index].rcolor * materials[geoms[geoIndex].materialid].emittance;
+ newr[index].life = true;
+
+ }
+ // If the ray keeps hitting the light once it dies - This case actually never happens
+ else if(geoIndex != -1 && materials[geoms[geoIndex].materialid].emittance > 0.01f && (r.life == true))
+ {
+
+ newr[index].rcolor = newr[index].rcolor ;
+ newr[index].life = true;
+ }
+ // The final case where the ray does not hit any object at all
+ else
+ {
+
+ newr[index].rcolor = newr[index].rcolor * glm::vec3(0,0,0);
+ newr[index].life = true;
+ }
+
- //colors[index] = generateRandomNumberFromThread(resolution, time, x, y);
}
}
+}
+
+ //A thrust based structure
+ struct is_dead
+ {
+ __host__ __device__
+ bool operator()(const ray r)
+ {
+ return r.life;
+ }
+ };
+
//TODO: FINISH THIS FUNCTION
// Wrapper for the __global__ call that sets up the kernel calls and does a ton of memory management
-void cudaRaytraceCore(uchar4* PBOpos, camera* renderCam, int frame, int iterations, material* materials, int numberOfMaterials, geom* geoms, int numberOfGeoms){
+void cudaRaytraceCore(uchar4* PBOpos, camera* renderCam, int frame, int iterations, material* materials, int numberOfMaterials, geom* geoms, int numberOfGeoms,std::vector mypoints,float *maxmin ){
int traceDepth = 1; //determines how many bounces the raytracer traces
// set up crucial magic
int tileSize = 8;
+ int numVertices = mypoints.size();
dim3 threadsPerBlock(tileSize, tileSize);
- dim3 fullBlocksPerGrid((int)ceil(float(renderCam->resolution.x)/float(tileSize)), (int)ceil(float(renderCam->resolution.y)/float(tileSize)));
+ dim3 fullBlocksPerGrid((int)ceil(float(renderCam->resolution.x)/float(tileSize)) , (int)ceil(float(renderCam->resolution.y)/float(tileSize)));
//send image to GPU
glm::vec3* cudaimage = NULL;
cudaMalloc((void**)&cudaimage, (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(glm::vec3));
cudaMemcpy( cudaimage, renderCam->image, (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(glm::vec3), cudaMemcpyHostToDevice);
+ //Send vertices of the mesh to GPU
+ glm::vec3* mvertex = NULL;
+ cudaMalloc((void**)&mvertex,mypoints.size() * sizeof(glm::vec3));
+
+ for(int i=0; i < mypoints.size(); i++){
+
+ cudaMemcpy( &mvertex[i] , &mypoints[i], sizeof(glm::vec3), cudaMemcpyHostToDevice);
+ }
+
+
+ //Send maxmins of the mesh to GPU
+ float* mami = NULL;
+ cudaMalloc((void**)&mami,6 * sizeof(float));
+ if(maxmin != NULL)
+ {
+ for(int i=0; i < 6; i++){
+
+ cudaMemcpy( &mami[i] , &maxmin[i], sizeof(float), cudaMemcpyHostToDevice);
+ }
+ }
+
//package geometry and materials and sent to GPU
staticGeom* geomList = new staticGeom[numberOfGeoms];
for(int i=0; iups[frame];
cam.fov = renderCam->fov;
- //kernel launches
- for(int bounce = 1; bounce <= 1; ++bounce)
+ //Allocate memory for ray pool
+ ray* raypool = NULL;
+ cudaMalloc((void**)&raypool, (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(ray));
+
+ //Allocate memory to store color for bounces
+ glm::vec3* colorBounce = NULL;
+ cudaMalloc((void**)&colorBounce, (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(glm::vec3));
+
+ //Allocate memory to store color for each iteration accumulation
+ glm::vec3* colorIters = NULL;
+ cudaMalloc((void**)&colorIters , (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(glm::vec3));
+
+ //Initialize the ray values
+ initializeray<<>>(renderCam->resolution,(float)iterations,cam,raypool,colorBounce,colorIters);
+ cudaThreadSynchronize();
+ ////kernel launches
+
+ // const int N = 6;
+ // int A[N] = {1, 4, 2, 8, 5, 7};
+ // int *new_end = thrust::remove_if(A, A + N, is_even());
+ // ray* raystart = new ray[N] ;
+ //cudaMemcpy( raystart, raypool, N*sizeof(ray), cudaMemcpyDeviceToHost);
+ //for(int j=0 ; j < N ; j++)
+ // std::cout << raystart[j].life ;
+ //delete [] raystart;
+
+ //Super-sampled antialiasing code
+ srand(iterations);
+ float x = 0.0f , y = 0.0f ;
+
+ if(iterations%20 == 0 )
{
- raytraceRay<<>>(renderCam->resolution, (float)iterations, (float)bounce, cam, traceDepth, cudaimage, cudageoms, numberOfGeoms, cudamaterials, numberOfMaterials);
+ x = (rand() % 100 + 1)/1000.0f;
+ y = (rand() % 100 + 1)/1000.0f;
+ cam.position[0] +=x;
+ cam.position[1] +=y;
}
+
+ // Motion blur
+ //int mID = 5; // this gives the object id that should be moved
+ //float raa = (rand() % 10 + 1 )/ 10.0f ;
+ //float xtrans = (2.0f * (1.0f - raa)) + (3.0f * raa) ;
+ //geoms[mID].translations[0][0] = xtrans; // comment this line for motion blur on and off
+ //glm::mat4 buildTransformationMatrix(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale);
+ //geoms[mID].transforms[0] = utilityCore::glmMat4ToCudaMat4(utilityCore::buildTransformationMatrix(geoms[mID].translations[0],geoms[mID].rotations[0],geoms[mID].scales[0]));
+ //geoms[mID].inverseTransforms[0] = utilityCore::glmMat4ToCudaMat4(glm::inverse(utilityCore::cudaMat4ToGlmMat4(geoms[mID].transforms[0])));
+
+
+ //create events
+cudaEvent_t event1, event2;
+cudaEventCreate(&event1);
+cudaEventCreate(&event2);
+
+cudaEventRecord(event1, 0);
+
+
+ int N = ((int)renderCam->resolution.x*(int)renderCam->resolution.y);
+ dim3 StreamBlocksPerGrid = fullBlocksPerGrid ;
+ int blockdim = fullBlocksPerGrid.x ;
+ for(int bounce = 1; bounce <=25; ++bounce)
+ {
+
+ raytraceRay<<>>(renderCam->resolution, (float)iterations, (float)bounce, cam, traceDepth, cudaimage, cudageoms, numberOfGeoms, cudamaterials, numberOfMaterials,raypool,colorBounce,bounce,N,blockdim,mvertex,numVertices,mami);
+ raytoColorbouncecopy<<>>(renderCam->resolution,colorBounce,raypool,N,blockdim);
+
+ thrust::device_ptr rptr = thrust::device_pointer_cast(raypool);
+ ray *endrptr = thrust::remove_if(rptr,rptr + N , is_dead()).get();
+ N = endrptr - raypool ;
+ int numofBlocks = ceil((float)N / (float)(tileSize * tileSize)) ;
+ blockdim = ceil(sqrt((float)numofBlocks));
+ StreamBlocksPerGrid = dim3(blockdim,blockdim);
+ cudaThreadSynchronize();
+ }
+
+ finalizeraycolor<<>>(renderCam->resolution,colorBounce,cudaimage,(float)iterations);
+ cudaThreadSynchronize();
sendImageToPBO<<>>(PBOpos, renderCam->resolution, cudaimage);
+
+
+ cudaEventRecord(event2, 0);
+ //synchronize
+ cudaEventSynchronize(event1); //optional
+ cudaEventSynchronize(event2); //wait for the event to be executed!
+
+//calculate time
+float dt_ms;
+cudaEventElapsedTime(&dt_ms, event1, event2);
+
+std::cout << dt_ms << std::endl ;
//retrieve image from GPU
cudaMemcpy( renderCam->image, cudaimage, (int)renderCam->resolution.x*(int)renderCam->resolution.y*sizeof(glm::vec3), cudaMemcpyDeviceToHost);
@@ -218,6 +538,9 @@ void cudaRaytraceCore(uchar4* PBOpos, camera* renderCam, int frame, int iteratio
cudaFree( cudaimage );
cudaFree( cudageoms );
cudaFree( cudamaterials );
+ cudaFree(colorBounce);
+ cudaFree(colorIters);
+ cudaFree(raypool);
delete [] geomList;
// make certain the kernel has completed
@@ -225,3 +548,30 @@ void cudaRaytraceCore(uchar4* PBOpos, camera* renderCam, int frame, int iteratio
checkCUDAError("Kernel failed!");
}
+
+
+float __device__ meshIntersectionTest(staticGeom curGeom,ray s,glm::vec3* myvertex, int numVertices, glm::vec3& mintersect, glm::vec3& mnormal)
+{
+ glm::vec3 ipss,normss;
+ float t , at = 12345.0;
+ glm::vec3 curnorm , curipss;
+
+ for(int k=0 ;k < numVertices - 2 ; k= k+3)
+ {
+ t = triangleIntersectionTest(curGeom,s,myvertex[k],myvertex[k+1],myvertex[k+2], ipss, normss);
+ if(t != -1 && t
#include
#include "sceneStructs.h"
+#include
#if CUDA_VERSION >= 5000
#include
#else
#include
#endif
-
-void cudaRaytraceCore(uchar4* pos, camera* renderCam, int frame, int iterations, material* materials, int numberOfMaterials, geom* geoms, int numberOfGeoms);
+void cudaRaytraceCore(uchar4* pos, camera* renderCam, int frame, int iterations, material* materials, int numberOfMaterials, geom* geoms, int numberOfGeoms, std::vector mymainpoints,float *maxmin );
+float __device__ meshIntersectionTest(staticGeom curGeom,ray s,glm::vec3* myvertex, int numVertices, glm::vec3& htemp, glm::vec3& ntemp);
#endif
diff --git a/src/scene.cpp b/src/scene.cpp
index 415d627..a033639 100755
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -43,7 +43,7 @@ int scene::loadObject(string objectid){
cout << "Loading Object " << id << "..." << endl;
geom newObject;
string line;
-
+ maxmin = NULL; // Change this for obj loading and no obj loading
//load object type
utilityCore::safeGetline(fp_in,line);
if (!line.empty() && fp_in.good()){
@@ -60,7 +60,8 @@ int scene::loadObject(string objectid){
istringstream liness(objline);
getline(liness, name, '.');
getline(liness, extension, '.');
- if(strcmp(extension.c_str(), "obj")==0){
+ if(strcmp(extension.c_str(), "obj")==0){ //
+ loadmesh(objline );
cout << "Creating new mesh..." << endl;
cout << "Reading mesh from " << line << "... " << endl;
newObject.type = MESH;
@@ -263,3 +264,163 @@ int scene::loadMaterial(string materialid){
return 1;
}
}
+
+
+
+// Object loader
+struct coordinate{
+ float x,y,z;
+ coordinate(float a, float b, float c) : x(a),y(b),z(c)
+ {
+ /* x = a ;
+ y = b ;
+ z = c ;*/
+ } ;
+};
+
+struct face
+{
+int facenum ;
+bool three;
+int faces[3] ;
+face(int f1,int f2,int f3)
+{
+ faces[0] = f1;
+ faces[1] = f2;
+ faces[2] = f3;
+ three = true;
+}
+};
+
+std::vector coord;
+
+std::vector vertex;
+
+std::vector faces;
+
+std::vector normals;
+
+//std::vector mymainpoints ;
+
+
+int scene::loadmesh(string filename )
+{
+ //for(int f=1 ; f < 48 ; f++)
+// {
+ //string result,actualfile;
+ //ostringstream convert ;
+ //convert << f ;
+ //result = convert.str();
+ // assigning a number to the output filename
+ //actualfile = filename ; // result+".obj";
+ std::ifstream in("bunny.obj" );//
+ char c[256];
+ cout << filename <c_str(),"%c %f %f %f",&tmp ,&tmpx ,&tmpy , &tmpz);
+ vertex.push_back(new coordinate(tmpx , tmpy,tmpz));
+ cout << "vertext is " << i <x << " "<< vertex[i]->y << " " << vertex[i]->z << endl;
+ }
+ else if((*coord[i])[0] == 'f')
+ {
+ char tmp;
+ int a,b,c;
+ if (count(coord[i]->begin(), coord[i]->end(),' ')==3)
+ {
+ sscanf(coord[i]->c_str(),"%c %d %d %d",&tmp ,&a ,&b , &c);
+ faces.push_back(new face(a,b,c));
+ }
+ }
+ else
+ {
+
+ }
+ }
+
+
+
+
+
+ glm::vec3 v1(0,0,0),v2(0,0,0),v3(0,0,0);
+ //glm::mat3 a(150,0,0,0,150,0,0,0,150);// scale
+ //glm::vec3 p(1.0,6.0,0); // position
+
+ float inf = 10000000000.0f;
+ //maxmin = new float[6] ;
+ //maxmin[6] = {-inf,inf,-inf,inf,-inf,inf};
+ maxmin = new float[6];
+ maxmin[0] = -inf ;
+ maxmin[1] = inf ;
+ maxmin[2] = -inf ;
+ maxmin[3] = inf ;
+ maxmin[4] = -inf ;
+ maxmin[5] = inf ;
+
+ for(int i=0;ifaces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
+ v2 = glm::vec3(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
+ v3 = glm::vec3(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z) ;
+
+ mymainpoints.push_back(glm::vec3(v1[0],v1[2],v1[1]));
+ mymainpoints.push_back(glm::vec3(v2[0],v2[2],v2[1]));
+ mymainpoints.push_back(glm::vec3(v3[0],v3[2],v3[1]));
+
+ if(v1[0] > maxmin[0] ) maxmin[0] = v1[0]; // maximum x of v1 is stored
+ if(v2[0] > maxmin[0] ) maxmin[0] = v2[0]; // maximum x of v2 is stored
+ if(v3[0] > maxmin[0] ) maxmin[0] = v3[0]; // maximum x of v3 is stored
+
+ if(v1[0] < maxmin[1] ) maxmin[1] = v1[0]; // minimum x of v1 is stored
+ if(v2[0] < maxmin[1] ) maxmin[1] = v2[0]; // minimum x of v2 is stored
+ if(v3[0] < maxmin[1] ) maxmin[1] = v3[0]; // minimum x of v3 is stored
+
+
+ if(v1[1] > maxmin[2] ) maxmin[2] = v1[1]; // maximum x of v1 is stored
+ if(v2[1] > maxmin[2] ) maxmin[2] = v2[1]; // maximum x of v2 is stored
+ if(v3[1] > maxmin[2] ) maxmin[2] = v3[1]; // maximum x of v3 is stored
+
+ if(v1[1] < maxmin[3] ) maxmin[3] = v1[1]; // minimum x of v1 is stored
+ if(v2[1] < maxmin[3] ) maxmin[3] = v2[1]; // minimum x of v2 is stored
+ if(v3[1] < maxmin[3] ) maxmin[3] = v3[1]; // minimum x of v3 is stored
+
+
+ if(v1[2] > maxmin[4] ) maxmin[4] = v1[2]; // maximum x of v1 is stored
+ if(v2[2] > maxmin[4] ) maxmin[4] = v2[2]; // maximum x of v2 is stored
+ if(v3[2] > maxmin[4] ) maxmin[4] = v3[2]; // maximum x of v3 is stored
+
+ if(v1[2] < maxmin[5] ) maxmin[5] = v1[2]; // minimum x of v1 is stored
+ if(v2[2] < maxmin[5] ) maxmin[5] = v2[2]; // minimum x of v2 is stored
+ if(v3[2] < maxmin[5] ) maxmin[5] = v3[2]; // minimum x of v3 is stored
+ }
+
+
+ //meanVertices->push_back(mymainpoints);
+ //mymainpoints.clear();
+
+ coord.clear();
+ vertex.clear();
+ faces.clear();
+
+ cout << "bunny is loaded " << endl;
+
+return 0 ;
+
+}
\ No newline at end of file
diff --git a/src/scene.h b/src/scene.h
index 9bfa71f..5e150e6 100755
--- a/src/scene.h
+++ b/src/scene.h
@@ -21,6 +21,7 @@ class scene{
ifstream fp_in;
int loadMaterial(string materialid);
int loadObject(string objectid);
+ int loadmesh(string filename ) ;
int loadCamera();
public:
scene(string filename);
@@ -28,6 +29,8 @@ class scene{
vector objects;
vector materials;
+ vector mymainpoints;
+ float *maxmin ; // float * numbers = new float[x+10];
camera renderCam;
};
diff --git a/src/sceneStructs.h b/src/sceneStructs.h
index b10f1cf..f301ba9 100755
--- a/src/sceneStructs.h
+++ b/src/sceneStructs.h
@@ -16,6 +16,10 @@ enum GEOMTYPE{ SPHERE, CUBE, MESH };
struct ray {
glm::vec3 origin;
glm::vec3 direction;
+ int x;
+ int y;
+ bool life;
+ glm::vec3 rcolor;
};
struct geom {