Skip to content

Commit 84613a3

Browse files
committed
update readme
1 parent 5b8d361 commit 84613a3

File tree

14 files changed

+166
-70
lines changed

14 files changed

+166
-70
lines changed

README.md

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
![](results/Cover/CoverDenoisedMIS.png)
1111

12-
<p align="center">A large mineway castle shade with one Disney BRDF material (6,490,766 triangles)</p>
12+
<p align="center">A large mineway castle shaded with one Disney BRDF material (6,490,766 triangles, 300 spp, 6.1 fps)</p>
1313

1414
![](results/RefractDragon.png)
1515

16-
<p align="center">A stanford dragon shade with refract material</p>
16+
<p align="center">A stanford dragon shaded with refract material</p>
1717

1818
## Features Implemented:
1919

@@ -27,11 +27,35 @@
2727

2828
# Bounding Volume Hierarchy
2929

30-
The base code shoot rays out from the camera and intersect each object in the scene.
30+
The base code shoots rays out from the camera and compute intersections with all objects in the scene.
3131

32-
After mesh loading feature is implemented, the way of light-scene intersection is changed from calculating
33-
intersection with implicit geometries to calculating it with all triangles! Which gives an extremely low frame rate
34-
when model with many faces is loaded:
32+
This works fine when we can implicitly define intersecting method for each geometry (just like SDF). But after mesh loading feature is implemented, the way of light-scene intersection is changed from calculating
33+
intersection with implicit geometries to calculating it with all triangles!
34+
35+
This gives an extremely low performance when model with many faces is loaded:
3536
| < 200 faces (~60 fps) | ~6000 faces (< 10 fps) |
36-
| -------------------------------------|-------------------------- |
37-
| ![](results/cornerEmittanceFixed.png)| ![](results/BeforeBVH.png)|
37+
| -------------------------------- | ------------------------------- |
38+
| ![](results/BVH/simplescene.png) | ![](results/BVH/marioScene.png) |
39+
40+
To effectively reduce the amout of intersection computation, we could use BVH, Bounding Volume Hierarchy, which construct
41+
a tree-like structure to store scene primitives.
42+
43+
The efficiency of BVH depends on how we build the tree. There are many ways to segment triangls, for this project, I used HLBVH, which is a combination of Surface Area Heuristic (SAH) and morton code based Linear BVH. For more reference, check [PBRT 4.3 Bounding Volume Hierarchy](https://pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies).
44+
45+
And this gives a very good speed up
46+
47+
| Before BVH (< 10 fps) | After BVH (~30 fps) |
48+
| ------------------------------- | ----------------------------- |
49+
| ![](results/BVH/marioScene.png) | ![](results/BVH/AfterBVH.png) |
50+
51+
We can go even further with a stanford dragon (2,349,078 triangles)
52+
53+
| Dragon ( 15 fps) |
54+
| --------------------------- |
55+
| ![](results/BVH/Dragon.png) |
56+
57+
Visualizer:
58+
| Wahoo | Dragon | Mineway Castle |
59+
| 5117 triangles | 2,349,078 triangles | 6,490,766 triangles |
60+
| ------------------------------- | ----------------------------- | --------------------------- |
61+
| ![](results/BVH/BVH.png) | ![](results/BVH/DragonBVH.png) | ![](results/BVH/CoverBVH.png) |

results/BVH/AfterBVH.png

1.19 MB
Loading

results/BVH/Dragon.png

1.14 MB
Loading

results/BVH/marioScene.png

1.22 MB
Loading

results/BVH/simplescene.png

1.03 MB
Loading

scenes/cornellNoSphere.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{
66
"TYPE":"Emitting",
77
"RGB":[1.0, 1.0, 1.0],
8-
"EMITTANCE":5.0
8+
"EMITTANCE":10.0
99
},
1010
"diffuse_white":
1111
{
@@ -26,7 +26,16 @@
2626
{
2727
"TYPE":"Specular",
2828
"RGB":[0.98, 0.98, 0.98],
29-
"ROUGHNESS":0.0
29+
"METALLIC":1,
30+
"SUBSURFACE":0.0,
31+
"SPECULAR":1,
32+
"ROUGHNESS":0.0,
33+
"SPECULARTINT":0.0,
34+
"ANISOTROPIC":0.0,
35+
"SHEEN":0.0,
36+
"SHEENTINT":0.0,
37+
"CLEARCOAT":0.0,
38+
"CLEARCOATGLOSS":0.0
3039
}
3140
},
3241
"Camera":
@@ -83,6 +92,15 @@
8392
"TRANS":[5.0,5.0,0.0],
8493
"ROTAT":[0.0,0.0,0.0],
8594
"SCALE":[0.005,5.0,5.0]
95+
},
96+
{
97+
"TYPE":"mesh",
98+
"MATERIAL":"specular_white",
99+
"FILENAME":"D:\\Fall2024\\CIS5650\\Project3-CUDA-Path-Tracer\\scenes\\objs\\Dragon.obj",
100+
"TRANS":[0.0,4.6,0.0],
101+
"ROTAT":[-85.0,0.0,0.0],
102+
"SCALE":[0.04, 0.04, 0.04]
86103
}
87104
]
105+
88106
}

