|
| 1 | +#include <iostream> |
| 2 | +#include "sphere.h" |
| 3 | +#include "hitable_list.h" |
| 4 | +#include "float.h" |
| 5 | +#include "camera.h" |
| 6 | +#include "material.h" |
| 7 | + |
| 8 | + |
| 9 | +vec3 color(const ray& r, hitable *world, int depth) { |
| 10 | + hit_record rec; |
| 11 | + if (world->hit(r, 0.001, MAXFLOAT, rec)) { |
| 12 | + ray scattered; |
| 13 | + vec3 attenuation; |
| 14 | + if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) { |
| 15 | + return attenuation*color(scattered, world, depth+1); |
| 16 | + } |
| 17 | + else { |
| 18 | + return vec3(0,0,0); |
| 19 | + } |
| 20 | + } |
| 21 | + else { |
| 22 | + vec3 unit_direction = unit_vector(r.direction()); |
| 23 | + float t = 0.5*(unit_direction.y() + 1.0); |
| 24 | + return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 25 | + } |
| 26 | +} |
| 27 | + |
| 28 | + |
| 29 | +hitable *random_scene() { |
| 30 | + int n = 500; |
| 31 | + hitable **list = new hitable*[n+1]; |
| 32 | + list[0] = new sphere(vec3(0,-1000,0), 1000, new lambertian(vec3(0.5, 0.5, 0.5))); |
| 33 | + int i = 1; |
| 34 | + for (int a = -11; a < 11; a++) { |
| 35 | + for (int b = -11; b < 11; b++) { |
| 36 | + float choose_mat = drand48(); |
| 37 | + vec3 center(a+0.9*drand48(),0.2,b+0.9*drand48()); |
| 38 | + if ((center-vec3(4,0.2,0)).length() > 0.9) { |
| 39 | + if (choose_mat < 0.8) { // diffuse |
| 40 | + list[i++] = new sphere(center, 0.2, new lambertian(vec3(drand48()*drand48(), drand48()*drand48(), drand48()*drand48()))); |
| 41 | + } |
| 42 | + else if (choose_mat < 0.95) { // metal |
| 43 | + list[i++] = new sphere(center, 0.2, |
| 44 | + new metal(vec3(0.5*(1 + drand48()), 0.5*(1 + drand48()), 0.5*(1 + drand48())), 0.5*drand48())); |
| 45 | + } |
| 46 | + else { // glass |
| 47 | + list[i++] = new sphere(center, 0.2, new dielectric(1.5)); |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + list[i++] = new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5)); |
| 54 | + list[i++] = new sphere(vec3(-4, 1, 0), 1.0, new lambertian(vec3(0.4, 0.2, 0.1))); |
| 55 | + list[i++] = new sphere(vec3(4, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0)); |
| 56 | + |
| 57 | + return new hitable_list(list,i); |
| 58 | +} |
| 59 | + |
| 60 | +int main() { |
| 61 | + int nx = 1200; |
| 62 | + int ny = 800; |
| 63 | + int ns = 10; |
| 64 | + std::cout << "P3\n" << nx << " " << ny << "\n255\n"; |
| 65 | + hitable *list[5]; |
| 66 | + float R = cos(M_PI/4); |
| 67 | + list[0] = new sphere(vec3(0,0,-1), 0.5, new lambertian(vec3(0.1, 0.2, 0.5))); |
| 68 | + list[1] = new sphere(vec3(0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0))); |
| 69 | + list[2] = new sphere(vec3(1,0,-1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 0.0)); |
| 70 | + list[3] = new sphere(vec3(-1,0,-1), 0.5, new dielectric(1.5)); |
| 71 | + list[4] = new sphere(vec3(-1,0,-1), -0.45, new dielectric(1.5)); |
| 72 | + hitable *world = new hitable_list(list,5); |
| 73 | + world = random_scene(); |
| 74 | + |
| 75 | + vec3 lookfrom(13,2,3); |
| 76 | + vec3 lookat(0,0,0); |
| 77 | + float dist_to_focus = 10.0; |
| 78 | + float aperture = 0.1; |
| 79 | + |
| 80 | + camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture, dist_to_focus); |
| 81 | + |
| 82 | + for (int j = ny-1; j >= 0; j--) { |
| 83 | + for (int i = 0; i < nx; i++) { |
| 84 | + vec3 col(0, 0, 0); |
| 85 | + for (int s=0; s < ns; s++) { |
| 86 | + float u = float(i + drand48()) / float(nx); |
| 87 | + float v = float(j + drand48()) / float(ny); |
| 88 | + ray r = cam.get_ray(u, v); |
| 89 | + vec3 p = r.point_at_parameter(2.0); |
| 90 | + col += color(r, world,0); |
| 91 | + } |
| 92 | + col /= float(ns); |
| 93 | + col = vec3( sqrt(col[0]), sqrt(col[1]), sqrt(col[2]) ); |
| 94 | + int ir = int(255.99*col[0]); |
| 95 | + int ig = int(255.99*col[1]); |
| 96 | + int ib = int(255.99*col[2]); |
| 97 | + std::cout << ir << " " << ig << " " << ib << "\n"; |
| 98 | + } |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | + |
| 103 | + |
0 commit comments