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
| Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payload) { Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005); Eigen::Vector3f kd = payload.color; Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);
auto l1 = light{{20, 20, 20}, {500, 500, 500}}; auto l2 = light{{-20, 20, 0}, {500, 500, 500}};
std::vector<light> lights = {l1, l2}; Eigen::Vector3f amb_light_intensity{10, 10, 10}; Eigen::Vector3f eye_pos{0, 0, 10};
float p = 150;
Eigen::Vector3f color = payload.color; Eigen::Vector3f point = payload.view_pos; Eigen::Vector3f normal = payload.normal;
float kh = 0.2, kn = 0.1;
Eigen::Vector3f n = normal; Eigen::Vector3f t; t << n.x()*n.y()/std::sqrt(n.x()*n.x()+n.z()*n.z()), std::sqrt(n.x()*n.x()+n.z()*n.z()), n.z()*n.y()/std::sqrt(n.x()*n.x()+n.z()*n.z()); Eigen::Vector3f b = n.cross(t); Eigen::Matrix3f TBN; TBN << t, b, n;
float u = payload.tex_coords(0), v = payload.tex_coords(1); float w = payload.texture->width; float h = payload.texture->height; float dU = kh * kn * ( payload.texture->getColor(u+1.0f/w, v).norm() - payload.texture->getColor(u, v).norm() ); float dV = kh * kn * ( payload.texture->getColor(u+1, v+1.0f/h).norm() - payload.texture->getColor(u, v).norm() ); Eigen::Vector3f ln = {-dU, -dV, 1.0f}; point += kn * n * payload.texture->getColor(u, v).norm(); normal = (TBN * ln).normalized();
Eigen::Vector3f result_color = {0, 0, 0};
for (auto& light : lights) {
auto light_vec = light.position - point; auto view_vec = eye_pos - point; auto radius2 = light_vec.dot(light_vec); auto light_vec_norm = light_vec.normalized(); auto view_vec_norm = view_vec.normalized();
result_color += ka.cwiseProduct(amb_light_intensity); result_color += kd.cwiseProduct(light.intensity) / radius2 * std::max(0.0f, light_vec_norm.dot(normal)); auto h_vec = (light_vec_norm + view_vec_norm).normalized(); result_color += ks.cwiseProduct(light.intensity) / radius2 * std::pow(std::max(0.0f, h_vec.dot(normal)), p); }
return result_color * 255.f; }
|