Home › Forums › GAMES在线课程(现代计算机图形学入门)讨论区 › 作业2 三角形在屏幕中的位置不对
Tagged: Issue about HW2
- This topic has 8 replies, 4 voices, and was last updated 3 years, 6 months ago by Vicky W.
-
AuthorPosts
-
-
orangeParticipant
写完跑起来后得到的结果和预期不太一样。第一是整体向右移动了半个屏幕,感觉像是model变换除了问题。第二个问题是蓝色的三角形罩住了黄色的三角形?代码如下
// 判断点是否在三角形内
bool is_point_inside_triangle(Eigen::Vector3f point, Eigen::Vector4f p1, Eigen::Vector4f p2, Eigen::Vector4f p3) {
// do three dot products and check if symbols are the same. if so, return true, else false
Eigen::Vector3f _p1(p1.x(), p1.y(), 0);
Eigen::Vector3f _p2(p2.x(), p2.y(), 0);
Eigen::Vector3f _p3(p3.x(), p3.y(), 0);Eigen::Vector3f v12 = _p2 – _p1;
Eigen::Vector3f v23 = _p3 – _p2;
Eigen::Vector3f v31 = _p1 – _p3;Eigen::Vector3f v1p = point – _p1;
Eigen::Vector3f v2p = point – _p2;
Eigen::Vector3f v3p = point – _p3;auto a = v12.cross(v1p);
auto b = v23.cross(v2p);
auto c = v31.cross(v3p);if(a.dot(b) < 0 || b.dot(c) < 0 || c.dot(a) < 0 ) {
return false;
} else {
return true;
}
}// rasterize_triangle
auto v = t.toVector4();
Eigen::Vector4f p1 = v[0];
Eigen::Vector4f p2 = v[1];
Eigen::Vector4f p3 = v[2];
int minX = std::floor(std::min(std::min(p1.x(), p2.x()), p3.x()));
int minY = std::floor(std::min(std::min(p1.y(), p2.y()), p3.y()));
int maxX = std::ceil(std::max(std::max(p1.x(), p2.x()), p3.x()));
int maxY = std::ceil(std::max(std::max(p1.y(), p2.y()), p3.y()));for(int i = minY; i < maxY; i++) {
for(int j = minX; j < maxX; j++) {
float cx = j + 0.5;
float cy = i + 0.5;
Eigen::Vector3f currentPoint(cx, cy, 0.0);bool inside = is_point_inside_triangle(currentPoint, p1, p2, p3);
if(inside) {
auto[alpha, beta, gamma] = computeBarycentric2D(cx, cy, 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;
int currentBufferIndex = get_index(j, i);
if(depth_buf[currentBufferIndex] > z_interpolated) {
depth_buf[currentBufferIndex] = z_interpolated;
set_pixel(Eigen::Vector3f(cx, cy, 0.0), t.getColor());
}
}
}
}// get_projection_matrix 感觉问题可能出在这里?但是作业一好像没发现有什么问题
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{ // Students will implement this functionEigen::Matrix4f projection = Eigen::Matrix4f::Identity();
// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it.
float fov = eye_fov * M_PI / 180.0;
float t = std::abs(zNear) * std::tan(fov / 2.0);
float b = -t;
float r = t * aspect_ratio;
float l = -r;
float n = zNear;
float f = zFar;// perspective to orthographic matrix;
Eigen::Matrix4f Mp2o;
// orthographic projection matrix
Eigen::Matrix4f Moscale;Eigen::Matrix4f Motranslation;
Mp2o << n, 0.0, 0.0, 0.0, 0.0, n, 0.0, 0.0, 0.0, 0.0, n + f, -n * f, 0.0, 0.0, 1.0, 0.0;
Moscale << 2.0/(r – l), 0.0, 0.0, 0.0, 0.0, 2.0/(t – b), 0.0, 0.0, 0.0, 0.0, 2.0/(f-n), 0.0, 0.0, 0.0, 0.0, 1.0;
Motranslation << 1.0, 0.0, 0.0, -(r+l)/2.0, 0.0, 1.0, 0.0, -(t+b)/2.0, 0.0, 0.0, 1.0, -(n+f)/2.0, 0.0, 0.0, 0.0, 1.0;Eigen::Matrix4f Mortho = Moscale * Motranslation;
Eigen::Matrix4f Mprojection = Mortho * Mp2o;
return Mprojection;
} -
两只黑眼圈Participant
depth_buf没初始化值得话,有问题
-
两只黑眼圈Participant
而且,每帧结束要自己去清空或重置depth_buf的值
-
Vicky WParticipant
if(depth_buf[currentBufferIndex] > z_interpolated
这句反咯,应该是小于。另外请问是否解决了右移的bug?因为我也出现了这样的问题,摸不着头脑,很头痛。
-
我也遇到了同样的问题,因为我是在Windows下自己配的环境,没用虚拟机,不知道是不是不同平台的库的问题。
现在我在set_pixel里面把index的偏移了-350强行移到中间。 -
我真的是裂开,找到原因了:
算包围盒和遍历像素的时候要用int,用float会有偏移。。。
坑了我一天,气死了,做MSAA的时候也是一直出问题,搞了半天才发现是float的问题,我吐了This post has received 1 vote up. -
Vicky WParticipant
ps:
我使用了 “rgb” 方法排查右移问题。
在遍历包围盒时,判断像素点是否在三角形内,若返回否,则执行下列语句:Eigen::Vector3f OutsidePix {x,y,0}; Eigen::Vector3f OutsideCol {x,y,1}; set_Pixel(OutsidePix, OutsideCol);
得到结果如附图所示。
我不确定这是否表示包围盒相关步骤,或更早的步骤中存在问题。如有朋友遇到类似问题,欢迎交流。
日后如果理清思路,我也会补充分享。Attachments:
You must be logged in to view attached files.
-
-
AuthorPosts
- You must be logged in to reply to this topic.