POV-Ray : Newsgroups : povray.advanced-users : Need help creating "flat" quadradural panels with smooth_triangle Server Time
26 Dec 2024 23:12:33 EST (-0500)
  Need help creating "flat" quadradural panels with smooth_triangle (Message 1 to 9 of 9)  
From: Mesh Mongrel
Subject: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 12:05:01
Message: <web.4357bfb42c8909645f0b7e880@news.povray.org>
I have a situation where I have a model with a section that consists of
panels that connect a base of a model to a midsection of a model.  Now I
created this POVRay model by measuring plastic pieces of a physical model
that you glue together and then paint.  In reality there is a slight
warping of the pieces when you assemble the physical model as the corners
of the panels are not all in the same plane.  This works because the pieces
are plastic and in real life the human eye doesn't really pick up the
slight warping and the panels apear flat.

So in POVRay I have the midsection polygon and the bottom polygon that need
a skirting made of panels to connect the two peices.  It seemed like the
logical construct for this particular problem is a mesh.  However since the
panels this mesh are made up of don't perfectly fit in the same plan some
of the panels show the triangle when light hits them at certain angles.

Now I had the idea that I could fix this problem by adjusting the shading
vector and use shmooth_triangle instead of triangle.  I got the idea by
reading this thread:

http://news.povray.org/povray.general/thread/%3Cweb.431fd888f4e5b5152f6d7a0@news.povray.org%3E/

Now I got the idea from the above thread that I could get the illusion of a
smooth panel by doing the following with x1-z4 replaced with actual
coordinate values:

mesh {
        #local P1 = <x1, y1, z1>;
        #local P2 = <x2, y2, z2>;
        #local P3 = <x3, y3, z3>;
        #local P4 = <x4, y4, z4>;
        #local N1 = vnormalize(vcross(P1 - P2, P3 - P1));
        #local N2 = vnormalize(vcross(P2 - P3, P4 - P1));
        #local N = (N1 + N2)/2;
        smooth_triangle { P1, N, P2, N, P3, N }
        smooth_triangle { P4, N, P3, N, P2, N }
}

It doesn't work.  I seem to get the same effect if I would just use
triangle.

I'm not understanding something here.  Am I wrong in my application of
vcross and vnormalize to get the normal vector for the triangles?  Am I
wrong in thinking that I can average the two vectors together as I have
done?  Am I wrong in thinking that if I give both triangles the same vector
I'll end up with the same shading?

Is there a better way to do this?  Maybe I shouldn't be using
smooth_triangle for this problem.  I cannot use polygons as they would
leave holes and I'm reticent to adjust the other portions of the model as
they look good.

Any advice would be appreciated.  Thanks.


Post a reply to this message

From: Mesh Mongrel
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 12:30:00
Message: <web.4357c524748e455f0b7e880@news.povray.org>
I appologize for the bogus HTML link in the above message.  Still getting
used to how the forums work here.

Here is a better URL for the message in the thread that gave me the idea for
generating smooth panels:

http://news.povray.org/web.43203f6a92437aab2cd8d46e0@news.povray.org


Post a reply to this message

From: Mesh Mongrel
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 16:25:01
Message: <web.4357fbd1748e455f0b7e880@news.povray.org>
Update:

I think I figured out that the normal I was calculating was the normal for
each vertex rather than the normal for the plane.  My misunderstanding.  If
I understand that correctly than I should need to calculate 6 vectors and
average them together rather than 2.

So I have tried this:

mesh {
        #local P1 = <x1, y1, z1>;
        #local P2 = <x2, y2, z2>;
        #local P3 = <x3, y3, z3>;
        #local P4 = <x4, y4, z4>;
        #local N1 = vnormalize(vcross(P3 - P1, P2 - P1));
        #local N2 = vnormalize(vcross(P1 - P2, P3 - P2));
        #local N3 = vnormalize(vcross(P1 - P3, P2 - P3));
        #local N4 = vnormalize(vcross(P4 - P3, P2 - P3));
        #local N5 = vnormalize(vcross(P3 - P2, P4 - P2));
        #local N6 = vnormalize(vcross(P3 - P4, P2 - P4));
        #local N = (N1 + N2 + N3 + N4 + N5 + N6)/6;
        smooth_triangle { P1, N, P2, N, P3, N }
        smooth_triangle { P2, N, P3, N, P4, N }
}


