|
|
Mike Williams <mik### [at] nospamplease> wrote:
: Black outline in smooth meshes
: (The outline of smooth meshes exhibit black dots or areas (which go away
: with double_illuminate))
: http://news.povray.org/3bf6794e$1@news.povray.org
: Heightfield bug (most probably an inverted normals problem)
: http://news.povray.org/3c4ca8ff@news.povray.org
AFAIK these two are symptoms of the same problem, which I discussed in the
latter thread.
It's not really a bug in smooth meshes nor in heighfields (they work
flawlessly in this context, ie. they always return the correct normal), but
the problem (not really a bug, as it's not a programming mistake) is at a
higher level.
The problem happens when the actual surface normal is pointing at the
incoming ray (ie. the angle between the incoming ray vector and the surface
normal vector is >90 degrees) but the object returns a normal vector which
points away from the incoming ray (ie. the angle is <90). This happens in
certain cases in smooth heighfields and smooth meshes.
The flaw is not in the heightfield or the mesh code: They return the correct
normal vector.
The flaw is in the calling routine, which inverts this normal vector if it
sees that its angle is <90 with respect to the ray vector.
This inversion is essential for the lighting to work and it's ok when the
object returns the actual surface normal.
However, this inversion routine does not take into account that the normal
returned by the object may not be the actual surface normal, but a perturbed
normal. It *assumes* that the normal vector the object returns is the actual
surface normal. This is the flaw.
The only solution I can think of is that this routine does not perform the
inversion if the condition described above is fullfilled. (And I think that
it has to be checked in both ways, as it has to work with the same idea also
when the ray hits the object from inside.) Thus, the normal inversion routine
would need to do something like this:
if(weWantToInvertTheNormal &&
dotproduct(Ray,RealNormal)*dotproduct(Ray,ReturnedNormal) >= 0)
{
invert(ReturnedNormal)
}
The problem is that the object does not return the real normal of the surface
but just the perturbed one. Thus the inversion routine can't do that.
To fix this problem, it would be necessary to somehow get the real surface
normal from the object.
This is probably something that will be possible (in a nice way) only in
povray 4, where the whole code is rewritten (as it's completely rewritten, then
this kind of thing can be taken into account).
--
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -
Post a reply to this message
|
|