-
Notifications
You must be signed in to change notification settings - Fork 0
/
Camera.cpp
134 lines (116 loc) · 3.55 KB
/
Camera.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
#include "StdAfx.h"
#include "Camera.h"
Ray Camera::generateRay(unsigned pixelID , bool flag) const
{
vec3f front = focus - position;
front.normalize();
vec3f right = front.cross(up);
right.normalize();
vec3f orthoUp = right.cross(front);
Ray ray;
int x = pixelID % width;
int y = pixelID / width;
float u = RandGenerator::genFloat();
float v = RandGenerator::genFloat();
float xc = x + 0.5 - (width/2.0);
float yc = (height/2.0) - 0.5 - y;
ray.direction = front*sightDist + right * (x + u - (width/2.0)) + orthoUp * ((height/2.0) - v - y);
ray.direction.normalize();
ray.color = vec3f(1, 1, 1);
ray.origin = position;
ray.contactObject = (SceneObject*)this;
if(!scene->usingGPU() || flag)
{
Scene::ObjSourceInformation osi;
ray.intersectDist = scene->intersect(ray, osi);
ray.intersectObjectTriangleID = osi.triangleID;
ray.intersectObject = (ray.intersectDist >= 0) ? scene->objects[osi.objID] : NULL;
}
ray.insideObject = scene->findInsideObject(ray);
float dist = sqrt(xc*xc+yc*yc+sightDist*sightDist);
//ray.directionProb = powf(dist, 3) / sightDist;
ray.directionProb = 1.f;
ray.directionSampleType = Ray::RANDOM;
ray.originSampleType = Ray::DEFINITE;
ray.pixelID = pixelID;
//if (x == 42 && y == 233)
// printf("pixel=(%d,%d), dir=(%.3f,%.3f,%.3f)\n" , x , y , ray.direction.x , ray.direction.y , ray.direction.z);
return ray;
}
float Camera::get_dw(unsigned pixelID) const
{
int x = pixelID % width;
int y = pixelID / width;
float xc = x + 0.5 - (width/2.0);
float yc = (height/2.0) - 0.5 - y;
float dist = sqrt(xc*xc+yc*yc+sightDist*sightDist);
return sightDist / powf(dist, 3);
}
vec3f Camera::eliminateVignetting(const vec3f& color, unsigned pixelID) const
{
vec3f front = focus - position;
front.normalize();
vec3f right = front.cross(up);
right.normalize();
vec3f orthoUp = right.cross(front);
Ray ray;
int x = pixelID % width;
int y = pixelID / width;
float xc = x + 0.5 - (width/2.0);
float yc = (height/2.0) - 0.5 - y;
vec3f dir = front*sightDist + right * (x + 0.5 - (width/2.0)) + orthoUp * ((height/2.0) - 0.5 - y);
dir.normalize();
//return color / powf(dir.dot(front), 4);
return color / abs(dir.dot(front));
}
float Camera::getDirectionSampleProbDensity(const Ray& inRay, const Ray& outRay) const
{
int x = outRay.pixelID % width;
int y = outRay.pixelID / width;
float xc = x + 0.5 - (width/2.0);
float yc = (height/2.0) - 0.5 - y;
float dist = sqrt(xc*xc+yc*yc+sightDist*sightDist);
//return powf(dist, 3) / sightDist;
return 1.f;
}
vec3f Camera::getWorldNormal(unsigned fi, const vec3f& position, bool flat) const
{
vec3f front = focus - position;
front.normalize();
return front;
}
vector<vec3f> Camera::generateRays() const
{
vector<vec3f> rays(width*height);
vec3f front = focus - position;
front.normalize();
vec3f right = front.cross(up);
right.normalize();
vec3f orthoUp = right.cross(front);
for(unsigned y=0; y<height; y++)
{
for(unsigned x=0; x<width; x++)
{
rays[y*width+x] = front*sightDist + right * (x + 0.5 - (width/2.0)) + orthoUp * ((height/2.0) - 0.5 - y);
rays[y*width+x].normalize();
}
}
return rays;
}
vec2<float> Camera::transToPixel(const vec3f& point) const
{
vec2<float> pixel;
vec3f v = point - position;
vec3f front = focus - position;
front.normalize();
vec3f right = front.cross(up);
right.normalize();
vec3f orthoUp = right.cross(front);
float frontDist = v.dot(front);
float ratio = sightDist / frontDist;
pixel.x = v.dot(right) * ratio;
pixel.y = v.dot(orthoUp) * ratio;
pixel.x += width/2.f - 0.5f;
pixel.y = height/2.f - pixel.y - 0.5f;
return pixel;
}