POV-Ray : Newsgroups : povray.programming : [Patch] Another radical idea -- isosurface function normals : [Patch] Another radical idea -- isosurface function normals Server Time
28 Jul 2024 20:25:17 EDT (-0400)
  [Patch] Another radical idea -- isosurface function normals  
From: Lummox JR
Date: 11 Jul 1999 01:17:48
Message: <37882911.1B00@aol.com>
My isoblob folly has gone along reasonably well, though I've had a
little trouble with the surface normals. Some of the normals seem to be
rather off from their expected values, still.
Anyway, I got to thinking: Normal calculation in an isoblob is done in
much the same way an isosurface does it: It looks at nearby values of
the function, and decides which way to point the x, y, and z coordinates
of the normal based on that. Makes sense, but there's a better way.

The isosurface function module was created with two types of
calculation: An ordinary function value at a given set of x,y,z
coordinates, and an interval calculation--used to solve for the
function's zeroes--expressing the minimum and maximum possible values
given a certain input of variables.
Why not make it possible to calculate the function normal at a given
point?
All this will take is a little calculus, and I've already worked out the
formulas needed to do it. Most of it, that is--noise3d() will need some
more careful work to get an accurate normal.
The idea is quite simple: A normal is calculated by partial derivatives,
and every function or variable or constant can have its derivative
calculated. With the chain rule thrown in, things get really simple. For
example:

d(x+y)=dx+dy
d(x*y)=y*dx+x*dy

If x represents a <1,0,0> in the normal stack value, and y is a <0,1,0>,
then an addition operation can add the two normals together, and a
multiplication can use the formula above, applying the actual values of
x and y to multiply by the two different normals.
More concisely:

Operator stack: x y +
(Assume <3,4,5> is the point to evaluate.)

Operation       Calc stack     Normal stack
x               3              <1,0,0>
y               4              <0,1,0>
*               12             <4,3,0>   // y*dx + x*dy

The beauty of this stack method is that this normal stack carries the
actual derivitave of (x*y), so any function that uses (x*y) as a value
can use not only the value itself (12), but also its derivitive for the
chain rule.
So, (x+y)*z would look like this:

Operation       Calc stack     Normal stack
x               3              <1,0,0>
y               4              <0,1,0>
+               7              <1,1,0>  // d(x+y) = dx+dy
z               5              <0,0,1>
*               35             <5,5,7>  // z*d(x+y) + (x+y)*dz

To verify it, try x*z+y*z:

Operation       Calc stack     Normal stack
x               3              <1,0,0>
z               5              <0,0,1>
*               15             <5,0,3>   // z*dx + x*dz
y               4              <0,1,0>
z               5              <0,0,1>
*               20             <0,5,4>   // z*dy + y*dz
+               35             <5,5,7>   // add tops of stack

The main drawback is that standard vector multiplication won't do,
because r, s, t, u, and v are also possible variables (the isoblob uses
<r,s,t>). Including the standard <x,y,z>, that's eight partial
derivatives to keep track of. This means the calculation stack is 9x the
size, for all intents and purposes--but most of the calculation done
with the excess is mere multiplication and addition.
The main advantages are these: The function only needs to be evaluated
once, at the point of intersection, instead of four times (as in the
isosurface normal routine), *and* it's completely accurate. The only
exception, as I mentioned, was noise3d(), which doesn't have an
easy-to-find normal; better to fudge that one.
All this can be done fairly smoothly by modifying f_func.c and its
support files. A few quick #define statements can take care of the task
of handling 8 different derivatives at a time, too, treating the bunch
as a giant 8-dimensional vector. I may get started on this shortly,
since it could be the salvation of the isoblob.
Interesting concept, no?

Lummox JR


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.