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
|
Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payload) { auto Limit_Number = [](float &number){ number = max(number, (float)0.0); number = min(number, (float)1.0); };
auto func_h = [&payload, Limit_Number](float u, float v) -> auto { Limit_Number(u); Limit_Number(v); return payload.texture->getColor(u, v).norm(); }; 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; float x = n.x(), y = n.y(), z = n.z();
Eigen::Vector3f t(x*y / sqrt(x*x + z*z), sqrt(x*x + z*z), z*y / sqrt(x*x + z*z)); Eigen::Vector3f b = n.cross(t);
Eigen::Matrix3f TBN; TBN << t.x(), b.x(), n.x(), t.y(), b.y(), n.y(), t.z(), b.z(), n.z();
float u = payload.tex_coords.x(), v = payload.tex_coords.y(); float w = payload.texture->width, h = payload.texture->height;
float dU = kh * kn * (func_h(u+1/w, v) - func_h(u,v)); float dV = kh * kn * (func_h(u, v+1/h) - func_h(u,v));
Eigen::Vector3f ln(-dU, -dV, 1.0f); ln.normalize();
normal = (TBN * ln).normalized();
point = point + kn * n * (payload.texture->getColor(u,v).norm());
Eigen::Vector3f result_color = {0, 0, 0};
Eigen::Vector3f ambient={0,0,0}; Eigen::Vector3f diffuse={0,0,0}; Eigen::Vector3f specular={0,0,0}; for (auto& light : lights) { float r_squared = (light.position - point).squaredNorm(); diffuse = kd.cwiseProduct(light.intensity / r_squared) * MAX(0, normal.dot(((light.position - point).normalized())));
auto h = ((light.position - point).normalized() + (eye_pos - point).normalized()).normalized(); specular = ks.cwiseProduct(light.intensity / r_squared) * std::pow(std::max(0.0f, normal.dot(h)), p); ambient = ka.cwiseProduct(amb_light_intensity); result_color += ambient + diffuse + specular; }
return result_color * 255.f; }
|