|
|
On 05/05/2024 00:48, William F Pokorny wrote:
> On 5/4/24 13:13, kurtz le pirate wrote:
>> What justifies such a gigantic max_gradient?
>
> Multiplication in an isosurface function tends to be a bad choice(*).
>
> Even with linear functions you have values larger than 1.0 some distance
> away from the surface roots. You are multiplying six torus equations and
> suppose at a distance a few units away from the cluster they all have a
> value of 10. So the equation's values are as high as 10^6 - at distance.
>
> Now think about what happens at each root. The values for one of the six
> tori rapidly approaches zero and at zero the entire equation winks to
> zero before climbing rapidly again out of the negative value region.
> Though the values near the roots will be < 1.0, the change from very
> large values to and from the root as the ray travels, will be rapid.
>
> Change your equation to:
>
> min(
> (sq(sqrt(x*x + y*y) - 3) + z*z - 0.4 ),
> (sq(sqrt((x - 4.5)*(x - 4.5) + z*z) - 3) + y*y - 0.4),
> (sq(sqrt((x + 4.5)*(x + 4.5) + z*z) - 3) + y*y - 0.4),
> (sq(sqrt((y + 4.5)*(y + 4.5) + z*z) - 3) + x*x - 0.4),
> (sq(sqrt((y - 4.5)*(y - 4.5) + z*z) - 3) + x*x - 0.4),
> (sq(sqrt(x*x + y*y) - 5) + z*z - 0.4 )
> )
>
> And the gradients will be much lower. Note, however, the value fields
> now overlap each other so there will minor-ish discontinuities due this.
> It's often the case you can cheat lower than the reported max gradient
> when using min() or max(). These sorts of value "discontinuities" are
> more like seams (inflections in values) away from the roots - and they
> don't matter that much so long as you set the gradient (sampling rate)
> high enough to not miss any roots(**) as the solver runs.
>
> (*) - The yuqk fork implemented an f_cbrt() inbuilt function wrapping
> C++'s std::cbrt(). This can wrap functions with high gradients in one or
> more cube roots which lowers the effective gradient as seen by the
> solver. (Sometimes, using multiplication is handy. Yes, I lie all the
> time... :-) )
>
> (**) - This why the yuqk fork added the 'report on|off' keyword to the
> isosurface{}. The gradient warnings can be turned off for particular
> isosurfaces, if the isosurface is otherwise rendering fine with a
> gradient lower than the actual max gradient.
>
> Bill P.
>
>
> Aside: I've been thinking some about the isosurface{} feature of late.
> Maybe adding options to return only the containing shape's clipped roots
> - it would be the opposite of 'open'(***). Further, perhaps an option to
> return only a range of all the roots found. This would let us break
> apart the surfaces in a way would allow flexible texturing and offer a
> way to gradually see isosurface{}s layer by layer, so to speak.
>
> (***) - Having a complement keyword to 'open', I suppose, could apply to
> all shapes supporting 'open' today? It would make texturing clipped
> parts in ways completely different than the sides of those shapes much
> easier.
>
Your explanation is clear. Well done.
Well, it's true that this kind of equation is rather special and
contains a lot of "empty space".
Multiplying isosurfaces is generally used to make blobs. No need here.
On the other hand, the min() function is the equivalent of union{} and
is much better adapted.
Without changing the value of max_gradient (3e10) and just by adding the
min() in my function, POV finds say : "The maximum gradient found was
4235539.500, but max_gradient of the isosurface was set to
30000001024.000...".
Thanks
--
Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message
|
|