POV-Ray : Newsgroups : povray.programming : Shading idea (to correct an annoying artifact) : Shading idea (to correct an annoying artifact) Server Time
28 Jul 2024 16:25:39 EDT (-0400)
  Shading idea (to correct an annoying artifact)  
From: Nieminen Juha
Date: 28 Dec 1999 15:33:32
Message: <38691e9c@news.povray.org>
The following scene calculates a sphere made of smooth_triangles. The
shading of the surface is smooth and we would expect that the shadow line
would be as with a real sphere. However we can see really annoying square
artifacts in the shadow line.

===========================================================================
camera { location -z*40 look_at 0 angle 35 }
light_source { <1500,2000,-500> 1 }
light_source { <-1500,-2000,-100> x*.4 }
background { rgb z }

mesh
{ #declare ang1=0;
  #while(ang1<pi)
    #declare nang1=ang1+pi/8;
    #declare ang2=0;
    #while(ang2<2*pi)
      #declare nang2=ang2+pi/8;
      #declare p1=<cos(ang2)*sin(ang1), cos(ang1), sin(ang2)*sin(ang1)>*7;
      #declare p2=<cos(nang2)*sin(ang1), cos(ang1), sin(nang2)*sin(ang1)>*7;
      #declare p3=<cos(nang2)*sin(nang1), cos(nang1), sin(nang2)*sin(nang1)>*7;
      #declare p4=<cos(ang2)*sin(nang1), cos(nang1), sin(ang2)*sin(nang1)>*7;
      smooth_triangle { p1,p1,p2,p2,p3,p3 }
      smooth_triangle { p1,p1,p3,p3,p4,p4 }
      #declare ang2=nang2;
    #end
    #declare ang1=nang1;
  #end
  pigment { rgb <1,1> } finish { specular .5 }
}
===========================================================================

  One could think that it's a bug.
  It isn't. It's not really povray's fault but is a consequence of the way
shadows are calculated. If we make the mesh shadowless, the shadow line will
be as expected. Try adding 'no_shadow' to the mesh block and you will see it.
  This problem is related to the normals not being the true normals of the
surface, but modified ones.
  This same artifact can be recreated with regular normal modifiers:
  In the following scene there are two spheres. The sphere at the right is
made of torii, so the shape of the surface is real. The sphere at the left
is a regular sphere with a normal modifier, so the shape of the surface is
fake.
  We can notice that the shadow line in the left sphere is straight and very
wrong looking. What we would expect is something like in the right sphere.
Again, adding the 'no_shadow' keyword to the first sphere gives us the
result we are expecting. Try it.

===========================================================================
camera { location -z*40 look_at 0 angle 35 }
light_source { <1500,2000,-500> 1 }
light_source { <-1500,-2000,-100> x*.4 }
background { rgb z }

sphere
{ 0,5
  pigment { rgb <1,1> } finish { specular .5 }
  normal
  { gradient y 2 slope_map
    { [0 <0,1>][.5 <1,0>][1 <0,-1>]
    }
  }
  translate -x*6
}
union
{ #declare ind=-4.5;
  #while(ind<=5)
    torus { 4.5*sqrt(1-ind*ind/25), .55 translate y*ind }
    #declare ind=ind+1;
  #end
  pigment { rgb <1,1> } finish { specular .5 }
  translate x*6
}
===========================================================================

  This problem can be seen in many images, even extremely high-quality ones,
for example http://oz.irtc.org/ftp/pub/stills/1998-10-31/running.jpg
  In this IRTC winner image we can notice the wrong-looking straight shadow
lines on the rocks (specially the one at the most foreground).
  'no_shadow' could have corrected this problem there, but it may had have
some unwanted effects because the rocks would not cast shadows anymore.

  So what's happening here?
  As I said, the problem is that the normal of the surface is not pointing
in the perpendicular direction of the surface, but it's modified to point
somewhere else. This is done to add a shape to the surface which isn't
really there; only the shading makes it look like it is there (this is
usually cheaper than actually adding that shape to the surface with, for
example, triangle meshes).
  The problem arises when the actual normal of the surface points away from
the light while the modified normal points at the light. If there was no
normal modifier, that point would be in the shadow, but the modified normal
makes it lit.
  When the actual normal of the surface points away from the light source,
we are actually on the "other side" of the object, ie the part of the object
that is not lit by the light source.
  Since most objects are closed surfaces, this means that there's already at
least one surface between the current point and the light source (think
about a point in the non-lit part of a sphere).
  What is happening here is that this surface is shadowing the current
point we are shading. So it doesn't matter if the normal is pointing at
the light: the point is not lit because the surface "at the other" side is
shadowing it.
  This is why making the object shadowless helps the situation. The other
surface stops shadowing the current point and thus we get the expected
shading. Of course this has the side-effect that the object stops completely
casting shadows, which is often the unwanted result.

  This can be a big problem sometimes. Smooth triangle meshes can have odd
shadow lines which are very ugly (I have experienced this problem many times).
  Can this problem be fixed?

  Answer: I'm not sure, but I have an idea. Perhaps someone could give it a
try?
  The shading could be calculated this way:
  If the actual normal of the surface is pointing away from the light source
while the modified normal is pointing at it, then we ignore the first
intersection of the current object and the shadow ray calculated for this
point.
  Any comments?

-- 
main(i,_){for(_?--i,main(i+2,"FhhQHFIJD|FQTITFN]zRFHhhTBFHhhTBFysdB"[i]
):5;i&&_>1;printf("%s",_-70?_&1?"[]":" ":(_=0,"\n")),_/=2);} /*- Warp -*/


Post a reply to this message

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