I still end up with the same shading problem.

I'd love to know what I'm missing.


Post a reply to this message

From: Slime
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 17:02:55
Message: <435805ff$1@news.povray.org>
> I still end up with the same shading problem.

I discovered myself at one point that, if a smooth triangle has all three
normals the same, POV-Ray ignores them and uses the triangle's actual normal
instead. A bug? Design flaw? Who knows.

You can fix the problem, I think, by very slightly changing one of the
normals:

smooth_triangle { P1, N, P2, N, P3, N + <0,0,.000001>}

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Chris B
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 21:38:58
Message: <435846b2$1@news.povray.org>
"Mesh Mongrel" <cor### [at] userssourceforgenet> wrote in message 
news:web.4357fbd1748e455f0b7e880@news.povray.org...
> Update:
>
> I think I figured out that the normal I was calculating was the normal for
> each vertex rather than the normal for the plane.  My misunderstanding. 
> If
> I understand that correctly than I should need to calculate 6 vectors and
> average them together rather than 2.
>
> So I have tried this:
>
> mesh {
>        #local P1 = <x1, y1, z1>;
>        #local P2 = <x2, y2, z2>;
>        #local P3 = <x3, y3, z3>;
>        #local P4 = <x4, y4, z4>;
>        #local N1 = vnormalize(vcross(P3 - P1, P2 - P1));
>        #local N2 = vnormalize(vcross(P1 - P2, P3 - P2));
>        #local N3 = vnormalize(vcross(P1 - P3, P2 - P3));
>        #local N4 = vnormalize(vcross(P4 - P3, P2 - P3));
>        #local N5 = vnormalize(vcross(P3 - P2, P4 - P2));
>        #local N6 = vnormalize(vcross(P3 - P4, P2 - P4));
>        #local N = (N1 + N2 + N3 + N4 + N5 + N6)/6;
>        smooth_triangle { P1, N, P2, N, P3, N }
>        smooth_triangle { P2, N, P3, N, P4, N }
> }
>
>
> I still end up with the same shading problem.
>
> I'd love to know what I'm missing.
>

I suspect you may be getting a couple of different explanations for 
different things mixed up.
In your example you work out a normal for each vertex of two triangles in 
isolation (as if the two triangles were not connected), then you 'average' 
all of the normals giving you a single surface normal that you apply to all 
points.
If you apply the same normal vector to all points in a triangle you are 
telling POV-Ray that the surface at all 3 points is pointing in the same 
direction.
If I've misunderstood your question and that is what you want to do, then I 
think Slime's suggestion should fix your problems.

If I understand correctly though, you just want a smooth surface made of 
multiple triangles.
For this, the normal at a vertex needs to be derived from the edges leading 
into the vertex. Each vertex will therefore have its own normal.
Where a vertex is only part of a single triangle you can simply use the 
cross product of the two edges leading into that vertex as the normal at 
that point.
Where a vertex is part of two triangles you could average the two cross 
products. Alternatively, you can imagine it as part of a single triangle 
made up using that vertex and the two points that are not on the joined edge 
of the two triangles. You can then still use a single cross product (as 
shown for P3 below).

When you have more than two triangles you need to start averaging your cross 
products. P2 in the example below is part of 4 triangles, so two cross 
products are calculated, one for each pair of triangles, then these vectors 
are added together and divided by two to give a surface normal N2 for the 
point P2. The same surface normal is then used for the point P2 in all 4 
triangles, but the other points in each of the triangles have their own 
normals.

I hope that the following example helps to clarify all this.
When you render it you can still make out some joins between the triangles, 
but that's because the points are a fair distance out of alignment and I've 
used a light at an extreme angle to the surface to emphasize the effect.
If your points are close to lying on a plane then it should look "flat".
The debug instructions write some values into the message stream to help 
show the workings for the calculation of N2.

light_source { < -150, 10  ,-80> color rgb 1}
camera {location <0.5,0.5,-2> look_at <0,0.5,0>}


