erichlof/THREE.js-PathTracing-Renderer

License ?

suprafun opened this issue · 16 comments

Hello, under what license is this amazing project released under ? I would like to really study it and learn more about path tracing from it. Thank-you.

@suprafun
Thank you for the compliment! I am glad and humbled you want to learn from my project. To answer your question about license, I don't really have a license for it. I value open source: I have learned a lot from other people's source and I want to just put my work out there for people to enjoy and learn from or use (it's my way of giving back to the open source community). I've never been one for licensing and legalities, although I might end up putting the free common license somewhere on this project page because multiple people have asked me about licensing.

Feel free to use my code how you want to. The code is a mix of my own ideas, work/style, etc. and other people's ideas in classic ray tracing textbooks from Peter Shirley and various coders on Shadertoy for example. Some of it is either copied or inspired by others. I have tried to include detailed credits to those I have borrowed from. Likewise if you end up using some of my code, I would appreciate a credit somewhere in the code comments or something like that.

Have fun with the project code! I have enjoyed working on it for 4+ years now (wow time flies!), and I hope you enjoy using it as well!
-Erich

dafhi commented

I agree; this project is amazing. I've recently begun reading and porting Peter Shirley's ideas to FreeBASIC. Three.js-PT will be somewhere down the line. Truly the best caustics I've seen

@dafhi
Thank you! Yes Peter Shirley is a ray tracing icon - if you enjoyed his Ray tracing in 1 weekend digital books, you would probably like his older paperback Realistic Ray Tracing, 2nd edition. It has a lot of the core ideas of rendering: much of his code was used by Kevin Beason in his smallpt (which I in turn started this whole project on in the beginning), and his ideas and methods have been adopted even in the early Brigade path tracers if I'm not mistaken. You have to get a used copy of that book maybe on Amazon, because I don't think it's available digitally like his other more recent books. But it has a lot of gold nuggets for rendering, some of which are incorporated into my project (the Tent filter, for example).

Thanks for the compliment about caustics. Caustics are the thorn-in-the-side of path tracers, lol. I've tried to speed things up with a few tricks like on the Cornell box (mirror caustics) and the Volumetric rendering scene (refracted caustics). There are other solutions like bi-directional and photon mapping to try to help, but real-time converged caustics at 60 fps is still a ways off, until we get even more cores on our GPUs.

Good luck with your freeBASIC pt; that sounds fun and challenging!
-Erich

dafhi commented

His older book sounds like a good read.

I developed a novel Russian roulette technique

Roulette = .1 (or whatever)
iRoulette = 1 / Roulette

Retrace hit point (iRoulette - 1) times
return radiance * iRoulette / (iRoulette - 1)

@dafhi
Cool, is the Roulette variable (0.1 in the example) chosen randomly each pass? How is the element of chance introduced into your algorithm? Just curious, it looks interesting. Thanks for sharing :)

dafhi commented

Great questions. Actually I have 12 randomized elements, but not Roulette

  int iRoulette = 10

  if rnd < 1 / iRoulette
    loop iRoulette - 1
      trace depth + 1
    radiance *= iRoulette / ( iRoulette - 1 )

randomized elements were mostly pre-calculated by a weight randomizer and evaluator.
score was simply the total pixel iteration sum, relevant because a small % of pixels get the attention, with an importance map being recalculated every 15 to 25 frames

dafhi commented

correction

int iRoulette = 4  // value I used

if RND >= 1 / iRoulette: return radiance * (iRoulette)/(iRoulette-1)
loop iRoulette - 1
  trace radiance, depth + 1

