-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPointLighter.cpp
More file actions
121 lines (104 loc) · 3.45 KB
/
PointLighter.cpp
File metadata and controls
121 lines (104 loc) · 3.45 KB
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
#include "PointLighter.hpp"
#include "lerp.hpp"
void PointLighter::calculateAmbientLight(std::vector<Point4D>& points, const Color& ambientColor)
{
auto colorChannels = ambientColor.getNormalizedColorChannels();
auto ambientRed = std::get<0>(colorChannels);
auto ambientGreen = std::get<1>(colorChannels);
auto ambientBlue = std::get<2>(colorChannels);
for (auto& point : points)
{
auto pointColorChannels = point.color.getNormalizedColorChannels();
auto pointRed = std::get<0>(pointColorChannels);
auto pointGreen = std::get<1>(pointColorChannels);
auto pointBlue = std::get<2>(pointColorChannels);
auto newColor = Color::getDenormalizedColor(ambientRed * pointRed, ambientGreen * pointGreen, ambientBlue * pointBlue);
point.color = newColor;
}
}
inline
double fatt(double A, double B, double d)
{
return 1 / (std::fma(B, d, A));
}
inline
double distance(const Point4D& l, const Point4D& p)
{
return std::sqrt(std::pow(l.x - p.x, 2) + std::pow(l.y - p.y, 2) + std::pow(l.z - p.z, 2));
}
inline
Point4D reflect(const Point4D& l, const Point4D& n)
{
return l - n * 2 * dot(l, n);
}
Color PointLighter::calculateLightAtPixel(const Point4D& p, const Point4D& vN, const Light& l, double ks, double kp)
{
auto pl = Point4D{ l.Location[0], l.Location[1], l.Location[2], l.Location[3] };
auto vl = normalize(pl - p);
auto vr = reflect(vl, vN);
auto dotNL = dot(vN, vl);
if (dotNL < 0)
{
dotNL = 0;
}
auto dotPR = dot(normalize(p), vr);
if (dotPR < 0)
{
dotPR = 0;
}
auto lightColor = l.color * fatt(l.A, l.B, distance(pl, p)) * (p.color * dotNL + ks * std::pow(dotPR, kp));
return lightColor;
}
Color PointLighter::calculateLights(Point4D & p, std::vector<Light> & lights, double ks, double kp)
{
auto vN = normalize(p.normal.value());
Color c{ 0.0 };
for (auto& l : lights)
{
c = c + calculateLightAtPixel(p, vN, l, ks, kp);
}
return c;
}
void PointLighter::calculateLighting(std::vector<Point4D>& points, const Color & ambientColor, std::vector<Light>& lights, double ks, double kp)
{
Color pointColor{ 255, 255, 255 };
auto ambientTerm = pointColor * ambientColor;
for (auto& p : points)
{
p.color = ambientTerm + calculateLights(p, lights, ks, kp);
}
}
void PointLighter::calculateDepthShading(std::vector<Point4D>& points, const Depth & depth)
{
auto zLerp = Lerp<double>(depth.near, depth.far, 0.0, 1.0);
for (auto& point : points)
{
if (point.z > depth.far)
{
point.color = depth.color;
}
else if (point.z > depth.near)
{
auto depthColorFactor = zLerp[static_cast<int>(point.z - depth.near)].second;
auto depthColorChannels = depth.color.getNormalizedColorChannels();
auto pointColorChannels = point.color.getNormalizedColorChannels();
auto newRed = ((1 - depthColorFactor) * std::get<0>(pointColorChannels)) + (depthColorFactor * std::get<0>(depthColorChannels));
auto newGreen = ((1 - depthColorFactor) * std::get<1>(pointColorChannels)) + (depthColorFactor * std::get<1>(depthColorChannels));
auto newBlue = ((1 - depthColorFactor) * std::get<2>(pointColorChannels)) + (depthColorFactor * std::get<2>(depthColorChannels));
point.color = Color::getDenormalizedColor(newRed, newGreen, newBlue);
}
}
}
//for (auto& point : points)
//{
// if (point.z > depth.far)
// {
// point.color = depth.color;
// }
// else if (point.z > depth.near)
// {
// auto factor = (point.z - depth.near) / (depth.far - depth.near);
// auto newColor = point.color * factor + (1 - factor) * depth.color;
// point.color = newColor;
// }
//}