#local P1  = < 0,0,0  >;
#local P2  = < 0,1,0.5>;
#local P3  = < 1,0,0  >;
#local P4  = < 1,1,0  >;
#local P5  = <-1,0,0.2>;
#local P6  = <-1,1,0  >;

#local N1a = vnormalize(vcross(P3 - P1, P2 - P1));
#local N2a = vnormalize(vcross(P4 - P2, P2 - P1));
#local N3  = vnormalize(vcross(P3 - P1, P4 - P3));
#local N4  = vnormalize(vcross(P4 - P2, P4 - P3));

#local N1b = vnormalize(vcross(P1 - P5, P2 - P1));
#local N2b = vnormalize(vcross(P2 - P6, P2 - P1));
#local N6  = vnormalize(vcross(P2 - P6, P6 - P5));
#local N5  = vnormalize(vcross(P1 - P5, P6 - P5));

#local N1 = (N1a+N1b)/2;
#local N2 = (N2a+N2b)/2;


#debug concat("N2a; ",vstr(3,N2a,",",3,3),"\n")
#debug concat("N2b: ",vstr(3,N2b,",",3,3),"\n")
#debug concat("N2 : ",vstr(3,N2,",",3,3),"\n")

mesh {
  smooth_triangle { P1, N1, P2, N2, P3, N3}
  smooth_triangle { P2, N2, P3, N3, P4, N4}
  smooth_triangle { P1, N1, P2, N2, P5, N5}
  smooth_triangle { P2, N2, P5, N5, P6, N6}
  pigment {color rgb 1}
}



Chris B.


Post a reply to this message

From: Mesh Mongrel
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 20 Oct 2005 23:55:01
Message: <web.43586550748e45a8cfcbd10@news.povray.org>
> smooth_triangle { P1, N, P2, N, P3, N + <0,0,.000001>}

Thanks for the suggestion.  But that didn't solve the shading problem
either.

Good news!  Through some trial and error I finally stumbled upon a solution.

I discovered that if I calculate the normals for all 6 of my verticies and
just average the 4 normals together that share a line between the two
triangles and then use the two remaining normals for the verticies they
were calculated from, it renders as a smooth surface.

The solution I stumbled across is below:

mesh {
        #local P1 = <x1, y1, z1>;
        #local P2 = <x2, y2, z2>;
        #local P3 = <x3, y3, z3>;
        #local P4 = <x4, y4, z4>;
        #local N1 = vnormalize(vcross(P3 - P1, P2 - P1));
        #local N2 = vnormalize(vcross(P1 - P2, P3 - P2));
        #local N3 = vnormalize(vcross(P1 - P3, P2 - P3));
        #local N4 = vnormalize(vcross(P4 - P3, P2 - P3));
        #local N5 = vnormalize(vcross(P3 - P2, P4 - P2));
        #local N6 = vnormalize(vcross(P3 - P4, P2 - P4));
        #local N = (N2 + N3 + N4 + N5) / 4;
        smooth_triangle { P1, N1, P2, N, P3, N }
        smooth_triangle { P2, N, P3, N, P4, N6 }
}

I've read bits and pieces that suggested the above was possible but couldn't
find an example that showed it in practice.

I don't know if this is the simplest solution, but it worked for my problem.


Post a reply to this message

From: Mesh Mongrel
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 21 Oct 2005 00:20:00
Message: <web.43586b5c748e45a8cfcbd10@news.povray.org>
Thanks Chris.  I found your explaination quite interesting.

What you are suggesting would translate in my case to so:

mesh {
        #local P1 = <x1, y1, z1>;
        #local P2 = <x2, y2, z2>;
        #local P3 = <x3, y3, z3>;
        #local P4 = <x4, y4, z4>;
        #local N1 = vnormalize(vcross(P3 - P1, P2 - P1));
        #local N2 = vnormalize(vcross(P1 - P2, P3 - P2));
        #local N3 = vnormalize(vcross(P1 - P3, P2 - P3));
        #local N4 = vnormalize(vcross(P4 - P3, P2 - P3));
        #local N5 = vnormalize(vcross(P3 - P2, P4 - P2));
        #local N6 = vnormalize(vcross(P3 - P4, P2 - P4));
        #local Na = (N2 + N5) / 2;
        #local Nb = (N3 + N4) / 2;
        smooth_triangle { P1, N1, P2, Na, P3, Nb }
        smooth_triangle { P2, Na, P3, Nb, P4, N6 }
}

