In smallpt's source at line 90 the direction is multiplied by 140 and I was wondering where that number is coming from. I was hoping for it to be explained in the slides attached to the source but I couldn't find an explanation for where that number is coming from.

If I increase the number(to 160.0 for example) it starts giving some kind of weird zoom-out effect: enter image description here

And if I decrease the number(in this example to 125.0) I get this partially black picture: enter image description here

As I understand it, after I've simplified smallpt a little bit, in the main function we get a random point in each subpixel normalized by the width/height between -0.5 and 0.5, and then calculate the new ray direction by multiplying the x and y axis by these offsets, then adding everything together to obtain the new direction, something like this:

fov_scale = 2.0 * tan(vertical_fov / 2.0)
cam_x_axis = vec3(aspect_ratio * fov_scale, 0, 0)
cam_y_axis = normalize(cross(cam_x_axis, cam_direction))

for x, y:
    for sx, sy, samps:
        // not using smallpt's tent filter
        x_in_subpixel = x + sx * 0.5 + erand48(Xi) * 0.5
        y_in_subpixel = y + sy * 0.5 + erand48(Xi) * 0.5
        // normalize them between -0.5 and 0.5
        new_x = x_in_subpixel / w - 0.5
        new_y = y_in_subpixel / h - 0.5

        offset_x = cam_x_axis * new_x
        offset_y = cam_y_axis * new_y
        new_direction = cam_direction + offset_x + offset_y
        // here we can see that magic number
        new_ray = ray(cam_position + new_direction * 140, normalize(new_direction))

So my questions are:

  • What does this number mean?
  • Can I calculate it programmatically to be exactly what is expected(maybe depending on the field of view, width/height of the image)?
  • $\begingroup$ It's a rescaling of the virtual film. $\endgroup$ – lightxbulb Mar 6 at 18:48
  • $\begingroup$ @lightxbulb And how is it calculated? I mean why 140? $\endgroup$ – Alexandru Ica Mar 6 at 20:26
  • $\begingroup$ It's just fitted to the specific scene as far as I can tell. Likely by trial and error. $\endgroup$ – lightxbulb Mar 6 at 22:24
  • $\begingroup$ @lightxbulb Thanks for commenting, I ended up replacing the code for the camera entirely(with inspiration from "Ray Tracing in One Weekend"), I really wanted to get rid of all of these constants! $\endgroup$ – Alexandru Ica Mar 7 at 11:24
Sphere(1e5, Vec(50,40.8,-1e5+170), Vec(),Vec(),           DIFF),//Frnt

The sphere with index 3 would intersect each ray if the ray origin would not be shifted forward.

You can easily verify this by returning surface normals from the radiance and not shifting the ray origin. (or just remove this one sphere). It also will look like a tunnel behind the camera ;)

  • $\begingroup$ Oh, thank you, so it was much simpler than I thought. I ended up borrowing parts from "Ray Tracing In One Weekend" for the camera anyway because I wasn't comfortable with using the one that comes with smallpt. $\endgroup$ – Alexandru Ica Jun 8 at 18:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.