Skip to content

Commit 8420f6d

Browse files
committed
Assignment7
1 parent e8e0886 commit 8420f6d

File tree

8 files changed

+80
-71
lines changed

8 files changed

+80
-71
lines changed

Frame/Asset/output/assigment7.ppm

0 Bytes
Binary file not shown.

Frame/Source/Assignment/Assignment6/Triangle.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ inline Bounds3 Triangle::getBounds() { return Union(Bounds3(v0, v1), v2); }
210210

211211
inline Intersection Triangle::getIntersection(Ray ray)
212212
{
213-
if (dotProduct(ray.direction, normal) > 0)
213+
if (dotProduct(ray.direction, normal) > 0.0f)
214214
{
215-
// 光线与三角形背面相交。
215+
// ¹âԴλÓÚÈý½ÇÐα³Ãæ¡£
216216
return Intersection{};
217217
}
218218

Frame/Source/Assignment/Assignment7/BVH.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ Intersection BVHAccel::Intersect(const Ray& ray) const
107107

108108
Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const
109109
{
110-
std::array<int, 3> dirIsNeg{
111-
static_cast<int>(ray.direction.x < 0),
112-
static_cast<int>(ray.direction.y < 0),
113-
static_cast<int>(ray.direction.z < 0)
110+
std::array<bool, 3> dirIsNeg{
111+
ray.direction.x < 0,
112+
ray.direction.y < 0,
113+
ray.direction.z < 0
114114
};
115115
if (!node->bounds.IntersectP(ray, ray.direction_inv, std::move(dirIsNeg)))
116116
{

Frame/Source/Assignment/Assignment7/Bounds3.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ class Bounds3
8484
return (i == 0) ? pMin : pMax;
8585
}
8686

87-
inline bool IntersectP(const Ray& ray, const Vector3f& invDir, const std::array<int, 3>& dirisNeg) const;
87+
inline bool IntersectP(const Ray& ray, const Vector3f& invDir, const std::array<bool, 3>& dirisNeg) const;
8888
};
8989

9090

9191

92-
inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir, const std::array<int, 3>& dirIsNeg) const
92+
inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir, const std::array<bool, 3>& dirIsNeg) const
9393
{
9494
float min_x = (pMin.x - ray.origin.x) * invDir[0];
9595
float max_x = (pMax.x - ray.origin.x) * invDir[0];

Frame/Source/Assignment/Assignment7/Scene.cpp

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "Scene.hpp"
66

7+
#include "Utils.hpp"
78

89
void Scene::buildBVH() {
910
printf(" - Generating BVH...\n\n");
@@ -60,66 +61,64 @@ bool Scene::trace(
6061
// Implementation of Path Tracing
6162
Vector3f Scene::castRay(const Ray &ray, int depth) const
6263
{
63-
Intersection p_inter = intersect(ray);
64-
if (!p_inter.happened)
64+
Vector3f L_dir;
65+
Vector3f L_indir;
66+
67+
// 从像素发出的光线与物体的交点
68+
Intersection obj_inter = intersect(ray);
69+
if (!obj_inter.happened)
70+
return L_dir;
71+
72+
// 打到光源
73+
if (obj_inter.m->hasEmission())
74+
return obj_inter.m->getEmission();
75+
76+
// 打到物体
77+
Vector3f p = obj_inter.coords;
78+
Material *m = obj_inter.m;
79+
Vector3f N = obj_inter.normal.normalized();
80+
Vector3f wo = ray.direction; // 像素到物体的向量
81+
82+
// 有交点,对光源采样
83+
float pdf_L = 1.0; //可以不初始化
84+
Intersection light_inter;
85+
sampleLight(light_inter, pdf_L); // 得到光源位置和对光源采样的pdf
86+
87+
Vector3f x = light_inter.coords;
88+
Vector3f ws = (x - p).normalized(); //物体到光源
89+
Vector3f NN = light_inter.normal.normalized();
90+
Vector3f emit = light_inter.emit;
91+
float d = (x - p).norm();
92+
93+
// 再次从光源发出一条光线,判断是否能打到该物体,即中间是否有阻挡
94+
Ray Obj2Light(p, ws);
95+
float d2 = intersect(Obj2Light).distance;
96+
// 是否阻挡,利用距离判断,需注意浮点数的处理
97+
if (d2 - d > -0.001)
98+
// if(Utils::FloatEqual(d2, d))
6599
{
66-
return Vector3f();
67-
}
68-
if (p_inter.m->hasEmission())
69-
{
70-
return p_inter.m->getEmission();
71-
}
72-
73-
float EPLISON = 0.0001;
74-
Vector3f l_dir;
75-
Vector3f l_indir;
76-
77-
// sampleLight(inter, pdf_light)
78-
Intersection x_inter;
79-
float pdf_light = 0.0f;
80-
sampleLight(x_inter, pdf_light);
81-
82-
// Get x, ws, NN, emit from inter
83-
Vector3f p = p_inter.coords;
84-
Vector3f x = x_inter.coords;
85-
Vector3f ws_dir = (x - p).normalized();
86-
float ws_distance = (x - p).norm();
87-
Vector3f N = p_inter.normal.normalized();
88-
Vector3f NN = x_inter.normal.normalized();
89-
Vector3f emit = x_inter.emit;
90-
91-
// Shoot a ray from p to x
92-
Ray ws_ray(p, ws_dir);
93-
Intersection ws_ray_inter = intersect(ws_ray);
94-
// If the ray is not blocked in the middle
95-
if (ws_ray_inter.distance - ws_distance > -EPLISON)
96-
{
97-
l_dir = emit * p_inter.m->eval(ray.direction, ws_ray.direction, N)
98-
* dotProduct(ws_ray.direction, N)
99-
* dotProduct(-ws_ray.direction, NN)
100-
/ std::pow(ws_distance, 2)
101-
/ pdf_light;
100+
Vector3f eval = m->eval(wo, ws, N); // wo不会用到
101+
float cos_theta = dotProduct(N, ws);
102+
float cos_theta_x = dotProduct(NN, -ws);//ws从物体指向光源,与NN的夹角大于180
103+
L_dir = emit * eval * cos_theta * cos_theta_x / std::pow(d, 2) / pdf_L;
102104
}
103105

104-
// Test Russian Roulette with probability RussianRoulette
105-
if (get_random_float() > RussianRoulette)
106+
// L_indir
107+
float P_RR = get_random_float();
108+
if (P_RR < RussianRoulette)
106109
{
107-
return l_dir;
108-
}
109-
110-
l_indir = 0.0;
111-
112-
Vector3f wi_dir = p_inter.m->sample(ray.direction, N).normalized();
113-
Ray wi_ray(p_inter.coords, wi_dir);
114-
// If ray r hit a non-emitting object at q
115-
Intersection wi_inter = intersect(wi_ray);
116-
if (wi_inter.happened && (!wi_inter.m->hasEmission()))
117-
{
118-
l_indir = castRay(wi_ray, depth + 1) * p_inter.m->eval(ray.direction, wi_ray.direction, N)
119-
* dotProduct(wi_ray.direction, N)
120-
/ p_inter.m->pdf(ray.direction, wi_ray.direction, N)
121-
/ RussianRoulette;
110+
Vector3f wi = m->sample(wo, N).normalized();
111+
Ray r(p, wi);
112+
Intersection inter = intersect(r);
113+
// 判断打到的物体是否会发光取决于m
114+
if (inter.happened && !inter.m->hasEmission())
115+
{
116+
Vector3f eval = m->eval(wo, wi, N);
117+
float pdf_O = m->pdf(wo, wi, N);
118+
float cos_theta = dotProduct(wi, N);
119+
L_indir = castRay(r, depth + 1) * eval * cos_theta / pdf_O / RussianRoulette;
120+
}
122121
}
123-
124-
return l_dir + l_indir;
122+
//4->16min
123+
return L_dir + L_indir;
125124
}

Frame/Source/Assignment/Assignment7/Triangle.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ inline Bounds3 Triangle::getBounds() { return Union(Bounds3(v0, v1), v2); }
231231

232232
inline Intersection Triangle::getIntersection(Ray ray)
233233
{
234-
if (dotProduct(ray.direction, normal) > 0)
234+
if (dotProduct(ray.direction, normal) > 0.0f)
235235
{
236-
// 光线与三角形背面相交。
236+
// ¹âԴλÓÚÈý½ÇÐα³Ãæ¡£
237237
return Intersection{};
238238
}
239239

Frame/Source/Assignment/Assignment7/Vector.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ class Vector3f {
3333
{ return Vector3f(v.x * r, v.y * r, v.z * r); }
3434
friend std::ostream & operator << (std::ostream &os, const Vector3f &v)
3535
{ return os << v.x << ", " << v.y << ", " << v.z; }
36-
double operator[](int index) const;
37-
double& operator[](int index);
36+
37+
float operator[](int index) const;
38+
float &operator[](int index);
3839

3940

4041
static Vector3f Min(const Vector3f &p1, const Vector3f &p2) {
@@ -47,10 +48,16 @@ class Vector3f {
4748
std::max(p1.z, p2.z));
4849
}
4950
};
50-
inline double Vector3f::operator[](int index) const {
51+
inline float Vector3f::operator[](int index) const
52+
{
5153
return (&x)[index];
5254
}
5355

56+
// 乐了,别光声明不写实现啊 GAMES,还有这个 用 double 返回 float 成员变量什么鬼。
57+
inline float &Vector3f::operator[](int index)
58+
{
59+
return (&x)[index];
60+
}
5461

5562
class Vector2f
5663
{

Frame/Source/Assignment/Assignment7/main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ int main(int argc, char** argv)
2424
green->Kd = Vector3f(0.14f, 0.45f, 0.091f);
2525
Material* white = new Material(DIFFUSE, Vector3f(0.0f));
2626
white->Kd = Vector3f(0.725f, 0.71f, 0.68f);
27-
Material* light = new Material(DIFFUSE, (8.0f * Vector3f(0.747f+0.058f, 0.747f+0.258f, 0.747f) + 15.6f * Vector3f(0.740f+0.287f,0.740f+0.160f,0.740f) + 18.4f *Vector3f(0.737f+0.642f,0.737f+0.159f,0.737f)));
27+
Material *light = new Material(DIFFUSE, (
28+
8.0f * Vector3f(0.747f + 0.058f, 0.747f + 0.258f, 0.747f) +
29+
15.6f * Vector3f(0.740f + 0.287f, 0.740f + 0.160f, 0.740f) +
30+
18.4f * Vector3f(0.737f + 0.642f, 0.737f + 0.159f, 0.737f)));
2831
light->Kd = Vector3f(0.65f);
2932

3033
MeshTriangle floor(Utils::PathFromAsset("model/cornellbox/floor.obj"), white);

0 commit comments

Comments
 (0)