//Screen space rasterization void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) { // TODO: From your HW3, get the triangle rasterization code. // TODO: Inside your rasterization loop: // * v[i].w() is the vertex view space depth value z. // * Z is interpolated view space depth for the current pixel // * zp is depth between zNear and zFar, used for z-buffer
auto v = t.toVector4(); // get bounding box of current triangle std::vector<float> vec_x{ v[0].x(), v[1].x(), v[2].x() }; std::vector<float> vec_y{ v[0].y(), v[1].y(), v[2].y() }; std::sort(vec_x.begin(), vec_x.end()); std::sort(vec_y.begin(), vec_y.end());
int min_x = std::floor(vec_x[0]), max_x = std::ceil(vec_x[2]); int min_y = std::floor(vec_y[0]), max_y = std::ceil(vec_y[2]);
for (int x = min_x; x <= max_x; x++) { for (int y = min_y; y <= max_y; y++) { if (insideTriangle(x + 0.5f, y + 0.5f, t.v)) { auto [alpha, beta, gamma] = computeBarycentric2D(x + 0.5f, y + 0.5f, t.v); float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w()); float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w(); zp *= Z;
Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload) { Eigen::Vector3f return_color = { 0, 0, 0 }; if (payload.texture) { // TODO: Get the texture value at the texture coordinates of the current fragment // use Bilinear interpolation return_color = payload.texture->getColorBilinear(payload.tex_coords.x(), payload.tex_coords.y()); } Eigen::Vector3f texture_color; texture_color << return_color.x(), return_color.y(), return_color.z();
Eigen::Vector3f color = payload.color; Eigen::Vector3f point = payload.view_pos; Eigen::Vector3f normal = payload.normal;
float kh = 0.2, kn = 0.1;
// TODO: Implement bump mapping here // Let n = normal = (x, y, z) // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z)) // Vector b = n cross product t // Matrix TBN = [t b n] // dU = kh * kn * (h(u+1/w,v)-h(u,v)) // dV = kh * kn * (h(u,v+1/h)-h(u,v)) // Vector ln = (-dU, -dV, 1) // Normal n = normalize(TBN * ln)
float x = normal.x(), y = normal.y(), z = normal.z(); Vector3f t(x * y / sqrt(x * x + z * z), sqrt(x * x + z * z), z * y / sqrt(x * x + z * z)); Vector3f b = normal.cross(t); Matrix3f TBN; TBN << t.x(), b.x(), normal.x(), t.y(), b.y(), normal.y(), t.z(), b.z(), normal.z();
float u = payload.tex_coords.x(); float v = payload.tex_coords.y(); float w = payload.texture->width; float h = payload.texture->height;
Eigen::Vector3f color = payload.color; Eigen::Vector3f point = payload.view_pos; Eigen::Vector3f normal = payload.normal;
float kh = 0.2, kn = 0.1;
// TODO: Implement displacement mapping here // Let n = normal = (x, y, z) // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z)) // Vector b = n cross product t // Matrix TBN = [t b n] // dU = kh * kn * (h(u+1/w,v)-h(u,v)) // dV = kh * kn * (h(u,v+1/h)-h(u,v)) // Vector ln = (-dU, -dV, 1) // Position p = p + kn * n * h(u,v) // Normal n = normalize(TBN * ln) float x = normal.x(); float y = normal.y(); float z = normal.z();
Vector3f t(x * y / sqrt(x * x + z * z), sqrt(x * x + z * z), z * y / sqrt(x * x + z * z)); Vector3f b = normal.cross(t); Matrix3f TBN; TBN << t.x(), b.x(), normal.x(), t.y(), b.y(), normal.y(), t.z(), b.z(), normal.z();
float u = payload.tex_coords.x(); float v = payload.tex_coords.y(); float w = payload.texture->width; float h = payload.texture->height;
float dU = kh * kn * (payload.texture->getColor(u + 1 / w, v).norm() - payload.texture->getColor(u, v).norm()); float dV = kh * kn * (payload.texture->getColor(u, v + 1 / h).norm() - payload.texture->getColor(u, v).norm()); Vector3f ln(-dU, -dV, 1.0f); point += (kn * normal * payload.texture->getColor(u, v).norm()); normal = (TBN * ln).normalized();
Eigen::Vector3f result_color = { 0, 0, 0 };
Vector3f view_vector = (eye_pos - point).normalized(); for (auto& light : lights) { // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* // components are. Then, accumulate that result on the *result_color* object.
// get color at u00, u01, u10, u11 auto u00 = image_data.at<cv::Vec3b>(v_max, u_min); auto u01 = image_data.at<cv::Vec3b>(v_min, u_min); auto u10 = image_data.at<cv::Vec3b>(v_max, u_max); auto u11 = image_data.at<cv::Vec3b>(v_min, u_max);
float s = (u_img - u_min) / (u_max - u_min); // range [0, 1] float t = (v_img - v_min) / (v_max - v_min);
auto lerp = [](float x, cv::Vec3b v0, cv::Vec3b v1) { return v0 + x * (v1 - v0); };
auto u0 = lerp(s, u00, u10); auto u1 = lerp(s, u01, u11);
auto color = lerp(t, u1, u0); return Eigen::Vector3f(color[0], color[1], color[2]); }