WARNING
Content Under Development
See
release page for
latest official PDF version.
**Chapter 9: A Scene Testing All New Features**
Let’s put it all together, with a big thin mist covering everything, and a blue subsurface
reflection sphere (we didn’t implement that explicitly, but a volume inside a dielectric is what a
subsurface material is). The biggest limitation left in the renderer is no shadow rays, but that is
why we get caustics and subsurface for free. It’s a double-edged design decision.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
hitable *final() {
int nb = 20;
hitable **list = new hitable*[30];
hitable **boxlist = new hitable*[10000];
hitable **boxlist2 = new hitable*[10000];
material *white = new lambertian( new constant_texture(vec3(0.73, 0.73, 0.73)));
material *ground = new lambertian( new constant_texture(vec3(0.48, 0.83, 0.53)));
int b = 0;
for (int i = 0; i < nb; i++) {
for (int j = 0; j < nb; j++) {
float w = 100;
float x0 = -1000 + i*w;
float z0 = -1000 + j*w;
float y0 = 0;
float x1 = x0 + w;
float y1 = 100*(drand48()+0.01);
float z1 = z0 + w;
boxlist[b++] = new box(vec3(x0,y0,z0), vec3(x1,y1,z1), ground);
}
}
int l = 0;
list[l++] = new bvh_node(boxlist, b, 0, 1);
material *light = new diffuse_light( new constant_texture(vec3(7, 7, 7)) );
list[l++] = new xz_rect(123, 423, 147, 412, 554, light);
vec3 center(400, 400, 200);
list[l++] = new moving_sphere(center, center+vec3(30, 0, 0),
0, 1, 50, new lambertian(new constant_texture(vec3(0.7, 0.3, 0.1))));
list[l++] = new sphere(vec3(260, 150, 45), 50, new dielectric(1.5));
list[l++] = new sphere(vec3(0, 150, 145), 50,
new metal(vec3(0.8, 0.8, 0.9), 10.0));
hitable *boundary = new sphere(vec3(360, 150, 145), 70, new dielectric(1.5));
list[l++] = boundary;
list[l++] = new constant_medium(boundary, 0.2,
new constant_texture(vec3(0.2, 0.4, 0.9)));
boundary = new sphere(vec3(0, 0, 0), 5000, new dielectric(1.5));
list[l++] = new constant_medium(boundary, 0.0001,
new constant_texture(vec3(1.0, 1.0, 1.0)));
int nx, ny, nn;
unsigned char *tex_data = stbi_load("earthmap.jpg", &nx, &ny, &nn, 0);
material *emat = new lambertian(new image_texture(tex_data, nx, ny));
list[l++] = new sphere(vec3(400,200, 400), 100, emat);
texture *pertext = new noise_texture(0.1);
list[l++] = new sphere(vec3(220,280, 300), 80, new lambertian( pertext ));
int ns = 1000;
for (int j = 0; j < ns; j++) {
boxlist2[j] = new sphere(
vec3(165*drand48(), 165*drand48(), 165*drand48()), 10, white);
}
list[l++] = new translate(new rotate_y(
new bvh_node(boxlist2,ns, 0.0, 1.0), 15), vec3(-100,270,395));
return new hitable_list(list,l);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running it with 10,000 rays per pixel yields:

Now go off and make a really cool image of your own! See http://in1weekend.com/ for pointers to
further reading and features, and feel free to email questions, comments, and cool images to me at
ptrshrl@gmail.com.