src/PTDirectives.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ __inline__ __host__ __device__ float hash13(glm::vec3 v) {
3131
float hash = glm::fract(sin(dotProduct) * 43758.5453f);
3232

3333
return hash;
34-
}
34+
}
35+

src/interactions.cu

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,50 +59,28 @@ __device__ void scatterRay(
5959
Light* dev_lights,
6060
cudaTextureObject_t envMap)
6161
{
62-
glm::vec3 normal = intersection.surfaceNormal;
63-
glm::vec2 uv = intersection.uv;
64-
65-
glm::vec3 wo = -pathSegment.ray.direction;
66-
glm::vec3 wi = glm::vec3(0.0f);
67-
glm::vec3 col = glm::vec3(1.0f);
68-
Material mat = m;
69-
70-
// TODO: implement PBR model
71-
thrust::uniform_real_distribution<float> u01(0, 1);
72-
glm::vec2 xi = glm::vec2(u01(rng), u01(rng));
73-
glm::mat3 ltw = LocalToWorld(normal);
74-
glm::mat3 wtl = glm::transpose(ltw);
75-
62+
glm::vec3 wi = calculateRandomDirectionInHemisphere(intersection.surfaceNormal, rng);
7663
float pdf = 0.f;
77-
78-
glm::vec3 bsdf = Sample_disneyBSDF(m, wo, xi, wi, ltw, wtl, pdf, rng);
79-
if (pdf <= 0) {
80-
pathSegment.remainingBounces = 0;
81-
return;
82-
}
83-
col = bsdf * AbsDot(wi, normal) / pdf;
64+
glm::vec3 bsdf = m.color;
8465
pathSegment.remainingBounces--;
8566

8667
#ifdef DEBUG_NORMAL
8768
col = glm::vec3(1.f);
88-
pathSegment.color = DEBUG_NORMAL ? (normal + 1.0f) / 2.0f : normal;
69+
pathSegment.accumLight = DEBUG_NORMAL ? (normal + 1.0f) / 2.0f : normal;
8970
pathSegment.remainingBounces = 0;
9071
#elif defined(DEBUG_WORLD_POS)
9172
col = glm::vec3(1.f);
92-
pathSegment.color = glm::clamp(intersect, glm::vec3(0), glm::vec3(1.0f));
73+
pathSegment.accumLight = glm::clamp(intersect, glm::vec3(0), glm::vec3(1.0f));
9374
pathSegment.remainingBounces = 0;
9475
#elif defined(DEBUG_UV)
9576
col = glm::vec3(1.f);
96-
pathSegment.color = glm::vec3(uv, 0);
77+
pathSegment.accumLight = glm::vec3(uv, 0);
9778
pathSegment.remainingBounces = 0;
9879
#endif
99-
//pathSegment.color = glm::vec3(col);
100-
//col = glm::vec3(1.0);
101-
//pathSegment.remainingBounces = 0;
10280

10381
pathSegment.ray.origin = intersect;
10482
pathSegment.ray.direction = glm::normalize(wi);
105-
pathSegment.throughput *= col;
83+
pathSegment.throughput *= bsdf;
10684
}
10785

10886
__device__ void MIS(

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int iteration;
2929
int width;
3030
int height;
3131
OIDNDevice oidnDevice;
32-
32+
bool shadeSimple = false;
3333
//-------------------------------
3434
//-------------MAIN--------------
3535
//-------------------------------
@@ -257,7 +257,7 @@ void runCuda()
257257
// execute the kernel
258258
int frame = 0;
259259

260-
pathtrace(pbo_dptr, pbo_post_dptr, frame, iteration);
260+
pathtrace(pbo_dptr, pbo_post_dptr, frame, iteration, shadeSimple);
261261
// unmap buffer object
262262
cudaGLUnmapBufferObject(pbo);
263263
cudaGLUnmapBufferObject(pbo_post);

src/main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern int iteration;
3232

3333
extern int width;
3434
extern int height;
35-
35+
extern bool shadeSimple;
3636

3737
void runCuda();
3838
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods);

0 commit comments

Comments
 (0)