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

Support for a THREE.ParametricGeometry #78

Open
yure-r opened this issue Apr 29, 2023 · 1 comment
Open

Support for a THREE.ParametricGeometry #78

yure-r opened this issue Apr 29, 2023 · 1 comment

Comments

@yure-r
Copy link

yure-r commented Apr 29, 2023

Hello Erich!!

I noticed you have equivalent functions to generate spheres and cubes, but what about an implementation of a custom parametric function that is rendered as a 3D geometry?

https://laustep.github.io/stlahblog/frames/threejs_RosesBouquet.html

^I've been working on a really involved project using parametric 3D flowers and I was wondering how you'd go about rendering those in your pathtracer without triangles? or if that's even possible 👀?

Please let me know!! I'm so excited to see the progress you've made so far and your renderer is amazing!!

thank you!!

@erichlof
Copy link
Owner

erichlof commented May 2, 2023

Hello @yure-r !
Thank you for the kind words. The Roses bouquet demo is really cool! The petals have a beautiful, organic shape. Speaking of shapes like these, I'm afraid I don't have much experience in ray tracing parametric 3D geometry. You asked if these shapes were possible with my renderer - sadly, not as of yet.

If you'll allow me, I can explain further why I haven't yet tackled this type of geometry for my ray/path tracer. Forgive me if you already know what I'm about to say, but basically ray casting any shapes other than planes, triangles, boxes, and the family of quadrics (spheres, cylinders, cones, paraboloids, etc.) is not only expensive, it can also be numerically unstable and unpredictable with visual artifacts (such as holes and surface tearing). If you look at my PathTracingCommon.js file, which contains the various ray vs. *(insert your favorite shape here) that I've collected/or implemented over the years, you'll likely notice that these routines stay within the confines of simpler shapes with well-known analytical solutions. For instance, all of the quadrics don't go above degree 2, and therefore have a nice analytical quadratic equation to solve for t at the end, which computers can easily do, and even us humans could do with pencil and paper if we had to, like back in high school, lol.

But then we have something like the famous Torus shape which is used heavily in certain areas of computer graphics. The problem is that this seemingly simple donut shape is quartic, or of degree 4. If you look at my source code to intersect a ray with a torus, you'll see that it is over a hundred lines long of complex shader code with multiple contributing functions (as opposed to 6 lines of code for a sphere, ha). Even with all that, I don't fully trust it, lol - it is a black box to me that I lifted off of a math whiz over on ShaderToy (who I give credit to in my copied code). If it stopped working one day, I wouldn't know how to fix it. Even though this bothers me, because I like knowing how every line in my codebase works and what it's purpose is, I've had to come to terms with the fact that I will probably never understand how to solve a quartic equation of degree 4. In fact, it bothers me so much that for weeks I have been working on my own "poor man's" torus intersection routine that doesn't go above degree 2! I figured out a cool trick to combine a section of an elongated Ellipsoid that is chopped off at its top and bottom, and on the inside, I intersect a friendly quadric (degree 2) Hyperboloid (fat hourglass), that is chopped off in a similar manner at top and bottom, in order to exactly meet the outside Ellipsoid shell. There is a problem with the seams where the 2 cheap quadrics meet, but I'm working on smoothing out the sharp transition. Personally, I'd much rather use my own hacked version of a Torus, even with its slight artifacts, over the huge black box that solves the traditional quartic torus analytically and mysteriously. In other words, at least I know how it works under the hood, so I feel like I'm in control more of the algorithm and the situation.

Which brings us to your lovely rose petal shapes. If I had to guess, I would say that those shapes require at least a degree 3 polynomial, or cubic equation in t. That's probably too conservative of an estimate- it might require higher degrees than that. Now assuming you didn't have to go above degree 3 for the curved surfaces, there are cubic solvers out there. But once again, numeric precision and shader complexity rear their ugly heads. For instance, in the monumental quartic solver, there is a whole section for 'polishing' the roots - otherwise we get numerous artifacts. I assume the same would need to be done with anything higher than degree 2 simple quadric shapes (which have a nice, closed form, stable solution).

However, all that being said, if you really want to render these shapes faithfully and accurately with some kind of Ray or path tracing, there are a couple of ways you could do it. The 1st is, as you probably guessed, bringing the shapes into a program like Blender, and triangulating everything. I know you wanted to be more pure about it, but with a decent stock triangle BVH accelerator, you could probably ray trace all the flowers in your demo in real time, even on mobile. The 2nd way is still a little of a black art: namely turning every rose petal into an SDF (Signed Distance Field) and 'warping' the 3D space around the petals. Then, rather than doing a possibly unstable, expensive, analytical single ray cast, you would incrementally ray-'march' several steps into the SDF of each petal. This alternative has its positives and negatives - on the plus side, you can ray march almost any imaginable shape, even with no known closed form analytical solutions, cheaply (as the legendary Inigo Quilez (iq) has proven) on ShaderToy. The negative is that ray marching takes much more time, especially around the edges of the petals where the marching ray origins get really close, but just miss and continue on to the background of the scene. Again, you can find numerous SDF flower examples on ShaderToy- some of which are very convincing.

So that was my very long way of saying - no unfortunately, the flower petals cannot be rendered as pure, non-trianglular shapes with my path tracer, but all is not lost if you look to other possible solutions.

Hope this helps, and again, apologies if you already knew some of these renderering/math-related issues.

Cheers, 🙂
-Erich

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants