POV-Ray : Newsgroups : povray.general : normal average bug (?) in beta6 : Re: normal average bug (?) in beta6 Server Time
13 Aug 2024 13:19:20 EDT (-0400)
  Re: normal average bug (?) in beta6  
From: Darius Davis
Date: 4 Sep 1998 04:02:36
Message: <35F07F51.1740@acm.org>
> : Please provide more details
> : (in terms of POV files that work and some that show the bug) and I'll do
> : my best to track it down.

Hi all,

I had the same problem a while ago, and I didn't bother to chase it up. 
After reading this, I sat down and actually found the bug (or at least I
think so - the test images now trace correctly!).

OK, to fix this problem of normals being reversed (sometimes):

LIGHTING.C, function compute_lighted_texture (about line 2502 in v3.02):

Move the following five lines of code (marked |):

 |  if ((opts.Quality_Flags & Q_NORMAL) && (Layer->Tnormal != NULL))
 |  {
 |    Perturb_Normal(Layer_Normal, Layer->Tnormal, IPoint);
 |  }
 |
    /* If the surface normal points away, flip its direction. */

    VDot(Normal_Direction, Layer_Normal, Ray->Direction);

    if (Normal_Direction > 0.0)
    {
      VScaleEq(Layer_Normal, -1.0);
    }

a bit further down, so it now reads:

    /* If the surface normal points away, flip its direction. */

    VDot(Normal_Direction, Layer_Normal, Ray->Direction);

    if (Normal_Direction > 0.0)
    {
      VScaleEq(Layer_Normal, -1.0);
    }

 |  if ((opts.Quality_Flags & Q_NORMAL) && (Layer->Tnormal != NULL))
 |  {
 |    Perturb_Normal(Layer_Normal, Layer->Tnormal, IPoint);
 |  }
 |

and now these images will trace correctly.  The problem arises when,
following the normal perturbation, the apparent surface normal actually
points more than 90 degrees away from the vector of the ray currently
being traced (as happens in the failing parts of Nathan Kopp's source
file, where the ray strikes one of the sharply sloped parts of the
slope_map).  In that event, the surface normal vector is incorrectly
reversed so that it now points *into* the box.  Later code then
eliminates the calculation of diffused light on that surface since the
normal is now pointing away from the *light source*.  Interestingly, the
lower of the two panels traces correctly because of a piece of code in
PARSE.C function Post_Process:

    if (Object->Texture->Type == PLAIN_PATTERN)
      if (Object->Texture->Tnormal != NULL)
        Object->Type |= DOUBLE_ILLUMINATE;

The bottom panel has a PLAIN_PATTERN texture and hence has the
DOUBLE_ILLUMINATE flag set, where the top panel does not receive the
flag (it has an AVERAGE_PATTERN texture).  DOUBLE_ILLUMINATE instructs
POV-Ray to illuminate the back face of objects, and as a result of this,
the reversed normal has no effect on the tracing of the lower panel. 
The top panel doesn't have DOUBLE_ILLUMINATE set, and hence the reversed
normal prevents the diffuse lighting calculations from completing.

Those three lines from Post_Process don't appear to be necessary once
compute_lighted_texture is fixed.

I have noticed the definition of DOUBLE_ILLUMINATE in OBJECT.H describes
its use: "Illuminate both sides of surface to avoid normal purturb
bug".  I wonder if what I've found is the normal perturb bug this refers
to?

DOUBLE_ILLUMINATE is used elsewhere in the code for 'smooth' Height
Fields - I'm not sure how the changes I have described may affect HFs or
any other objects.  Please let me know if it causes any problems... I'd
appreciate some help with testing and verifying this.

For the interested, I've attached below a slightly modified version of
Nathan Kopp's sample image which demonstrates the bug even more simply
(BTW, thanks Nathan, that scene file was what I used for the debugging),
and another very short scene file to demonstrate it extremely clearly.

Cheers,

Darius Davis
Dar### [at] acmorg

-------------------------------------------------------------------------------------------

// Average normal bug test.
// Lower box shows ordinary normal map, upper box averaged one (buggy)
camera { location <-5,0,-2> look_at <0,0,0> angle 35 }
light_source { <0,0,-1> color 1 }
#declare TestNormal=
normal
{ gradient x 1
  slope_map
  { [0 <0,0>] [.2 <0,0>] [.2 <0,1>] [.4 <1,1>] [.4 <1,0>]
    [.6 <1,0>] [.6 <1,-1>] [.8 <0,-1>] [.8 <0,0>] [1 <0,0>]
  }
}
#declare TestTexture=texture { pigment { rgb 1 } normal { TestNormal } }
// Simply placing the identical texture within an 'average' texture
makes the bug evident!
#declare TestAverage=
texture
{ average texture_map
  { [TestTexture] }
}
box { <-2.5,.05,0><5,2,.1> texture { TestAverage scale 2} }
box { <-2.5,-.05,0><5,-2,.1> texture { TestTexture scale 2} }

--------------------------------

// another quick, separate self-contained scene file to demonstrate bug
    sphere {2*z, 0.9 texture {pigment {color rgb <1, 0, 0.5>} normal
{crackle 5 scale 0.1}}}
    light_source {<-5, 5, -3> color rgb 1}

--------------------------------


Post a reply to this message

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