-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSceneHeteroObject.cpp
138 lines (121 loc) · 3.8 KB
/
SceneHeteroObject.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "StdAfx.h"
#include "SceneHeteroObject.h"
#include <fstream>
#include <assert.h>
void SceneHeteroObject::parseDensityFile(const std::string &filename){
std::ifstream fin(filename.c_str());
fin >> nx >> ny >> nz;
stepSize = 0.05;
offSet = 0.00001;
// TODO: parse the density file according to pbrt.
}
float SceneHeteroObject::getDensity(const vec3f &pos) const{
// TODO: add code handling parsed density file, interpolation.
return 1.0;
}
vec3f SceneHeteroObject::sigma_a(const vec3f &pos) const{
return getDensity(pos) * (da);
}
vec3f SceneHeteroObject::sigma_s(const vec3f &pos) const{
return getDensity(pos) * (ds);
}
vec3f SceneHeteroObject::sigma_t(const vec3f &pos) const{
return getDensity(pos) * (dt);
}
float SceneHeteroObject::sampleDistance(const vec3f &pos, const vec3f &dir) const{
float theta_t = y(dt);
float t = -log(RandGenerator::genFloat()) / theta_t;
while(y(sigma_t(pos + dir * t)) / theta_t < RandGenerator::genFloat()){
t -= log(RandGenerator::genFloat()) / theta_t;
}
return t;
}
vec3f SceneHeteroObject::rayMarchingPdf(const vec3f &p0, const vec3f &p1, vec3f &averDt) const{
vec3f direction = p1 - p0;
float length = direction.length();
if (length == 0.f) return 0.f;
direction.normalize();
float t = offSet;
vec3f kernelPdf(0.,0.,0.);
vec3f kernelDt(0.,0.,0.);
int spp = 0;
while(t < length){
vec3f Dt = sigma_t(p0 + direction * t);
kernelPdf += Dt * exp(-y(Dt) * t);
kernelDt += Dt;
t += stepSize;
spp++;
}
assert(spp);
averDt = kernelDt / spp;
return kernelPdf * stepSize;
}
Ray SceneHeteroObject::scatter(Ray& inRay, float dist, unsigned triangleID, bool forward, SceneObject* intersectObject) const
{
Ray outRay;
if(forward) return outRay;
vec3f position = inRay.origin + inRay.direction*dist;
LocalFrame lf = getAutoGenWorldLocalFrame(triangleID, position);
if(intersectObject == this && inRay.direction.dot(lf.n) < 0)
{
outRay = inRay;
outRay.origin = position;
outRay.insideObject = (SceneObject*)this;
outRay.contactObject = outRay.insideObject;
return outRay;
}
outRay = inRay;
float bounce_dist = sampleDistance(position, inRay.direction);
bool hit = bounce_dist > dist;
outRay.color = vec3f(1,1,1);
outRay.directionProb = 1.0;
outRay.insideObject = NULL;
outRay.contactObject = NULL;
if(hit){
// hit a surface or volume bound
vec3f averDt;
vec3f P_surf = P_surface(inRay.origin, inRay.origin + inRay.direction * dist, averDt);
outRay.color = vec3f(1,1,1);
outRay.origin = inRay.origin + inRay.direction * dist;
outRay.direction = inRay.direction;
outRay.directionProb *= y(P_surf);
if(this == intersectObject)
{
outRay.insideObject = scene->findInsideObject(outRay, (SceneObject*)this);
outRay.contactObject = NULL;
}
else
{
outRay.insideObject = (SceneObject*)this;
outRay.contactObject = intersectObject;
}
}
else{
// simple travel in volume media
// travel straight forward
outRay.color = vec3f(1, 1, 1);
vec3f averDt;
outRay.directionProb = y(p_medium(inRay.origin, inRay.origin + inRay.direction * bounce_dist, averDt));
outRay.insideObject = (SceneObject*)this;
outRay.contactObject = NULL;
outRay.origin = inRay.origin + inRay.direction * bounce_dist;
float albedo = y(ds) / y(dt);
float rander = RandGenerator::genFloat();
if(rander < albedo){
// scattering
outRay.direction = vec3f(1,1,1);//RandGenerator::getHGDirection(-0.5, RandGenerator::genFloat(), RandGenerator::genFloat());
vec3f phase_f = this->bsdf->evaluate(LocalFrame(), -outRay.direction, -inRay.direction);
outRay.color *= phase_f;
outRay.directionProb *= albedo * 1.0 / (4 * M_PI);
}
else{
// terminate
outRay.direction = vec3f(0, 0, 0);
outRay.color = vec3f(0, 0, 0);
outRay.directionProb = 1;
outRay.insideObject = NULL;
outRay.contactObject = NULL;
}
}
return outRay;
}