在Fundamentals of Computer Graphics, 4th 的第153頁有如下描述:
Many APIs such as OpenGL (Shreiner, Neider, Woo, & Davis, 2004) use the same canonical view volume as presented here. They also usually have the user specify the absolute values of n and f . The projection matrix for OpenGL is
Other APIs send n and f to 0 and 1, respectively. Blinn (J. Blinn, 1996) recom- mends making the canonical view volume $[0, 1]^3$ for efficiency. All such decisions will change the the projection matrix slightly.
//Screen space rasterizationvoid rst::rasterizer::rasterize_triangle(constTriangle& t) {auto v =t.toVector4(); // TODO : Find out the bounding box of current triangle. // iterate through the pixel and find if the current pixel is inside the triangle // If so, use the following code to get the interpolated z value. //auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v); //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w()); //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w(); //z_interpolated *= w_reciprocal; // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
}
先找到包圍盒子bounding box
在bounding box中檢測像素是否在三角形內
如果在,則
用重心座標插值得到当前三角形像素的z值
判斷z值与depth buffer的关系
z<depth buffer
設置當前像素顏色
//Screen space rasterizationvoid rst::rasterizer::rasterize_triangle(constTriangle& t) {auto v =t.toVector4(); // TODO : Find out the bounding box of current triangle. // iterate through the pixel and find if the current pixel is inside the triangle // If so, use the following code to get the interpolated z value. //auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v); //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w()); //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w(); //z_interpolated *= w_reciprocal; // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
// Finding out the bounding box for the current trianglefloat min_x =ceil(std::min({v[0].x(),v[1].x(),v[2].x()}));float max_x =ceil(std::max({v[0].x(),v[1].x(),v[2].x()}));float min_y =ceil(std::min({v[0].y(),v[1].y(),v[2].y()}));float max_y =ceil(std::max({v[0].y(),v[1].y(),v[2].y()})); // Iterating through each pixel in the bounding boxfor (float x = min_x; x <= max_x; x++) {for (float y = min_y; y <= max_y; y++) { // If the pixel is inside the triangleif (insideTriangle(x+0.5f, y+0.5f,t.v)) {auto[alpha, beta, gamma] =computeBarycentric2D(x, y,t.v);float w_reciprocal =1.0/(alpha /v[0].w() + beta /v[1].w() + gamma /v[2].w()); float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
z_interpolated *= w_reciprocal;if (z_interpolated <depth_buf[get_index(x, y)]) { // Set the pixel color if it should be paintedset_pixel(Eigen::Vector3f(x, y, z_interpolated),t.getColor());depth_buf[get_index(x, y)] = z_interpolated; } } } }}
//Screen space rasterizationvoid rst::rasterizer::rasterize_triangle(constTriangle& t) {auto v =t.toVector4(); // TODO : Find out the bounding box of current triangle. // iterate through the pixel and find if the current pixel is inside the triangle // If so, use the following code to get the interpolated z value. //auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v); //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w()); //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w(); //z_interpolated *= w_reciprocal; // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
// Finding out the bounding box for the current triangle// float min_x = std::min({v[0].x(), v[1].x(), v[2].x()});// float max_x = std::max({v[0].x(), v[1].x(), v[2].x()});// float min_y = std::min({v[0].y(), v[1].y(), v[2].y()});// float max_y = std::max({v[0].y(), v[1].y(), v[2].y()});float min_x = std::floor(std::min({v[0].x(),v[1].x(),v[2].x()}));float max_x = std::ceil(std::max({v[0].x(),v[1].x(),v[2].x()}));float min_y = std::floor(std::min({v[0].y(),v[1].y(),v[2].y()}));float max_y = std::ceil(std::max({v[0].y(),v[1].y(),v[2].y()}));bool ssaa_mode =true;if(ssaa_mode){ // Iterating through each pixel in the bounding boxfor (float x = min_x; x <= max_x; x++) {for (float y = min_y; y <= max_y; y++) {float min_depth = std::numeric_limits<float>::infinity(); Eigen::Vector3f color(0,0,0); // Super Sampling at 2x2 grid within the pixelfor (int dx =0; dx <2; ++dx) {for (int dy =0; dy <2; ++dy) {float sample_x = x + dx *0.5f;float sample_y = y + dy *0.5f; // If the sample point is inside the triangleif (insideTriangle(sample_x, sample_y,t.v)) {auto[alpha, beta, gamma] =computeBarycentric2D(sample_x, sample_y,t.v);float w_reciprocal =1.0/(alpha /v[0].w() + beta /v[1].w() + gamma /v[2].w()); float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
z_interpolated *= w_reciprocal; // Accumulate color and find minimum depth color +=t.getColor(); min_depth = std::min(min_depth, z_interpolated); } } } color /=4.0f; // average the colorif (min_depth <depth_buf[get_index(x, y)]) { // Set the pixel color if it should be paintedset_pixel(Eigen::Vector3f(x, y, min_depth), color);depth_buf[get_index(x, y)] = min_depth; } } }return; }else{ // Iterating through each pixel in the bounding boxfor (float x = min_x; x <= max_x; x++) {for (float y = min_y; y <= max_y; y++) { // If the pixel is inside the triangleif (insideTriangle(x, y,t.v)) {auto [alpha, beta, gamma] =computeBarycentric2D(x, y,t.v);float w_reciprocal =1.0/ (alpha /v[0].w() + beta /v[1].w() + gamma /v[2].w());float z_interpolated = alpha *v[0].z() /v[0].w() + beta *v[1].z() /v[1].w() + gamma *v[2].z() /v[2].w(); z_interpolated *= w_reciprocal;if (z_interpolated <depth_buf[get_index(x, y)]) { // Set the pixel color if it should be paintedset_pixel(Eigen::Vector3f(x, y, z_interpolated),t.getColor());depth_buf[get_index(x, y)] = z_interpolated; } } } } }}