hunterloftis / pbr

a Physically Based Renderer (PBR) in Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Time and Frames limits gone after refactor

dormando opened this issue · comments

Thanks for merging the -profile fix so quickly! At the same time I'd noticed Time and Frames were also in options but not implemented anymore.

While I'm still trying to grok how the program works I can fix these to help learn the code structure, but wanted to open this issue first in case you had specific plans for redoing or replacing these features.

If "any way is fine" I'll just think of something. :)

Thanks!

I don't have a specific way in mind but I'd like to hear how you'd go about it.

Time limiter is pretty easy, I just made that work locally. I also made it dump a png after hitting the time limit or ^C'ing, and think I'll add an option to adjust the periodic dump.

Frames looks interesting:

  • one tracer worker is fired up per CPU
  • each tracer is submitting a pass across the x/y as a Frame upstream
  • which then gets merged into the top level frame sample as they come in.

f.samples is more like f.frames, though you have a note suggesting "samples -> pixels" for the output, but I don't think it's easy for users to relate frames == samples. not sure it'd make sense to output "samples/sec" :P

Also, when frame.Stop() is called, it immediately exits out. That might be fine for ^C'ing but being able to wait for outstanding frames/samples to finish might be nice for the frame/time limiter.

Frame limit could be done two ways, I'm not partial to either:

  1. be exact, have a frame.C that gets pinged with the current frame/sample total after each submission.
  2. add a per-second ticker in Iterative that samples the frame/sample total. Stop when it's past the limit.

I could also see an option where a frame submits series of rows/columns for each worker to chew on and re-assembles a high level "frame" out of it then merges down. this could allow rendering individual passes of complex scenes in less time, but doesn't get you a final product any quicker. Maybe as an option later, not going to do or suggest that now :)

Let me know what you think and I'll throw up another PR. Also, tell me if you prefer I talk things through before submitting or not. can always adjust or throw away code as well.

oh wait, maybe rays/sec sounds cooler than pixels/sec :)

edit: also maybe "rays per pixel" instead of frame limit? saw that metric in a few places online

While I agree "rays/pixel" sounds cool, "samples/pixel" is more accurate than "rays/pixel" because a given sample is built from 1...N rays :)

I've probably named render/sample poorly, since "sample" can mean "sample of entire frame" or "sample of single pixel." It might be clearer to name it render/layer or something, since it's one layer of a frame that's merged with other layers to converge to an accurate image.

That would give a clearer mental model, like:

width * height samples = 1 layer; N layers = 1 frame, 1 frame at a given point in time => 1 image

I've previously tried the rows/columns with workers and changed to full frames largely for simplicity. Frames also yield less communication overhead (and so finish faster). I wouldn't mind going back to a tiling system as long as we could do it without adding much complexity.

Since Frame.Sample() already returns the total number of samples, your second idea sounds like the simplest.

Makes sense, thanks!

I'll go with the simple route for now :) Want to get the big picture before fiddling with things like frames/etc. Pretty sure I can come up with a sliced model with low or no communication overhead, I'll let it bake for a while.

Longer term (once slicing/etc is more static) getting exact pass limits is handy, since combining that with seeding the random numbers for the ray traces would allow you to regenerate the same image exactly, allowing easier or automated comparisons while tweaking code or camera options.