Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A non recursive implementation of ray_color #624

Open
D-K-E opened this issue May 28, 2020 · 8 comments
Open

A non recursive implementation of ray_color #624

D-K-E opened this issue May 28, 2020 · 8 comments

Comments

@D-K-E
Copy link

D-K-E commented May 28, 2020

I would like to suggest a simple non recursive implementation for ray_color function to be mentioned in an alternative listing during the first book around chapter 8.

I realize that it is maybe outside of the current scope of the first book, where everything is as simple as possible. However, since portability is also a concern for the first book, and it is not possible to use recursion in glsl and OpenCL, it might help to briefly at least mention a non recursive implementation from which the reader might build her own version for more complicated stuff later on.

Here is my proposition:

color ray_color2(const Ray &r, const HittableList &scene, int depth) {
  Ray r_in = Ray(r.origin, r.direction);
  color rcolor = color(1,1,1);
  while (true) {
    HitRecord record;
    if (depth <= 0) {
      // final case
      return color(0);
    }
    if (scene.hit(r_in, 0.001, INF, record)) {
      // recursive case
      point3 target = record.point + random_in_hemisphere(record.normal);
      r_in = Ray(record.point, target - record.point);
      depth--;
      rcolor *= 0.5;
    } else {
      // no hit so bye
      vec3 direction = unit_vector(r_in.direction);
      double temp = 0.5 * (direction.y() + 1.0);
      rcolor *= (1.0 - temp) * color(1,1,1) + temp * color(0.5, 0.7, 1.0);
      return rcolor;
    }
  }
}

Note that I am not using any call stack to emulate the recursion. The function correctly renders the figure in Rendering of diffuse spheres with hemispherical scattering, I also ported it to glsl and it works over there as well.

@hollasch hollasch added this to the Future milestone May 28, 2020
@trevordblack
Copy link
Collaborator

There have been a couple of public implementations in languages or environments that discourage recursion, e.g. Cuda, OptiX, OpenCL, GLSL

I think that having two implementations of the main rendering loop would be overkill, and I think that recursion is the KISS version of the two.
But, I'm open to suggestions.

@D-K-E
Copy link
Author

D-K-E commented May 28, 2020

I also admit that recursion reads more easily, and it also models better the underlying equation.

Having said that, I also noticed that through listing 34 - 40, we are slowly building up the ray_color for lambertian surfaces by tweaking the distribution function along the way and at the end an alternative implementation with random_in_hemisphere is provided. I thought it would fit the overall flow of the chapter to mention a non recursive implementation while the rendering loop is still simple before passing to metals.

My initial research, aka googling, showed only implementations with a call stack using preprocessor variables of the type #define MAX_BOUNDS etc, so I thought it might be an improvement to implement the function without it.

It would be great to have at least a link to a public non recursive implementation in section 13.2: Next Steps for those who are trying to port what's here to an environment that discourages recursion.

@trevordblack
Copy link
Collaborator

https://github.com/RayTracing/raytracing.github.io/wiki/Implementations-in-Other-Languages

See: Cuda

I'm not sure if we're still broadcasting this wiki page.

@hollasch
Are we?

@hollasch
Copy link
Collaborator

broadcasting == advertising? Not that much. It's still up and readable to the general public. I don't know if anyone with a GitHub account can edit.

@trevordblack
Copy link
Collaborator

trevordblack commented May 29, 2020 via email

@hollasch
Copy link
Collaborator

Looks like it's only mentioned in the src README's. We should probably note this in the project web page.

@D-K-E
Copy link
Author

D-K-E commented May 29, 2020

The implementation I am seeing in the link uses a constant value for iteration, not much different than using a preprocessor directive and a call stack. However it would have been a good pointer if I had known it before.

@Morozov-5F
Copy link

I have tried to implement an iterative variant of the rendering ray_colour function and I've managed to make a working variant which produces the same results as recursive option for scenes from "The Next Week" book. Here's the link: https://github.com/Morozov-5F/raytracing-weekend/blob/96aab798a0d72dc67bcc3d0d54f26c063bac856f/main.c#L93 (note that it's in C).

@hollasch hollasch modified the milestones: Backlog, v4.1.0 Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants