@@ -47,10 +47,26 @@ Eigen::Matrix4f get_model_matrix(float angle)
47
47
return translate * rotation * scale;
48
48
}
49
49
50
- Eigen::Matrix4f get_projection_matrix (float eye_fov, float aspect_ratio, float zNear, float zFar)
50
+ Eigen::Matrix4f get_projection_matrix (float eye_fov, float aspect_ratio,
51
+ float zNear, float zFar)
51
52
{
52
- // TODO: Use the same projection matrix from the previous assignments
53
53
54
+ Eigen::Matrix4f projection = Eigen::Matrix4f::Identity ();
55
+
56
+ float fov_angle = eye_fov * M_PI / 180 ;
57
+
58
+ float n = -zNear;
59
+ float t = tan (fov_angle / 2 ) * zNear;
60
+ float b = -t;
61
+ float r = t * aspect_ratio;
62
+ float l = -r;
63
+ float f = -zFar;
64
+
65
+ projection << 2 * n /(r - l), 0 , (l + r)/(l - r) , 0 ,
66
+ 0 , 2 * n /(t-b), (b + r)/(b - t), 0 ,
67
+ 0 , 0 , (f + n)/(n - f), 2 * f * n / (f-n),
68
+ 0 , 0 ,1 , 0 ;
69
+ return projection;
54
70
}
55
71
56
72
Eigen::Vector3f vertex_shader (const vertex_shader_payload& payload)
@@ -84,6 +100,7 @@ Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
84
100
if (payload.texture )
85
101
{
86
102
// TODO: Get the texture value at the texture coordinates of the current fragment
103
+ return_color = payload.texture ->getColor (payload.tex_coords .x (), payload.tex_coords .y ());
87
104
88
105
}
89
106
Eigen::Vector3f texture_color;
@@ -102,7 +119,6 @@ Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
102
119
103
120
float p = 150 ;
104
121
105
- Eigen::Vector3f color = texture_color;
106
122
Eigen::Vector3f point = payload.view_pos ;
107
123
Eigen::Vector3f normal = payload.normal ;
108
124
@@ -113,6 +129,13 @@ Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
113
129
// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular*
114
130
// components are. Then, accumulate that result on the *result_color* object.
115
131
132
+ Eigen::Vector3f l = light.position - point;
133
+ Eigen::Vector3f v = eye_pos - point;
134
+ Eigen::Vector3f h = (l.normalized () + v.normalized ()).normalized ();
135
+ Vector3f diffuse = kd.cwiseProduct (light.intensity / (l.dot (l)) * std::max (0 .0f , (normal .normalized ().dot (l.normalized ()))));
136
+ Vector3f specular = ks.cwiseProduct (light.intensity / (l.dot (l)) * pow (std::max (0 .0f , normal .normalized ().dot (h)), p));
137
+ Vector3f ambient = ka.cwiseProduct (amb_light_intensity);
138
+ result_color += diffuse + specular + ambient;
116
139
}
117
140
118
141
return result_color * 255 .f ;
@@ -133,25 +156,31 @@ Eigen::Vector3f phong_fragment_shader(const fragment_shader_payload& payload)
133
156
134
157
float p = 150 ;
135
158
136
- Eigen::Vector3f color = payload.color ;
137
159
Eigen::Vector3f point = payload.view_pos ;
138
160
Eigen::Vector3f normal = payload.normal ;
139
161
140
162
Eigen::Vector3f result_color = {0 , 0 , 0 };
163
+
141
164
for (auto & light : lights)
142
165
{
143
166
// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular*
144
167
// components are. Then, accumulate that result on the *result_color* object.
145
168
169
+ Eigen::Vector3f l = light.position - point;
170
+ Eigen::Vector3f v = eye_pos - point;
171
+ Eigen::Vector3f h = (l.normalized () + v.normalized ()).normalized ();
172
+ Vector3f ambient = ka.cwiseProduct (amb_light_intensity);
173
+ Vector3f diffuse = kd.cwiseProduct (light.intensity / (l.dot (l)) * std::max (0 .0f , (normal .dot (l.normalized ()))));
174
+ Vector3f specular = ks.cwiseProduct (light.intensity / (l.dot (l)) * pow (std::max (0 .0f , normal .dot (h)), p));
175
+ result_color += ambient + diffuse + specular;
146
176
}
147
177
148
178
return result_color * 255 .f ;
149
179
}
150
180
151
181
152
-
153
- Eigen::Vector3f displacement_fragment_shader (const fragment_shader_payload& payload)
154
- {
182
+ Eigen::Vector3f displacement_fragment_shader (const fragment_shader_payload& payload)
183
+ {
155
184
156
185
Eigen::Vector3f ka = Eigen::Vector3f (0.005 , 0.005 , 0.005 );
157
186
Eigen::Vector3f kd = payload.color ;
@@ -171,17 +200,29 @@ Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payl
171
200
Eigen::Vector3f normal = payload.normal ;
172
201
173
202
float kh = 0.2 , kn = 0.1 ;
174
-
175
- // TODO: Implement displacement mapping here
176
- // Let n = normal = (x, y, z)
177
- // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
178
- // Vector b = n cross product t
179
- // Matrix TBN = [t b n]
180
- // dU = kh * kn * (h(u+1/w,v)-h(u,v))
181
- // dV = kh * kn * (h(u,v+1/h)-h(u,v))
182
- // Vector ln = (-dU, -dV, 1)
183
- // Position p = p + kn * n * h(u,v)
184
- // Normal n = normalize(TBN * ln)
203
+ float x = normal .x ();
204
+ float y = normal .y ();
205
+ float z = normal .z ();
206
+ Eigen::Vector3f t;
207
+ t << x*y/sqrt (x*x+z*z), sqrt (x*x+z*z), z*y/sqrt (x*x+z*z);
208
+ Eigen::Vector3f b = normal .cross (t);
209
+ Eigen::Matrix3f TBN;
210
+ TBN << t, b, normal ;
211
+
212
+ float u, v, w, h;
213
+ u = payload.tex_coords .x ();
214
+ v = payload.tex_coords .y ();
215
+ w = payload.texture ->width ;
216
+ h = payload.texture ->height ;
217
+
218
+ float dU = kh * kn * (payload.texture ->getColor (u + 1.0 / w,v).norm () - payload.texture ->getColor (u,v).norm ());
219
+ float dV = kh * kn * (payload.texture ->getColor (u,v + 1.0 / h).norm () - payload.texture ->getColor (u,v).norm ());
220
+
221
+ Vector3f ln;
222
+ ln << -dU, dV, 1 ;
223
+
224
+ point += kn * normal * payload.texture ->getColor (u,v).norm ();// 这一步就是区分displacement与bump的关键,位移
225
+ normal = (TBN * ln).normalized ();
185
226
186
227
187
228
Eigen::Vector3f result_color = {0 , 0 , 0 };
@@ -190,10 +231,17 @@ Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payl
190
231
{
191
232
// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular*
192
233
// components are. Then, accumulate that result on the *result_color* object.
193
-
194
-
234
+
235
+ Eigen::Vector3f l = light.position - point;
236
+ Eigen::Vector3f v = eye_pos - point;
237
+ Eigen::Vector3f h = (l.normalized () + v.normalized ()).normalized ();
238
+ Vector3f ambient = ka.cwiseProduct (amb_light_intensity);
239
+ Vector3f diffuse = kd.cwiseProduct (light.intensity / (l.dot (l)) * std::max (0 .0f , (normal .dot (l.normalized ()))));
240
+ Vector3f specular = ks.cwiseProduct (light.intensity / (l.dot (l)) * pow (std::max (0 .0f , normal .dot (h)), p));
241
+ result_color += ambient + diffuse + specular;
195
242
}
196
243
244
+
197
245
return result_color * 255 .f ;
198
246
}
199
247
@@ -231,6 +279,28 @@ Eigen::Vector3f bump_fragment_shader(const fragment_shader_payload& payload)
231
279
// Vector ln = (-dU, -dV, 1)
232
280
// Normal n = normalize(TBN * ln)
233
281
282
+ float x = normal .x ();
283
+ float y = normal .y ();
284
+ float z = normal .z ();
285
+ Eigen::Vector3f t;
286
+ t << x*y/sqrt (x*x+z*z), sqrt (x*x+z*z), z*y/sqrt (x*x+z*z);
287
+ Eigen::Vector3f b = normal .cross (t);
288
+ Eigen::Matrix3f TBN;
289
+ TBN << t, b, normal ;
290
+
291
+ float u, v, w, h;
292
+ u = payload.tex_coords .x ();
293
+ v = payload.tex_coords .y ();
294
+ w = payload.texture ->width ;
295
+ h = payload.texture ->height ;
296
+
297
+ float dU = kh * kn * (payload.texture ->getColorBilinear (u + 1.0 / w,v).norm () - payload.texture ->getColorBilinear (u,v).norm ());
298
+ float dV = kh * kn * (payload.texture ->getColorBilinear (u,v + 1.0 / h).norm () - payload.texture ->getColorBilinear (u,v).norm ());
299
+
300
+ Vector3f ln;
301
+ ln << -dU, dV, 1 ;
302
+
303
+ normal = (TBN * ln).normalized ();
234
304
235
305
Eigen::Vector3f result_color = {0 , 0 , 0 };
236
306
result_color = normal ;
0 commit comments