My picture is brighter
qinglaihuier opened this issue · 0 comments
qinglaihuier commented
Thank you very much for your tutorial, I learned a lot from it.
But in Lesson 2 my picture is much brighter than yours on the whole, is this normal?
`int main() {
Model* model = &_model;
Vec3f light_dir (0,0,-1);
const int C_width = 600;
const int C_height = 600;
TGAImage image(C_width, C_height, TGAImage::RGB);
for (int i = 0; i < model->nfaces(); ++i) {
std::vector<int> face = model->face(i);
Vec2i screen_coords[3];
Vec3f world_coords[3];
for (int j = 0; j < 3; ++j) {
Vec3f v = model->vert(face[j]);
screen_coords[j] = Vec2i((v.x + 1) * C_width/2, (v.y + 1) * C_height/2);
world_coords[j] = v;
}
Vec3f normal = (world_coords[2] - world_coords[0]) ^ (world_coords[1] - world_coords[0]);
normal.normalize();
float intensity = normal * light_dir;
if(intensity > 0)
triangle(screen_coords, image, TGAColor(intensity * 255.0, intensity * 255.0, intensity * 255.0,255));
}
image.flip_vertically();
image.write_tga_file("output2.tga");
}
void triangle(Vec2i* pts, TGAImage& image, const TGAColor color) {
Vec2i bboxmin = Vec2i(image.get_width() - 1, image.get_height() - 1);
Vec2i bboxmax = {0,0};
Vec2i clamp = Vec2i(image.get_width() - 1, image.get_height() - 1);
for (int i = 0; i < 3; ++i) {
bboxmin.x = std::max(0, std::min(bboxmin.x, pts[i].x));
bboxmin.y = std::max(0, std::min(bboxmin.y, pts[i].y));
bboxmax.x = std::min(clamp.x, std::max(bboxmax.x, pts[i].x));
bboxmax.y = std::min(clamp.y, std::max(bboxmax.y, pts[i].y));
}
Vec2i nowV;
Vec3f _barycentric;
for (int x = bboxmin.x; x <= bboxmax.x; ++x) {
for (int y = bboxmin.y; y <= bboxmax.y; ++y) {
nowV.x = x;
nowV.y = y;
_barycentric = barycentric(pts, nowV);
if (_barycentric.x < 0 || _barycentric.y < 0 || _barycentric.z < 0) continue;
image.set(x, y,color);
}
}
}`
`Vec3f barycentric(Vec2i* pts, Vec2i p) {
Vec2i AB = pts[1] - pts[0];
Vec2i AC = pts[2] - pts[0]; //uAB + vAC +PA = 0
Vec2i PA = pts[0] - p;
Vec3i vX = { AB.x,AC.x,PA.x };
Vec3i vY = { AB.y,AC.y,PA.y };
Vec3f cross_product ;
cross_product.x = (float)vX.y * vY.z - (float)vX.z * vY.y;
cross_product.y = (float)vX.z * vY.x - (float)vX.x * vY.z;
cross_product.z = (float)vX.x * vY.y - (float)vX.y * vY.x;
if (std::abs(cross_product.z) < 1.0) return Vec3f(-1, 1, 1);
return Vec3f(1.f - (cross_product.x + cross_product.y)/ cross_product.z, cross_product.x/ cross_product.z, cross_product.y/cross_product.z);
//Vec3f u = Vec3f(pts[2].x - pts[0].x, pts[1].x - pts[0].x, pts[0].x - P.x) ^ Vec3f(pts[2].y - pts[0].y, pts[1].y - pts[0].y, pts[0].y - P.y);
///* `pts` and `P` has integer value as coordinates
// so `abs(u[2])` < 1 means `u[2]` is 0, that means
// triangle is degenerate, in this case return something with negative coordinates */
//if (std::abs(u.z) < 1) return Vec3f(-1, 1, 1);
//return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
}
`