@dafhi
Oh nice! I think I understand a little better now.
Actually I could see your algo working well for a more traditional CPU (offline) renderer. The only issue I see with using it on a real-time GPU renderer is that there might be divergent threads due to the conditional 'trace' (branching function). In other words, some pixels will rightly be killed off by the Russian Roulette algo - but others who passed the test will go on tracing. While they are continuing tracing, the ones that got killed off will have to idly wait for the still-active threads to finish their tracing. Sometimes this can impact GPU performance because not all threads are working on something at the same time. And as we all have heard, GPUs like to do the same thing on all threads at the same time if possible (at least that's my simplified understanding, ha ha).

Because of this issue I have slightly biased my own renderer as a trade off for GPU thread occupancy. In other words, if you look at the bounces loop in each fragment shader, the rays are first cast from the camera on bounce 0, then on bounce 1 they fly off the various scene surfaces in all directions (this is where all path tracers (mine included) cannot avoid pixel divergence, and they continue the bouncing loop until either max bounces is reached, or they hit nothing (INFINITY), or they hit a light source (hopefully!). But you see how they all march forward at the same time, step by step, or bounce by bounce - first the ray cast, then first reflection (or refraction), then 2nd reflection (or refraction), and so on, in lock-step. I got this idea from the old Brigade path tracer pdf research paper.

It is possible to side-step the occupancy problem I mentioned, by something called 'path restart' or 'ray regen' (I can't remember exactly). In this scenario, the GPU keeps track of how active all the threads are, and if some of them have been killed off early, or bounced into INFINITY, they restart the ray from a previous known hitpoint on an earlier surface. I sort of do something similar - if you take a look at the Geometry_Showcase bounces loop, you can see how I give extra work to the pixels that have nothing to do ( if they hit INFINITY, or they hit a light source, or a maximum reflection bounce level has been reached). I assign to the diffuse surfaces a shadow ray, then they go off and do that for 1 more bounce. Usually everything gets done around the same time and the convergence is a little better. The rays that had a ton of work to do in the beginning because they hit some fancy glass object are finally done around the time that the early exited rays have done their extra homework of casting a shadowray. But it does introduce more complexity in the tight GPU bounces loop - so it's always a balancing act! lol

Thanks for sharing, let me know if you get it up and running.
-Erich

dafhi commented

Wow interesting! yeah I have a measly single-threaded CPU thing with only spheres & no accel. And yet, it is 1K lines of code. That's why I'm going through "Ray Tracing in one Weekend" xD .. My PT's been operational since 2016. I'll whip up .exe's of my weight randomizer and test scene. The randomizer generates a text file which my PT will utilize if exists. Assuming you can run .exe files.

My PT hasn't used Russian roulette for some time but I'm gonna stick it back in. And I think the logic I posted is wrong again. Off to try and figure this thing out

dafhi commented

now I remember the roulette thing.

"dim chance of a retrace."
to compensate, multiply the radiance if there actually was a trace

my idea was to trace multiple times so the multiplier could be reduced. adding that in now

@dafhi
Thanks for sharing..I was able to briefly run the 1st .exe but darn Windows 10 / Norton is so cautious with downloaded .exe's that it removed it from my computer while it was in the middle of running! But what I did see for a brief moment looked cool! Please share the link if you get a dedicated repo for your project up and running. It might be better if we can somehow build the project ourselves so that our software defenders don't go nuts about the downloaded .exe's, lol.

Thanks again, and good luck on your project!

@dafhi
To avoid derailing the op's original issue too much here, I have opened a new thread on your own repo. See you over there! ;-)

Hi ! First of all congrats for your amazing work, this renderer is awesome !
If you permit it I would like to use it in the jewlery viewer I'm developing as an alternative rendering option.

Therefore I'm chiming in about the license. I read above that you want this project to be open-source and to allow everyone to learn from it and use it, but if you don't define a license it won't be possible to do that legally.

Without a license, regular copywrite applies. If tomorrow you want to sue somebody for using your technology in a commercial project, you are entitled to do so... Therefore it's quite dangerous for us to use it, even if you said in a issue on Github somewhere that you are willing to share it.

I would suggest at least Creative Commons Zero v1.0 Universal, which you can add in two clicks via Github. With this license we are in right to use it freely, we have the insurance that we can at least use the current version of your software without fearing any future legal challenge, but we have to credit the author ( you ) in any project using it. This way you ensure some traction for your project and yourself, while keeping it open as you wished. You may decide in the future to revert to MIT license, which would just remove the obligation for users to credit you.

Once again, congrats for your work, it's amazingly fast and beautiful and I do think this should be merged into three.js at some point.

@felixmariotto

Hi Felix! Thank you for the kind words. Yes of course you can use my code or parts of my code for your jewelry viewer. That sounds like a cool project - good luck! :)

Also thank you very much for your detailed description and arguments for me adding a license. I must admit I was kind of ignorant about the whole licensing situation. But with your helpful insight, I see now why it is important to put my intentions and permissions in writing somewhere on my repository.

I have taken your suggestion to heart and I have not only added a Creative Commons Zero v1.0 Universal license to this repository, I also went back and added one to all of my old repositories as well!

Thanks again for the kind words and helpful suggestions/arguments for adding this. Hopefully everything is in place now so everyone can use my project code how they like and/or learn some aspects of rendering from it.

Take care,
-Erich

Thank you ! Best of luck !