|
![](/i/fill.gif) |
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.
Post a reply to this message
|
![](/i/fill.gif) |