Пример #1
0
/**
 * Raster the color triangle to the screen.  Points are in
 * NDC coordinates (converted to screen coordinates).
 *
 * colors correspond to the respective points.
 */
void raster_triangle(point *a, point *b, point *c, color ca,
		color cb, color cc, int xres, int yres, color** grid,
		float** depth_grid) {
	point screen_a = NDC_to_screen(a, xres, yres);
	point screen_b = NDC_to_screen(b, xres, yres);
	point screen_c = NDC_to_screen(c, xres, yres);

	float x_min = min_x(&screen_a, &screen_b, &screen_c);
	float x_max = max_x(&screen_a, &screen_b, &screen_c);
	float y_min = min_y(&screen_a, &screen_b, &screen_c);
	float y_max = max_y(&screen_a, &screen_b, &screen_c);

	x_max = x_max > xres ? xres : x_max;
	y_max = y_max > yres ? yres : y_max;

	for (int x = x_min; x < x_max; x++) {
		for (int y = y_min; y < y_max; y++) {
			point curr_point = create_point(x, y, 0);
			float alpha = compute_alpha(&screen_a, &screen_b, &screen_c, &curr_point);
			float beta = compute_beta(&screen_a, &screen_b, &screen_c, &curr_point);
			float gamma = compute_gamma(&screen_a, &screen_b, &screen_c, &curr_point);
			curr_point.z = alpha * screen_a.z + beta * screen_b.z + gamma * screen_c.z;

			if (valid_parameters(alpha, beta, gamma) && depth_grid[x][y] > curr_point.z) {
				color col = compute_color(ca, cb, cc, alpha, beta, gamma);
				grid[x][y].r = col.r;
				grid[x][y].g = col.g;
				grid[x][y].b = col.b;

				depth_grid[x][y] = curr_point.z;
			}
		}
	}
}
Пример #2
0
int main(int argc, char *argv[])
{
    int nx = 450;
    int ny = 450;
    int ns = 300; 

    camera cam(M_PI/3.7, float(nx)/float(ny));
    hitable_list list;
    mk_cornell_box(list);
    set_cornell_view(cam, nx, ny);
    
#ifdef _WIN32
    setmode(fileno(stdout), O_BINARY);
#endif

    // Don't stack allocate this, it is usually way larger than the compiler's set
    // stack size. 
    unsigned char *img = new unsigned char[nx * ny * 3];

    //std::cout << "P3\n" << nx << " " << ny << "\n255\n";
    for (int j = ny - 1; j >= 0; j--)
    {
        for (int i = 0; i < nx; i++)
        {
            vec3 col(0,0,0);
            for (int s=0; s < ns; s++)
            {
                float u = float(i + random1d()) / float(nx);
                float v = float(j + random1d()) / float(ny);
                ray r = cam.get_ray(u, v);
                col += compute_color(r, &list, 0);
            }
            col /= float(ns);
            col = gamma_corrected_clamp(col);
            /*if (col.x() > 1 || col.y() > 1 || col.z() > 1)
                std::cout << "# channel greater than 1 at " << i << "," << j << "\n";
            */
            img[((ny - 1 - j) * nx + i) * 3 + 0] = (unsigned char)(254.99 * col[0]);
            img[((ny - 1 - j) * nx + i) * 3 + 1] = (unsigned char)(254.99 * col[1]);
            img[((ny - 1 - j) * nx + i) * 3 + 2] = (unsigned char)(254.99 * col[2]);
            //std::cout << ir << " " << ig << " " << ib << "\n";
        }
    }

    if (!stbi_write_png_to_func(stbi_write_to_stdout, 0, nx, ny, 3, img, 3 * sizeof(char) * nx))
        std::cerr << "Failed to write anything at all.\n";

    delete[] img;
}
Пример #3
0
color compute_color(ray const &r, hitable *world, int depth)
{
    hit_record rec = {};
    if (world->hit(r, 0.0001f, FLT_MAX, rec))
    {
        ray scattered;
        color attenuation;
        if (rec.mat_ptr == 0)
            std::cerr << "SCHEISSE!";
        color emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.P); 
        if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered))
        {
            return emitted + attenuation * compute_color(scattered, world, depth+1);
        }
        else
            return emitted;
    }
    
    return color(0,0,0); 
}