单位网站建设情况总结,seo包年优化平台,php商城网站建设多少钱,凯里建设局网站目录 普通作业#xff1a;提高作业#xff1a;参考博客博客一博客二博客三 附代码框架的个人一些注释和理解#xff1a;rasterizer.cppTriangle.cpp 普通作业#xff1a;
// 判断点是否在三角形内的辅助函数
static bool insideTriangle(float x, float y, const Vector3f… 目录 普通作业提高作业参考博客博客一博客二博客三 附代码框架的个人一些注释和理解rasterizer.cppTriangle.cpp 普通作业
// 判断点是否在三角形内的辅助函数
static bool insideTriangle(float x, float y, const Vector3f* _v)
{//Vector3f* _v这个参数是一个Vector3f指针实际上代表的是一个数组。数组中的每个元素是一个Vector3f类型//也就是代表了一个顶点的坐标。每个点用_v[0]_v[1]_v[2]表示。而每个_v[0]就是一个Vector3f类型的点。// //整个数组代表了多个点。这里一般认为传入的是三个点即一个三角形。const Eigen::Vector2f P(x, y);// 提取x和yconst Eigen::Vector2f A _v[0].head(2), B _v[1].head(2), C _v[2].head(2);// 计算需求的向量const Eigen::Vector2f AP P - A;const Eigen::Vector2f BP P - B;const Eigen::Vector2f CP P - C;const Eigen::Vector2f AB B - A;const Eigen::Vector2f BC C - B;const Eigen::Vector2f CA A - C;//计算叉积float eq1 AB[0] * AP[1] - AB[1] * AP[0];float eq2 BC[0] * BP[1] - BC[1] * BP[0];float eq3 CA[0] * CP[1] - CA[1] * CP[0];//判断是否同向if (eq1 0 eq2 0 eq3 0)return true;else if (eq1 0 eq2 0 eq3 0)return true;elsereturn false;// TODO: 实现此函数检查点 (x, y) 是否在由 _v[0]、_v[1]、_v[2] 表示的三角形内
}
// 屏幕空间光栅化
void rst::rasterizer::rasterize_triangle(const Triangle t)
{auto v t.toVector4();int min_x INT_MAX;int max_x INT_MIN;int min_y INT_MAX;int max_y INT_MIN;//找出包围盒的边界for (auto point : v){if (point[0] min_x) min_x point[0];if (point[0] max_x) max_x point[0];if (point[1] min_y) min_y point[1];if (point[1] max_y) max_y point[1];}for (int y min_y; y max_y; y){for (int x min_x; x max_x; x){if (insideTriangle((float)x 0.5, (float)y 0.5, t.v)){// 如果是这样使用以下代码获取插值的 z 值。// auto [alpha, beta, gamma] computeBarycentric2D(x, y, t.v); C17以上的版本才可以用此句否则修改成下面的俩句float alpha, beta, gamma;std::tie(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)]){Eigen::Vector3f p { (float)x,(float)y, z_interpolated }; //当前坐标set_pixel(p, t.getColor());depth_buf[get_index(x, y)] z_interpolated; //更新z值}}}}// TODO: 找出当前三角形的边界框。// 遍历像素并查找当前像素是否在三角形内// 如果是这样使用以下代码获取插值的 z 值。// 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_pixel 函数为三角形的颜色使用 getColor 函数如果应该绘制的话。
}
提高作业
MSAA多重采样抗锯齿 这个算法很简单只要把判断像素中心点在不在三角形内改成判断像素块中的四个采样点在不在三角形内然后按点在三角形内的比例去改变颜色就行话不多说看代码更清楚
void rst::rasterizer::rasterize_triangle(const Triangle t) {auto v t.toVector4();int min_x INT_MAX;int max_x INT_MIN;int min_y INT_MAX;int max_y INT_MIN;for (auto point : v){if (point[0] min_x) min_x point[0];if (point[0] max_x) max_x point[0];if (point[1] min_y) min_y point[1];if (point[1] max_y) max_y point[1];}//MSAA:for (int y min_y; y max_y; y){for (int x min_x; x max_x; x){float fineness 0; //创建一个纯度值if (insideTriangle((float)x 0.25, (float)y 0.25, t.v)) fineness 0.25; //改为判断四个采样块的中心点在不在三角形内if (insideTriangle((float)x 0.25, (float)y 0.75, t.v)) fineness 0.25;if (insideTriangle((float)x 0.75, (float)y 0.25, t.v)) fineness 0.25;if (insideTriangle((float)x 0.75, (float)y 0.75, t.v)) fineness 0.25;if (fineness ! 0) {auto abg computeBarycentric2D((float)x 0.5, (float)y 0.5, t.v);float alpha std::get0(abg);float beta std::get1(abg);float gamma std::get2(abg);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)]){Eigen::Vector3f p { (float)x,(float)y, z_interpolated };set_pixel(p, fineness*t.getColor()); //将比例乘给颜色depth_buf[get_index(x, y)] z_interpolated;}}}}
}参考博客
博客一
博客二
博客三
附代码框架的个人一些注释和理解
rasterizer.cpp
// 防止代码格式化
//
// 由 goksu 于 4/6/19 创建#include algorithm
#include vector
#include rasterizer.h
#include opencv2/opencv.hpp
#include math.h// 将三维向量加载到顶点缓冲区的函数
rst::pos_buf_id rst::rasterizer::load_positions(const std::vectorEigen::Vector3f positions)
{auto id get_next_id();pos_buf.emplace(id, positions);return { id };
}// 将三维向量加载到索引缓冲区的函数
rst::ind_buf_id rst::rasterizer::load_indices(const std::vectorEigen::Vector3i indices)
{auto id get_next_id();ind_buf.emplace(id, indices);return { id };
}// 将三维向量加载到颜色缓冲区的函数
rst::col_buf_id rst::rasterizer::load_colors(const std::vectorEigen::Vector3f cols)
{auto id get_next_id();col_buf.emplace(id, cols);return { id };
}// 将三维向量转换为四维向量的辅助函数
auto to_vec4(const Eigen::Vector3f v3, float w 1.0f)
{return Vector4f(v3.x(), v3.y(), v3.z(), w);
}
//------------------补充——————————————————————————
// 判断点是否在三角形内的辅助函数
static bool insideTriangle(float x, float y, const Vector3f* _v)
{//Vector3f* _v这个参数是一个Vector3f指针实际上代表的是一个数组。数组中的每个元素是一个Vector3f类型//也就是代表了一个顶点的坐标。每个点用_v[0]_v[1]_v[2]表示。而每个_v[0]就是一个Vector3f类型的点。// //整个数组代表了多个点。这里一般认为传入的是三个点即一个三角形。const Eigen::Vector2f P(x, y);// 提取x和yconst Eigen::Vector2f A _v[0].head(2), B _v[1].head(2), C _v[2].head(2);// 计算需求的向量const Eigen::Vector2f AP P - A;const Eigen::Vector2f BP P - B;const Eigen::Vector2f CP P - C;const Eigen::Vector2f AB B - A;const Eigen::Vector2f BC C - B;const Eigen::Vector2f CA A - C;//计算叉积float eq1 AB[0] * AP[1] - AB[1] * AP[0];float eq2 BC[0] * BP[1] - BC[1] * BP[0];float eq3 CA[0] * CP[1] - CA[1] * CP[0];//判断是否同向if (eq1 0 eq2 0 eq3 0)return true;else if (eq1 0 eq2 0 eq3 0)return true;elsereturn false;// TODO: 实现此函数检查点 (x, y) 是否在由 _v[0]、_v[1]、_v[2] 表示的三角形内
}// 计算二维重心坐标的辅助函数
static std::tuplefloat, float, float computeBarycentric2D(float x, float y, const Vector3f* v)
{// 计算重心坐标float c1 (x * (v[1].y() - v[2].y()) (v[2].x() - v[1].x()) * y v[1].x() * v[2].y() - v[2].x() * v[1].y()) /(v[0].x() * (v[1].y() - v[2].y()) (v[2].x() - v[1].x()) * v[0].y() v[1].x() * v[2].y() - v[2].x() * v[1].y());float c2 (x * (v[2].y() - v[0].y()) (v[0].x() - v[2].x()) * y v[2].x() * v[0].y() - v[0].x() * v[2].y()) /(v[1].x() * (v[2].y() - v[0].y()) (v[0].x() - v[2].x()) * v[1].y() v[2].x() * v[0].y() - v[0].x() * v[2].y());float c3 (x * (v[0].y() - v[1].y()) (v[1].x() - v[0].x()) * y v[0].x() * v[1].y() - v[1].x() * v[0].y()) /(v[2].x() * (v[0].y() - v[1].y()) (v[1].x() - v[0].x()) * v[2].y() v[0].x() * v[1].y() - v[1].x() * v[0].y());return { c1, c2, c3 };
}// 绘制函数根据指定类型绘制三角形
void rst::rasterizer::draw(pos_buf_id pos_buffer, ind_buf_id ind_buffer, col_buf_id col_buffer, Primitive type)
{auto buf pos_buf[pos_buffer.pos_id];auto ind ind_buf[ind_buffer.ind_id];auto col col_buf[col_buffer.col_id];// 计算透视变换的范围float f1 (50 - 0.1) / 2.0;float f2 (50 0.1) / 2.0;Eigen::Matrix4f mvp projection * view * model;for (auto i : ind){Triangle t;Eigen::Vector4f v[] {mvp * to_vec4(buf[i[0]], 1.0f),mvp * to_vec4(buf[i[1]], 1.0f),mvp * to_vec4(buf[i[2]], 1.0f)};// 齐次除法for (auto vec : v){vec / vec.w();}// 视口变换for (auto vert : v){vert.x() 0.5 * width * (vert.x() 1.0);vert.y() 0.5 * height * (vert.y() 1.0);vert.z() vert.z() * f1 f2;}for (int i 0; i 3; i){t.setVertex(i, v[i].head3());t.setVertex(i, v[i].head3());t.setVertex(i, v[i].head3());}auto col_x col[i[0]];auto col_y col[i[1]];auto col_z col[i[2]];t.setColor(0, col_x[0], col_x[1], col_x[2]);t.setColor(1, col_y[0], col_y[1], col_y[2]);t.setColor(2, col_z[0], col_z[1], col_z[2]);rasterize_triangle(t);}
}//------------------补充——————————————————————————
// 屏幕空间光栅化
void rst::rasterizer::rasterize_triangle(const Triangle t)
{auto v t.toVector4();int min_x INT_MAX;int max_x INT_MIN;int min_y INT_MAX;int max_y INT_MIN;//找出包围盒的边界for (auto point : v){if (point[0] min_x) min_x point[0];if (point[0] max_x) max_x point[0];if (point[1] min_y) min_y point[1];if (point[1] max_y) max_y point[1];}for (int y min_y; y max_y; y){for (int x min_x; x max_x; x){if (insideTriangle((float)x 0.5, (float)y 0.5, t.v)){// 如果是这样使用以下代码获取插值的 z 值。// auto [alpha, beta, gamma] computeBarycentric2D(x, y, t.v); C17以上的版本才可以用此句否则修改成下面的俩句float alpha, beta, gamma;std::tie(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)]){Eigen::Vector3f p { (float)x,(float)y, z_interpolated }; //当前坐标set_pixel(p, t.getColor());depth_buf[get_index(x, y)] z_interpolated; //更新z值}}}}// TODO: 找出当前三角形的边界框。// 遍历像素并查找当前像素是否在三角形内// 如果是这样使用以下代码获取插值的 z 值。// 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_pixel 函数为三角形的颜色使用 getColor 函数如果应该绘制的话。
}// 设置模型矩阵的函数
void rst::rasterizer::set_model(const Eigen::Matrix4f m)
{model m;
}// 设置视图矩阵的函数
void rst::rasterizer::set_view(const Eigen::Matrix4f v)
{view v;
}// 设置投影矩阵的函数
void rst::rasterizer::set_projection(const Eigen::Matrix4f p)
{projection p;
}// 清除颜色和深度缓冲区的函数
void rst::rasterizer::clear(rst::Buffers buff)
{if ((buff rst::Buffers::Color) rst::Buffers::Color){std::fill(frame_buf.begin(), frame_buf.end(), Eigen::Vector3f{ 0, 0, 0 });}if ((buff rst::Buffers::Depth) rst::Buffers::Depth){std::fill(depth_buf.begin(), depth_buf.end(), std::numeric_limitsfloat::infinity());}
}// 构造函数初始化宽度和高度
rst::rasterizer::rasterizer(int w, int h) : width(w), height(h)
{frame_buf.resize(w * h);depth_buf.resize(w * h);
}// 获取索引的函数
int rst::rasterizer::get_index(int x, int y)
{return (height - 1 - y) * width x;
}// 设置像素颜色的函数
void rst::rasterizer::set_pixel(const Eigen::Vector3f point, const Eigen::Vector3f color)
{// 旧的索引auto ind point.y() point.x() * width;auto ind (height - 1 - point.y()) * width point.x();frame_buf[ind] color;
}
Triangle.cpp
//
// Created by LEI XU on 4/11/19.
//#include Triangle.h
#include algorithm
#include array// 初始化三角形的顶点坐标、颜色和纹理坐标为零向量或零值
Triangle::Triangle() {v[0] 0, 0, 0;v[1] 0, 0, 0;v[2] 0, 0, 0;color[0] 0.0, 0.0, 0.0;color[1] 0.0, 0.0, 0.0;color[2] 0.0, 0.0, 0.0;tex_coords[0] 0.0, 0.0;tex_coords[1] 0.0, 0.0;tex_coords[2] 0.0, 0.0;
}
// 设置三角形的顶点坐标
void Triangle::setVertex(int ind, Vector3f ver) {v[ind] ver;
}
// 设置三角形的法向量
void Triangle::setNormal(int ind, Vector3f n) {normal[ind] n;
}
// 设置三角形的颜色
void Triangle::setColor(int ind, float r, float g, float b) {if ((r 0.0) || (r 255.) ||(g 0.0) || (g 255.) ||(b 0.0) || (b 255.)) {fprintf(stderr, ERROR! Invalid color values);fflush(stderr);exit(-1);}// 将颜色值存储为范围在[0, 1]之间的Vector3fcolor[ind] Vector3f((float)r / 255., (float)g / 255., (float)b / 255.);return;
}
// 设置三角形的纹理坐标
void Triangle::setTexCoord(int ind, float s, float t) {tex_coords[ind] Vector2f(s, t);
}
// 将三角形的顶点坐标转换为四维向量
//这里transform()是stl算法作用是将第一个迭代器的元素做op变换之后放到第二个迭代器中
//最后一个位置的参数代表重载() {}运算符的操作。这里的transform的意思就是将v中vec的xyz存给res
std::arrayVector4f, 3 Triangle::toVector4() const
{std::arrayEigen::Vector4f, 3 res;std::transform(std::begin(v), std::end(v), res.begin(), [](auto vec) { return Eigen::Vector4f(vec.x(), vec.y(), vec.z(), 1.f); });return res;
}