I get very strange results when I try this.  I end up with shadows in
strange parts of my panels.  Through trial and error and basically
intepretting what little I read in as many ways as possible, I came up with
a solution I posted about the same time you were typing up your post.

I found that I needed to average all of SP2 and SP3's normals together and
use those for all instances of SP2 and SP3 in the smooth_triangles.  That
worked for my problem and it sort of makes sense to me even though I didn't
find that solution intuitative.

Does the solution in my earlier post look reasonable?


Post a reply to this message

From: Chris B
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 21 Oct 2005 05:04:30
Message: <4358af1e$1@news.povray.org>
"Mesh Mongrel" <cor### [at] userssourceforgenet> wrote in message 
news:web.43586b5c748e45a8cfcbd10@news.povray.org...
> ... snip ...
> I get very strange results when I try this.  I end up with shadows in
> strange parts of my panels.

Bands of shadows can occur in the middle of a panel if the normals at the 
vertices are pointing in opposite directions.
When you do a cross product at the apex of a triangle that is facing towards 
you, you get two possible results.
One is a normal facing towards you, the other is a normal facing away from 
you. This depends on the sequence and direction of the vectors you specify 
with vcross.

Reading the help on the POV-ray coordinate system should give you a better 
understanding of this.

I find it helps to consider the corner of a triangle re-oriented so that one 
edge points in something like the direction of +x and the other points in 
something like the direction of  +y.
If you pass the vectors to vcross in that sequence, then the resulting 
vector will point in the direction of +z.

Chris B.


Post a reply to this message

From: Mesh Mongrel
Subject: Re: Need help creating "flat" quadradural panels with smooth_triangle
Date: 22 Oct 2005 02:45:00
Message: <web.4359de66748e45a8cfcbd10@news.povray.org>
"Chris B" <c_b### [at] btconnectcomnospam> wrote:
> "Mesh Mongrel" <cor### [at] userssourceforgenet> wrote in message
> news:web.43586b5c748e45a8cfcbd10@news.povray.org...
> > ... snip ...
> > I get very strange results when I try this.  I end up with shadows in
> > strange parts of my panels.
>
> Bands of shadows can occur in the middle of a panel if the normals at the
> vertices are pointing in opposite directions.
> When you do a cross product at the apex of a triangle that is facing towards
> you, you get two possible results.
> One is a normal facing towards you, the other is a normal facing away from
> you. This depends on the sequence and direction of the vectors you specify
> with vcross.

Ah.  Now I get it.  I need to make certain I order the verticies I put into
the cross product so I generate vectors that all point in generally the
same direction.  Once all the normals are on the same side of the two
triangles then I can average the normals for the vertices shared on the
triangles and use those as normals for my smooth triangles and I get a
"flat" panel!

After doing some debug and working out the signs in my normal vectors I
ended up putting the below code in my panel macro:

    #local N1 = vnormalize(vcross(P3 - P1, P2 - P1));
    #local N2 = vnormalize(vcross(P1 - P2, P3 - P2));
    #local N3 = vnormalize(vcross(P2 - P3, P1 - P3));
    #local N4 = vnormalize(vcross(P4 - P3, P2 - P3));
    #local N5 = vnormalize(vcross(P3 - P2, P4 - P2));
    #local N6 = vnormalize(vcross(P2 - P4, P3 - P4));
    #local Na = (N2 + N5) / 2;
    #local Nb = (N3 + N4) / 2;
    smooth_triangle { P1, N1, P2, Na, P3, Nb }
    smooth_triangle { P2, Na, P3, Nb, P4, N6 }

I just so happened to luck out with my earlier approach of averaging 4
vectors together.  I was lucky that it worked for the 6 panels I had the
problem with.

Uderstanding the correct approach will better serve me in the future.

Thanks Chris.


Post a reply to this message

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