Skip to content

Commit

Permalink
encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
roeas committed Aug 2, 2024
1 parent 92e498b commit 164d51a
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 54 deletions.
6 changes: 3 additions & 3 deletions Frame/Source/Assignment/Assignment1/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eyePos)

Eigen::Matrix4f get_model_matrix(float angle)
{
// 绕 Z 轴旋转
// 绕 Z 轴旋转
Eigen::Matrix4f model;
model <<
std::cos(angle), -std::sin(angle), 0.0f, 0.0f,
Expand All @@ -33,11 +33,11 @@ Eigen::Matrix4f get_model_matrix(float angle)

Eigen::Matrix4f get_projection_matrix(float fov, float aspect, float near, float far)
{
// 由 frustum 的定义得 top 与 right
// 由 frustum 的定义得 top 与 right
float top = std::tan(fov * 0.5f * MY_PI / 180.0f) * std::abs(near);
float right = aspect * top;

// 由相机此时的位置与方向得 bottom = -top 与 left = -right
// 由相机此时的位置与方向得 bottom = -top 与 left = -right
float bottom = -top;
float left = -right;

Expand Down
6 changes: 3 additions & 3 deletions Frame/Source/Assignment/Assignment2/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ Eigen::Matrix4f get_model_matrix(float rotation_angle)

Eigen::Matrix4f get_projection_matrix(float fov, float aspect, float near, float far)
{
// 修复框架 bug
// 修复框架 bug
near = -near;
far = -far;

// 由 frustum 的定义得 top 与 right
// 由 frustum 的定义得 top 与 right
float top = std::tan(fov * 0.5f * MY_PI / 180.0f) * std::abs(near);
float right = aspect * top;

// 由相机此时的位置与方向得 bottom = -top 与 left = -right
// 由相机此时的位置与方向得 bottom = -top 与 left = -right
float bottom = -top;
float left = -right;

Expand Down
26 changes: 13 additions & 13 deletions Frame/Source/Assignment/Assignment2/rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ auto to_vec4(const Eigen::Vector3f& v3, float w = 1.0f)

static bool insideTriangle(float x, float y, const Vector3f* v)
{
// 此时位于屏幕空间,保证 z 分量一致即可
// 此时位于屏幕空间,保证 z 分量一致即可
Eigen::Vector3f point = { x, y, 1.0f };
Eigen::Vector3f vertex_a = { v[0].x(), v[0].y(), 1.0f };
Eigen::Vector3f vertex_b = { v[1].x(), v[1].y(), 1.0f };
Expand Down Expand Up @@ -124,7 +124,7 @@ void rst::rasterizer::draw(pos_buf_id pos_buffer, ind_buf_id ind_buffer, col_buf
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();

// AABB 应当由整数的像素下标索引定义
// AABB 应当由整数的像素下标索引定义
uint16_t min_x = std::floor(std::min(v[0].x(), std::min(v[1].x(), v[2].x())));
uint16_t max_x = std::ceil(std::max(v[0].x(), std::max(v[1].x(), v[2].x())));
uint16_t min_y = std::floor(std::min(v[0].y(), std::min(v[1].y(), v[2].y())));
Expand All @@ -137,12 +137,12 @@ void rst::rasterizer::rasterize_triangle(const Triangle& t) {
size_t index = static_cast<size_t>(get_index(static_cast<int>(pos_x), static_cast<int>(pos_y)));
float &depth = depth_buf[index];

// SSAA 所采样的四个子像素相对于像素左下角坐标的偏移量
// SSAA 所采样的四个子像素相对于像素左下角坐标的偏移量
static const std::vector<Eigen::Vector2f> s_offsets = { {0.25f, 0.25f}, {0.75f, 0.25f}, {0.25f, 0.75f}, {0.75f, 0.75f} };
constexpr uint8_t SubPixelCount = 4;
assert(s_offsets.size() == SubPixelCount);

// 用于计算子像素贡献值
// 用于计算子像素贡献值
uint8_t activeColor = 0;
uint8_t activeDepth = 0;
Eigen::Vector3f finalColor = { 0.0f, 0.0f , 0.0f };
Expand All @@ -153,22 +153,22 @@ void rst::rasterizer::rasterize_triangle(const Triangle& t) {
float subPos_x = static_cast<float>(pos_x) + offset.x();
float subPos_y = static_cast<float>(pos_y) + offset.y();

// 获取子像素的深度插值
// 获取子像素的深度插值
auto [alpha, beta, gamma] = computeBarycentric2D(subPos_x, subPos_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 (insideTriangle(subPos_x, subPos_y, t.v))
{
// 修复框架 bug
// 修复框架 bug
if (z_interpolated > depth)
{
// 只有同时通过了 inside 测试与深度测试才会对颜色有贡献
// 只有同时通过了 inside 测试与深度测试才会对颜色有贡献
++activeColor;
finalColor += t.getColor();
}
// 只要通过 inside 测试就会对深度有贡献
// 只要通过 inside 测试就会对深度有贡献
++activeDepth;
finalDepth += z_interpolated;
}
Expand All @@ -177,13 +177,13 @@ void rst::rasterizer::rasterize_triangle(const Triangle& t) {
finalColor /= static_cast<float>(activeColor);
finalDepth /= static_cast<float>(activeDepth);

// 没有通过测试的子像素依旧应当对颜色与深度产生贡献,
// 按理来说其值应从 frame_buf_ssaax4 与 depth_buf_ssaax4 中获取。
// 鉴于框架本身较为简陋,这里意思到位即可。
// 没有通过测试的子像素依旧应当对颜色与深度产生贡献,
// 按理来说其值应从 frame_buf_ssaax4 与 depth_buf_ssaax4 中获取。
// 鉴于框架本身较为简陋,这里意思到位即可。
// finalColor += static_cast<float>(SubPixelCount - activeColor) / static_cast<float>(SubPixelCount) * frame_buf_ssaax2[subIndex];
// finalDepth += static_cast<float>(SubPixelCount - activeDepth) / static_cast<float>(SubPixelCount) * depth_buf_ssaax2[subIndex];

// 修复框架 bug
// 修复框架 bug
if (finalDepth > depth)
{
depth = finalDepth;
Expand Down Expand Up @@ -216,7 +216,7 @@ void rst::rasterizer::clear(rst::Buffers buff)
}
if ((buff & rst::Buffers::Depth) == rst::Buffers::Depth)
{
// 修复框架 bug
// 修复框架 bug
std::fill(depth_buf.begin(), depth_buf.end(), std::numeric_limits<float>::lowest());
}
}
Expand Down
4 changes: 2 additions & 2 deletions Frame/Source/Assignment/Assignment3/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ class Texture
float v_img = (1.0f - v) * heightf;
Eigen::Vector2f center{ std::round(u_img), std::round(v_img) };

// 边界情况,当采样点位于边界时进行 clamp,使得两对次采样点值相等,即此时双线性插值退化为单次线性插值
// 边界情况,当采样点位于边界时进行 clamp,使得两对次采样点值相等,即此时双线性插值退化为单次线性插值
Eigen::Vector2f u00{ std::max(0.0f, center.x() - 0.5f), std::max(0.0f, center.y() - 0.5f) };
Eigen::Vector2f u01{ std::max(0.0f, center.x() - 0.5f), std::min(heightf, center.y() + 0.5f)};
Eigen::Vector2f u10{ std::min(widthf, center.x() + 0.5f), std::max(0.0f, center.y() - 0.5f) };
Eigen::Vector2f u11{ std::min(widthf, center.x() + 0.5f), std::min(heightf, center.y() + 0.5f) };

// 边界情况,假设次采样点坐标为 (width, height),它应当采样的下标则为 (width - 1, height - 1)
// 边界情况,假设次采样点坐标为 (width, height),它应当采样的下标则为 (width - 1, height - 1)
Eigen::Vector2i u00_index{ std::clamp(static_cast<int>(u00.x()), 0, width - 1), std::clamp(static_cast<int>(u00.y()), 0, height - 1) };
Eigen::Vector2i u01_index{ std::clamp(static_cast<int>(u01.x()), 0, width - 1), std::clamp(static_cast<int>(u01.y()), 0, height - 1) };
Eigen::Vector2i u10_index{ std::clamp(static_cast<int>(u10.x()), 0, width - 1), std::clamp(static_cast<int>(u10.y()), 0, height - 1) };
Expand Down
10 changes: 5 additions & 5 deletions Frame/Source/Assignment/Assignment3/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ Eigen::Matrix4f get_model_matrix(float angle)

Eigen::Matrix4f get_projection_matrix(float fov, float aspect, float near, float far)
{
// 修复框架 bug
// 修复框架 bug
near = -near;
far = -far;

// 由 frustum 的定义得 top 与 right
// 由 frustum 的定义得 top 与 right
float top = std::tan(fov * 0.5f * MY_PI / 180.0f) * std::abs(near);
float right = aspect * top;

// 由相机此时的位置与方向得 bottom = -top 与 left = -right
// 由相机此时的位置与方向得 bottom = -top 与 left = -right
float bottom = -top;
float left = -right;

Expand Down Expand Up @@ -152,7 +152,7 @@ Eigen::Vector3f phong_fragment_shader(const fragment_shader_payload& payload)

Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload &payload)
{
// 好像 OpenCV 读取 png 时的返回值范围是 [0, 255],而非 [0, 1]
// 好像 OpenCV 读取 png 时的返回值范围是 [0, 255],而非 [0, 1]
static constexpr float reciprocal = 1.0f / 255.0f;

static Eigen::Vector3f ka = Eigen::Vector3f(0.005f, 0.005f, 0.005f);
Expand Down Expand Up @@ -288,7 +288,7 @@ Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payl
float du = kh * kn * (height_u - height);
float dv = kh * kn * (height_v - height);

// 将着色点沿着原法线的方向进行位移
// 将着色点沿着原法线的方向进行位移
point += kn * normal * height;

Eigen::Vector3f localNormal = Eigen::Vector3f{ -du, -dv, 1.0f };
Expand Down
8 changes: 4 additions & 4 deletions Frame/Source/Assignment/Assignment3/rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ void rst::rasterizer::draw(std::vector<Triangle *> &TriangleList)
// Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos)
{
// 为了获取顶点的 w 分量,这里不能使用 Triangle::toVector4
// 为了获取顶点的 w 分量,这里不能使用 Triangle::toVector4
const Eigen::Vector4f *v = t.v;

// AABB 应当由整数的像素下标索引定义
// AABB 应当由整数的像素下标索引定义
uint16_t min_x = std::floor(std::min(v[0].x(), std::min(v[1].x(), v[2].x())));
uint16_t max_x = std::ceil(std::max(v[0].x(), std::max(v[1].x(), v[2].x())));
uint16_t min_y = std::floor(std::min(v[0].y(), std::min(v[1].y(), v[2].y())));
Expand All @@ -153,7 +153,7 @@ void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eig
size_t index = static_cast<size_t>(get_index(static_cast<int>(pos_x), static_cast<int>(pos_y)));
float &depth = depth_buf[index];

// 修复框架 bug
// 修复框架 bug
if (final_z > depth)
{
depth = final_z;
Expand Down Expand Up @@ -201,7 +201,7 @@ void rst::rasterizer::clear(rst::Buffers buff)
}
if ((buff & rst::Buffers::Depth) == rst::Buffers::Depth)
{
// 修复框架 bug
// 修复框架 bug
std::fill(depth_buf.begin(), depth_buf.end(), std::numeric_limits<float>::lowest());
}
}
Expand Down
2 changes: 1 addition & 1 deletion Frame/Source/Assignment/Assignment4/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void bezier(const std::vector<cv::Point2f> &control_points, cv::Mat &window)
int x_index = point.x() + offset[i][j].x();
int y_index = point.y() + offset[i][j].y();

// OpenCV »áʹһ¸öÏñËصãµÄÖµ mod 255
// OpenCV 会使一个像素点的值 mod 255
uchar color = std::max(static_cast<uchar>(filter[i][j] * 255), window.at<cv::Vec3b>(y_index, x_index)[1]);
window.at<cv::Vec3b>(y_index, x_index)[1] = std::min(static_cast<uchar>(255), color);
}
Expand Down
32 changes: 16 additions & 16 deletions Frame/Source/Assignment/Assignment6/BVH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)
{
BVHBuildNode* pNode = new BVHBuildNode();

// 所有物体的包围盒集合。
// 所有物体的包围盒集合。
Bounds3 bounds;
for (int i = 0; i < objects.size(); ++i)
{
bounds = Union(bounds, objects[i]->getBounds());
}

// 只存在一个物体,建立叶节点。
// 只存在一个物体,建立叶节点。
if (objects.size() == 1)
{
pNode->bounds = objects[0]->getBounds();
Expand All @@ -46,7 +46,7 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)

return pNode;
}
// 存在两个物体,建立其 left 和 right 叶节点。
// 存在两个物体,建立其 left 和 right 叶节点。
else if (objects.size() == 2)
{
pNode->left = recursiveBuild(std::vector{ objects[0] });
Expand All @@ -57,33 +57,33 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)
}
else
{
// 由所有物体的质心组成的包围盒。
// 由所有物体的质心组成的包围盒。
Bounds3 centroidBounds;
for (int i = 0; i < objects.size(); ++i)
{
centroidBounds = Union(centroidBounds, objects[i]->getBounds().Centroid());
}

// 最长的维度。
// 最长的维度。
switch (centroidBounds.maxExtent())
{
case 0:
// X 轴。
// X 轴。
std::sort(objects.begin(), objects.end(), [](auto f1, auto f2)
{
// 将所有物体按照其包围盒的质心的 X 轴排序,Y 轴和 Z 轴的 case 同理。
// 将所有物体按照其包围盒的质心的 X 轴排序,Y 轴和 Z 轴的 case 同理。
return f1->getBounds().Centroid().x < f2->getBounds().Centroid().x;
});
break;
case 1:
// Y 轴。
// Y 轴。
std::sort(objects.begin(), objects.end(), [](auto f1, auto f2)
{
return f1->getBounds().Centroid().y < f2->getBounds().Centroid().y;
});
break;
case 2:
// Z 轴。
// Z 轴。
std::sort(objects.begin(), objects.end(), [](auto f1, auto f2)
{
return f1->getBounds().Centroid().z < f2->getBounds().Centroid().z;
Expand All @@ -98,14 +98,14 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)

#if ENABLE_SAH

// 一份比较清晰的 SAH 介绍:https://zhuanlan.zhihu.com/p/50720158
// 一份比较清晰的 SAH 介绍:https://zhuanlan.zhihu.com/p/50720158

// 划分方式的总数。
// 划分方式的总数。
constexpr uint8_t SlashCount = 8;
constexpr float SlashCountInv = 1.0f / static_cast<float>(SlashCount);
const float SC = centroidBounds.SurfaceArea();

// 用于记录最优的划分方式。
// 用于记录最优的划分方式。
uint8_t minCostIndex = SlashCount / 2;
float minCost = std::numeric_limits<float>::infinity();

Expand All @@ -115,7 +115,7 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)
auto leftObjects = std::vector<Object *>(begin, target);
auto rightObjects = std::vector<Object *>(target, end);

// 分别计算划分之后两部分包围盒的表面积。
// 分别计算划分之后两部分包围盒的表面积。
Bounds3 leftBounds, rightBounds;
for (const auto &obj : leftObjects)
{
Expand All @@ -134,7 +134,7 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)

if (cost < minCost)
{
// 更新更优的划分方式。
// 更新更优的划分方式。
minCost = cost;
minCostIndex = index;
}
Expand All @@ -144,7 +144,7 @@ BVHBuildNode* BVHAccel::recursiveBuild(std::vector<Object*> objects)

#else // ENABLE_SAH

// 基本的 BVH 划分方式,按数量从中间一分为二。
// 基本的 BVH 划分方式,按数量从中间一分为二。
const auto &target = objects.begin() + (objects.size() / 2);

#endif // ENABLE_SAH
Expand Down Expand Up @@ -181,7 +181,7 @@ Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const
return Intersection{};
}

// 叶节点
// 叶节点
if (node->left == nullptr && node->right == nullptr)
{
return node->object->getIntersection(ray);
Expand Down
2 changes: 1 addition & 1 deletion Frame/Source/Assignment/Assignment6/Triangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ inline Intersection Triangle::getIntersection(Ray ray)
{
if (dotProduct(ray.direction, normal) > 0.0f)
{
// ¹âԴλÓÚÈý½ÇÐα³Ãæ¡£
// 光源位于三角形背面。
return Intersection{};
}

Expand Down
8 changes: 4 additions & 4 deletions Frame/Source/Assignment/Assignment7/Material.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ class Material
return false;
}

// 返回出射光线的方向。
// 返回出射光线的方向。
inline Vector3f sample(const Vector3f &wi, const Vector3f &N);
// 返回采样的 PDF。
// 返回采样的 PDF。
inline float pdf(const Vector3f &wi, const Vector3f &wo, const Vector3f &N);
// 返回 BRDF。
// 返回 BRDF。
inline Vector3f eval(const Vector3f &wi, const Vector3f &wo, const Vector3f &N);
};

Expand Down Expand Up @@ -220,7 +220,7 @@ Vector3f Material::eval(const Vector3f &wi, const Vector3f &wo, const Vector3f &
}
case MaterialType::MIRROR:
{
// 听说完美镜面是需要考虑菲涅尔项的,有空再研究吧。
// 听说完美镜面是需要考虑菲涅尔项的,有空再研究吧。
return Vector3f{ 1.0f , 1.0f , 1.0f };
break;
}
Expand Down
4 changes: 2 additions & 2 deletions Frame/Source/Assignment/Assignment7/Triangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,11 @@ inline Intersection Triangle::getIntersection(Ray ray)
{
if (dotProduct(ray.direction, normal) > 0.0f)
{
// 光源位于三角形背面。
// 光源位于三角形背面。
return Intersection{};
}

// E1, E2 在 Triangle 的构造函数中已经赋好值了。
// E1, E2 在 Triangle 的构造函数中已经赋好值了。
const Vector3f &E1 = e1;
const Vector3f &E2 = e2;
const Vector3f &D = ray.direction;
Expand Down

0 comments on commit 164d51a

Please sign in to comment.