POV-Ray : Newsgroups : povray.programming : Shading idea (to correct an annoying artifact) Server Time
25 Dec 2024 11:14:38 EST (-0500)
  Shading idea (to correct an annoying artifact) (Message 1 to 8 of 8)  
From: Nieminen Juha
Subject: Shading idea (to correct an annoying artifact)
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

From: Ron Parker
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 28 Dec 1999 15:38:56
Message: <386b1ed1.94879596@news.povray.org>
On 28 Dec 1999 15:33:32 -0500, Nieminen Juha
<war### [at] punarastascstutfi> wrote:

>  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?

One problem I can see is that it would be possible to create
pathological objects that might get shaded incorrectly as a result of
this workaround.  Non-closed, non-convex objects come to mind
immediately.  Perhaps we should make the workaround more explicit by
specifically having a "no self-shadowing" keyword?  Non-convex objects
still would act funny, but you could work around that if you needed to
by clever use of CSG.


Post a reply to this message

From: Nieminen Juha
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 29 Dec 1999 05:08:55
Message: <3869ddb7@news.povray.org>
Ron Parker <par### [at] fwicom> wrote:
: One problem I can see is that it would be possible to create
: pathological objects that might get shaded incorrectly as a result of
: this workaround.  Non-closed, non-convex objects come to mind
: immediately.  Perhaps we should make the workaround more explicit by
: specifically having a "no self-shadowing" keyword?  Non-convex objects
: still would act funny, but you could work around that if you needed to
: by clever use of CSG.

  Yes, I think that the fixed shading should be optional too.
  However, I don't think that a "no self-shadowing" option would be good
for this. Sometimes you really want the object to cast shadows on itself
(a cup of coffee comes immediately to my mind).
  I really think that this fix should be a separated option of its own and
that it should work the way I said.

-- 
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

From: Burton Radons
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 19 Jan 2000 04:47:43
Message: <3885887A.F393ECC7@pacificcoast.net>
Nieminen Juha wrote:
>   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.

I should've responded a few days ago but kept putting it off.

This solution would only compound the problem.  If you let the ray
ignore the first intersection, then it will be inside the sphere and
simply hit the other side going out, causing the same problem as
before.  Currently at least the transparency would work right, but if
the sphere were translucent, you would only see the one side filtering
the light in a band at the shadow line!

I think the only solution to this problem now and forever would be if
these faked surfaces were actually modeled.  I've been thinking that if
the point were moved after the intersection detected and that point
used, the place where the distorted normal actually works, then it would
avoid this shadow and allow other effects.  But I don't know how much
distortion that would leave on the objects.

For example, a polygon would be in two places at once.  An object
drawing close could "intersect" this virtual position and cause a
distinct shadow line long before it physically touches.  I'll add this
feature to my raytracer and leave it dead until I'm willing to play with
it.  Perhaps if the virtual distortion decreased as the angle between
the surface and the camera increased.  But then that would look like the
textures were not perspective correct.


Post a reply to this message

From: Nieminen Juha
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 19 Jan 2000 05:39:07
Message: <3885944b@news.povray.org>
Burton Radons <lot### [at] pacificcoastnet> wrote:
: This solution would only compound the problem.  If you let the ray
: ignore the first intersection, then it will be inside the sphere and
: simply hit the other side going out, causing the same problem as
: before.

  The solution was precisely to ignore that surface (ie. the first intersection
with the current object from the current point). So there's no such problem.

: Currently at least the transparency would work right, but if
: the sphere were translucent, you would only see the one side filtering
: the light in a band at the shadow line!

  The other side of the sphere either shadows the current point or it doesn't.
It doesn't matter if the surface is translucent or opaque (the only difference
will be in the coloring and strength of the shadow).

-- 
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

From: Burton Radons
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 19 Jan 2000 06:11:49
Message: <38859C2B.A2868EB0@pacificcoast.net>
Nieminen Juha wrote:
> 
> Burton Radons <lot### [at] pacificcoastnet> wrote:
> : This solution would only compound the problem.  If you let the ray
> : ignore the first intersection, then it will be inside the sphere and
> : simply hit the other side going out, causing the same problem as
> : before.
> 
>   The solution was precisely to ignore that surface (ie. the first intersection
> with the current object from the current point). So there's no such problem.

Sorry.  I was thinking of the first intersection as being the surface,
and therefore the cause of the shadow, but with the epsilon it should
pass through the intersected surface and hit the other side of the
object.  And of course, the surface is already taken into account for
the coloring and doesn't need to be filtered twice.

I can't think of any reason why your technique would fail.


Post a reply to this message

From: Nathan Kopp
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 19 Jan 2000 11:32:30
Message: <3885e71e@news.povray.org>
Burton Radons <lot### [at] pacificcoastnet> wrote ...
> Nieminen Juha wrote:
> >
> > Burton Radons <lot### [at] pacificcoastnet> wrote:
> > : This solution would only compound the problem.  If you let the ray
> > : ignore the first intersection, then it will be inside the sphere and
> > : simply hit the other side going out, causing the same problem as
> > : before.
> >
> >   The solution was precisely to ignore that surface (ie. the first
intersection
> > with the current object from the current point). So there's no such
problem.
>
> Sorry.  I was thinking of the first intersection as being the surface,
> and therefore the cause of the shadow, but with the epsilon it should
> pass through the intersected surface and hit the other side of the
> object.  And of course, the surface is already taken into account for
> the coloring and doesn't need to be filtered twice.
>
> I can't think of any reason why your technique would fail.

Actually, you brought up a good point. Media calculations (which have to
know whether a ray is inside or outside of a particular interior), and the
translucency calculations WOULD get confused by ignoring the first
intersection.  However, with fully-opaque objects, this should work.  Using
it as an option then allows users to apply it only in situations where it
would not cause strange problems.

Actually implementing this could prove quite difficult, unfortunately (due
to the shadow cache and the bounding box tree which have been implemented to
speed up shadow calculations).

-Nathan


Post a reply to this message

From: Nieminen Juha
Subject: Re: Shading idea (to correct an annoying artifact)
Date: 20 Jan 2000 02:58:16
Message: <3886c018@news.povray.org>
Nathan Kopp <Nat### [at] koppcom> wrote:
: Actually, you brought up a good point. Media calculations (which have to
: know whether a ray is inside or outside of a particular interior), and the
: translucency calculations WOULD get confused by ignoring the first
: intersection.

  My suggestion was to ignore the first intersection for the _shadow_
calculation, not for anything else (although I didn't think about this
when I wrote the article :) ).

: Using
: it as an option then allows users to apply it only in situations where it
: would not cause strange problems.

  Of course it should be an option.
  The other advantage would be backwards compatibility (who knows, perhaps
someone really _wants_ that effect in an old scene...).

: Actually implementing this could prove quite difficult, unfortunately (due
: to the shadow cache and the bounding box tree which have been implemented to
: speed up shadow calculations).

  What a pitty :(

-- 
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.