ssloy / tinyrenderer

A brief computer graphics / rendering course
https://github.com/ssloy/tinyrenderer/wiki
Other
20.73k stars 1.99k forks source link

My picture is brighter #124

Open qinglaihuier opened 1 year ago

qinglaihuier commented 1 year ago

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);

} `

QQ图片20230209202042