POV-Ray : Newsgroups : povray.pov4.discussion.general : On surface normal calculation and perturbation Server Time16 Sep 2024 04:49:14 EDT (-0400)
 On surface normal calculation and perturbation (Message 1 to 2 of 2)
 From: Bald Eagle Subject: On surface normal calculation and perturbation Date: 13 Nov 2023 21:30:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.6552db6d61b9f4951f9dae3025979125%40news.povray.org",
"headline": "On surface normal calculation and perturbation",
"dateCreated": "2023-11-14T02:30:00+00:00",
"datePublished": "2023-11-14T02:30:00+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
So, William Pokorny's recent experiments / bug eradication in the yuqk fork
reminded me of a discussion we had about 2 years ago concerning POV-Ray's
internal handling of surface normals, and how they get perturbed by the various
normal patterns.

clipka briefly touched on this:
https://news.povray.org/povray.general/message/%3C5c45e632%241%40news.povray.org%3E/#%3C5c45e632%241%40news.povray.org%
3E

"When plugging in a pattern into a normal, the normal is computed by
first sampling the pattern at four points in 3D space, from that
computing the gradient of the pattern in 3D space, and from that
computing how to perturb the normal. The four samples are always taken
at fixed offsets relative to the intersection points, distributed in a
tetrahedral arrangement."

But I'm still mystified how applying a scalar value to a normal (vector) changes
the direction of the normal.  This is apparently the basis of how surface
normals are simulated in the raytracer, but neither myself nor WFP exactly
understand how it all works.  All the vectors sum to <0, 0, 0>, and we can't
seem to determine where the anisotropy gets introduced.

In trying to figure this out, I stumbled upon:

https://iquilezles.org/articles/normalsSDF/

Which attempts to explain it a bit too briefly, but the result seems to be that
after terms cancel, one gets directional gradients of the function, the vector
sum of which is the normal vector to the surface.

I was unable to find any other mention of this method, so I have an email out
trying to find the origin of this technique, and hopefully the
technical/mathematical details of how it works.

Maybe TOK has the key to this.  :)

I hastily scribbled out a scene that uses the method to compute the normal of a
simple sine-wave function, and plots the normal vectors on the surface.  It
seems like it mostly works, but some of the normals are wrong.
(it almost seems like if the sides of the valleys were switched, and the signs
of the normals were reversed, then the wrong normals would be corrected)
I'll have to superimpose a trace () result onto this for comparison.

Rendering a visualization of the tetrahedral vectors and coloring them by vertex
coordinates suggested that 3 of the vectors are pseudo-cardinal vectors, and the
remaining vector is the inverse of their vector sum.  (Center cube)

Shifting the reference point/origin to <-1, -1, -1> shows what I mean. (Right
cube)

I don't presently know what that all means, but hopefully it spurs some ideas.

https://j3l7h.de/talks/2008-02-18_Care_and_Feeding_of_Normal_Vectors.pdf
```

Attachments:

Preview of image 'pyramidnormal.png'

 From: Bald Eagle Subject: Re: On surface normal calculation and perturbation Date: 14 Nov 2023 19:50:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.65541523bbd63a0f1f9dae3025979125%40news.povray.org",
"headline": "Re: On surface normal calculation and perturbation",
"dateCreated": "2023-11-15T00:50:00+00:00",
"datePublished": "2023-11-15T00:50:00+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
So, one of the things that I noticed, looking at this with fresh eyes, is that
I'm probably not doing the whole

ki * f (p + h*ki)

part correctly.

I'm not sure how to take a simple function like f(x) = sin (x) and plug a vector
into that.

do I just use the x components of the ki vectors?

I'm getting errors for trying to normalize a zero-length vector that way...
```