Shading problem

  • Follow


Hello! I'm new at this group. I think I need help...
I'm doing a 3D viewer of triangle meshes. I load them from an STL
file. So, when I read the data from the file, I have:
- A array of vertexs ( of unique vertexs, none of them is repeated)
- A array of triangles (it is a indexed array)
- A array of normals, one for each vertex.
I compute the normal as the average of the normals of the triangles
that share this vertex.
Until this point, everything is OK.
If I use GL_SMOOTH (smooth shading) the object is viewed OK. But if I
use GL_FLAT, it seems that each triangle uses the normal of the last
vertex, and this is not correct. The correct will be that each
triangle uses the average of the normal of the three vertex, or to
calculate again the norm for each triangle.
Is there any way of solving this easy?

If there is no easy-way, I can compute myself the triangle normals,
but how can I pass this normals as an array?

Thanks in advance!

0
Reply marta.jornet (1) 5/31/2007 4:22:12 PM

On May 31, 6:22 pm, ^_^ Marta <marta.jor...@gmail.com> wrote:
>
> If I use GL_SMOOTH (smooth shading) the object is viewed OK. But if I
> use GL_FLAT, it seems that each triangle uses the normal of the last
> vertex, and this is not correct.

This is the way OpenGL does it.

> The correct will be that each
> triangle uses the average of the normal of the three vertex, or to
> calculate again the norm for each triangle.
> Is there any way of solving this easy?
>

Nope.

> If there is no easy-way, I can compute myself the triangle normals,
> but how can I pass this normals as an array?
>

You won't be able to share vertices any more.


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.


Governments, like diapers, should be changed often,
and for the same reason.

0
Reply fungus 5/31/2007 6:46:12 PM


"fungus" <openglMYSOCKS@artlum.com> wrote in message 
news:1180637172.048920.40070@m36g2000hse.googlegroups.com...
> On May 31, 6:22 pm, ^_^ Marta <marta.jor...@gmail.com> wrote:
>>
>> If I use GL_SMOOTH (smooth shading) the object is viewed OK. But if I
>> use GL_FLAT, it seems that each triangle uses the normal of the last
>> vertex, and this is not correct.
>
> This is the way OpenGL does it.
>
>> The correct will be that each
>> triangle uses the average of the normal of the three vertex, or to
>> calculate again the norm for each triangle.
>> Is there any way of solving this easy?
>>
>
> Nope.
>
>> If there is no easy-way, I can compute myself the triangle normals,
>> but how can I pass this normals as an array?
>>
>
> You won't be able to share vertices any more.
>
>
> --
> <\___/>
> / O O \
> \_____/  FTB.     Remove my socks for email address.
>
>
> Governments, like diapers, should be changed often,
> and for the same reason.
>

Yeah, big hole in the vertex array syntax, can't do minimal face-shaded 
displays.

jbw


0
Reply jbwest 6/1/2007 1:42:47 AM

But this is a really BIG problem!!!
For example, one of my test meshes has 2 million triangles. Then, I
have approx. 500.000 different vertexs, so I have 500.000 vertex
normals. If I can't repeat the vertices, that will mean 6 milions of
vertex, and 6 millions of normals!!!!! With this huge arrays, if I try
to rotate the mesh, it goes really slow. And the memory of the
computer reaches its limit sooner.


0
Reply _ 6/1/2007 8:06:24 AM

One idea:
Can I pass a array of vertex, a indexed array of triangles and then a
array of normals, with one normal for each triangle?
Can't this be done?
I just want a good flat shading with shared vertices! Is this really
impossible?

0
Reply _ 6/1/2007 8:17:55 AM

On Jun 1, 10:17 am, ^_^ Marta <marta.jor...@gmail.com> wrote:
> One idea:
> Can I pass a array of vertex, a indexed array of triangles and then a
> array of normals, with one normal for each triangle?
> Can't this be done?

No, sorry.....


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.


Governments, like diapers, should be changed often,
and for the same reason.

0
Reply fungus 6/1/2007 3:11:52 PM

On Jun 1, 10:06 am, ^_^ Marta <marta.jor...@gmail.com> wrote:
> But this is a really BIG problem!!!
> For example, one of my test meshes has 2 million triangles. Then, I
> have approx. 500.000 different vertexs, so I have 500.000 vertex
> normals. If I can't repeat the vertices, that will mean 6 milions of
> vertex, and 6 millions of normals!!!!!

Yes...there's not much you can do. Graphics cards are
designed to work that way. In the real world it's not a very
common situation, not common enough to want to "fix"
things.

If it makes things clearer, think of a "vertex" as a collection of
attributes, not a position in space. A "vertex" has a position,
a normal, some texture coordinates, etc.


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.


Governments, like diapers, should be changed often,
and for the same reason.

0
Reply fungus 6/1/2007 3:19:26 PM

"^_^ Marta" <marta.jornet@gmail.com> wrote in message 
news:1180685184.793845.11510@k79g2000hse.googlegroups.com...
> But this is a really BIG problem!!!
> For example, one of my test meshes has 2 million triangles. Then, I
> have approx. 500.000 different vertexs, so I have 500.000 vertex
> normals. If I can't repeat the vertices, that will mean 6 milions of
> vertex, and 6 millions of normals!!!!! With this huge arrays, if I try
> to rotate the mesh, it goes really slow. And the memory of the
> computer reaches its limit sooner.
>
>

Yup, we're screwed. I've found that NVIDIA (but not ATI) is good with byte 
normals to save memory in a vertex array/vbo/etc.

jbw


0
Reply jbwest 6/1/2007 3:31:40 PM

> Yup, we're screwed. I've found that NVIDIA (but not ATI) is good with byte
> normals to save memory in a vertex array/vbo/etc.
>
> jbw

I'll check this about byte normals.
I know that maybe it's not a normal situation, but I want to view
sometimes flat shading and sometimes smooth shading. That's because in
mechanical parts, with a lot of edges, flat visualitzation works
better. But in "organic" surfaces, its better to use smooth shading.
And sometimes is usefull to compare both.
This weekend I will think about the problem...
The worse is that a lot of programs use both, like PolyWorks or
RapidForm, so there has to a be a solution! And they are really fast,
so there has to be a good solution!

This is the biggest problem I find doing the viewer!!   T_T

0
Reply _ 6/1/2007 4:52:44 PM

On Jun 1, 6:52 pm, ^_^ Marta <marta.jor...@gmail.com> wrote:
>
> The worse is that a lot of programs use both, like PolyWorks or
> RapidForm, so there has to a be a solution! And they are really fast,
> so there has to be a good solution!
>

You'll find there's no "magic" answer. Also that the fastest
programs are the ones which give the card data in the format
it was designed to process.


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.


Governments, like diapers, should be changed often,
and for the same reason.

0
Reply fungus 6/1/2007 7:10:19 PM

"fungus":
>> If there is no easy-way, I can compute myself the triangle normals,
>> but how can I pass this normals as an array?

> You won't be able to share vertices any more.

Doesn't OpenGL support "triangle strips"?
In D3D, triangle strips are a sequence of vertices, where
we have one vertex per triangle (the other two vertices are 
inherited from the the previous triangle). Triangle strips 
are constitent with switching shading mode to flat in D3D,
I think.

Gruss

Jan Bruns

0
Reply Jan 6/2/2007 7:28:53 AM

On Fri, 01 Jun 2007 01:06:24 -0700, ^_^ Marta <marta.jornet@gmail.com>
wrote:

>If I can't repeat the vertices, that will mean 6 milions of
>vertex, and 6 millions of normals!!!!! 

If you use triangle strips, since OpenGL uses the last vertex normal
as the "face" normal in flat shading, couldn't you have two normal
arrays? One with the normal "smooth" vertex normals, and one which
contains the face normal. Then you could just change the normal array
pointer, and you wouldn't have to duplicate ALL the vertices.

Just a wild idea...
- Asbj�rn
0
Reply Lord 6/4/2007 12:04:16 AM

"Lord Crc" <lordcrc@hotmail.com> wrote in message 
news:uhl663dt8bcasjv7cej8dhim7rbjb2kiil@4ax.com...
> On Fri, 01 Jun 2007 01:06:24 -0700, ^_^ Marta <marta.jornet@gmail.com>
> wrote:
>
>>If I can't repeat the vertices, that will mean 6 milions of
>>vertex, and 6 millions of normals!!!!!
>
> If you use triangle strips, since OpenGL uses the last vertex normal
> as the "face" normal in flat shading, couldn't you have two normal
> arrays? One with the normal "smooth" vertex normals, and one which
> contains the face normal. Then you could just change the normal array
> pointer, and you wouldn't have to duplicate ALL the vertices.
>
> Just a wild idea...
> - Asbj�rn

With shared vertices and normals (and only one index -- to both) its not 
generally possible for a single vertex normal to be a single face normal. 
That shared vertex *in general* will also be  the last vertex/normal for 
another adjacent triangle, and thus it won't be the right normal for that 
2nd triangle.

jbw


0
Reply jbwest 6/4/2007 1:54:04 AM

Using triangle strips could be a good solution for visualitzation.
But then I will need to calculate this strips!
I think that this is not a bad solution if you will display allways
the same mesh (like in a game). In this case, you can "striptificate"
the mesh and store it as strips.
But in a viewer, the mesh can be allways different. So each time I
want to display a mesh, I will need to "striptificate" it! I think
that this process will be too time-consuming.
Have someone of you implemented a "stiptification" program? Can any of
you give me an idea about time-consumption (n=BA of triangles/seconds of
processing)?


0
Reply _ 6/5/2007 11:32:31 AM

"^_^ Marta":

> Using triangle strips could be a good solution for visualitzation.
> But then I will need to calculate this strips!
> I think that this is not a bad solution if you will display allways
> the same mesh (like in a game). In this case, you can "striptificate"
> the mesh and store it as strips.
> But in a viewer, the mesh can be allways different. So each time I
> want to display a mesh, I will need to "striptificate" it! I think
> that this process will be too time-consuming.
> Have someone of you implemented a "stiptification" program? Can any of
> you give me an idea about time-consumption (n� of triangles/seconds of
> processing)?

There are many libraries out there, that can do this job.

But maybe you can avoid that using indexd triangle list:

Say you have n triangles.

For any triangle create a single vertex, and assign the face-normal
to it. Because a triangle has 3 endpoints, you have a free choice
which one should carry that normal. So better try to use one, that
hasn't already a normal assigned.

Now you have n trianges and n vertices. However, it's probably still
possible, that some positions of the object still don't have a
corresponding vertex-"object", so you could yet either try to optimize
the selection mechanism or simply create m additional vertices for
the remaining positions.

Finally, create the index-list, so that each triangle has it's
normal-carrying vertex named at the correct entry.

Gruss

Jan Bruns


0
Reply Jan 6/5/2007 12:33:01 PM

"Jan Bruns" <testzugang_janbruns@arcor.de> wrote in message 
news:46655808$0$20286$9b4e6d93@newsspool3.arcor-online.net...
>
> "^_^ Marta":
>
>> Using triangle strips could be a good solution for visualitzation.
>> But then I will need to calculate this strips!
>> I think that this is not a bad solution if you will display allways
>> the same mesh (like in a game). In this case, you can "striptificate"
>> the mesh and store it as strips.
>> But in a viewer, the mesh can be allways different. So each time I
>> want to display a mesh, I will need to "striptificate" it! I think
>> that this process will be too time-consuming.
>> Have someone of you implemented a "stiptification" program? Can any of
>> you give me an idea about time-consumption (n� of triangles/seconds of
>> processing)?
>
> There are many libraries out there, that can do this job.
>
> But maybe you can avoid that using indexd triangle list:
>
> Say you have n triangles.
>
> For any triangle create a single vertex, and assign the face-normal
> to it. Because a triangle has 3 endpoints, you have a free choice
> which one should carry that normal. So better try to use one, that
> hasn't already a normal assigned.
>
> Now you have n trianges and n vertices. However, it's probably still
> possible, that some positions of the object still don't have a
> corresponding vertex-"object", so you could yet either try to optimize
> the selection mechanism or simply create m additional vertices for
> the remaining positions.
>
> Finally, create the index-list, so that each triangle has it's
> normal-carrying vertex named at the correct entry.
>
> Gruss
>
> Jan Bruns
>
>

In my experience, one is better off (for the most general and complex cases) 
giving up on index lists and shared vertices and just create a display list 
with flat-shaded triangles. Performance is excellent, it's dead simple to 
implement (and hence, bug-free), and the total memory load on your system 
may not be too bad because you never have to store the normals youself --  
just compute them on the fly, placing them in the display list & then 
forgetting them.

-jbw 


0
Reply jbwest 6/5/2007 3:06:36 PM

Hi Marta!

I had nearly the same problem: The extremly slow rotating with a fine
mesh.

Then I tried it with display lists. That's a pretty nice way and not
too complicated.
Basically, using display lists is something like a "record button".
You "press" it and the OpenGLCallings are recorded for later use.

Now in a simple code:

ListID = glGenLists(size);
glNewList(ListID, GL_COMPILE);

glBegin(GL_POLYGON);   --> dont use Triangles in your case. Polygons
are a bit faster
vertex
color
etc.
glEnd();

glEndList();

So, now you won't see anything on your screen.
Now use:
glCallList(ListID);
and your generated mesh will be shown.

You will see, that this approach is warp speed in comparasion to the
"normal" way without display lists :)

Best Regards,
Cordovan






0
Reply Cordovan 6/5/2007 3:11:35 PM

"Cordovan" <nucerion@gmx.de> wrote in message 
news:1181056295.303223.261380@p47g2000hsd.googlegroups.com...
> Hi Marta!
>
> I had nearly the same problem: The extremly slow rotating with a fine
> mesh.
>
> Then I tried it with display lists. That's a pretty nice way and not
> too complicated.
> Basically, using display lists is something like a "record button".
> You "press" it and the OpenGLCallings are recorded for later use.
>
> Now in a simple code:
>
> ListID = glGenLists(size);
> glNewList(ListID, GL_COMPILE);
>
> glBegin(GL_POLYGON);   --> dont use Triangles in your case. Polygons
> are a bit faster
> vertex
> color
> etc.
> glEnd();
>
> glEndList();
>
> So, now you won't see anything on your screen.
> Now use:
> glCallList(ListID);
> and your generated mesh will be shown.
>
> You will see, that this approach is warp speed in comparasion to the
> "normal" way without display lists :)
>
> Best Regards,
> Cordovan
>
>
>
>
>
>

glBegin(GL_TRIANGLES) is virtually as fast as triangle strips and you don't 
have to "stripify" (sometimes the driver does anyway...and the vertex cache 
works wonders). I don't know why Cordovan says triangles are slower . If 
your mesh is a real rectilinear mesh, use GL_QUADS (or QUAD_STRIP), hey, 
that's what they are for.

If it is a rectilinear mesh, one simple cheat is use a "LOD" (Level Of 
Detail), that is, maybe a 2x2 decimated version of your mesh. Just skip 
every other row & column when creating the 2nd display list. 4x faster for 
"while rotating" visualization.


jbw 


0
Reply jbwest 6/6/2007 1:47:31 AM

> glBegin(GL_TRIANGLES) is virtually as fast as triangle strips and you don't
> have to "stripify" (sometimes the driver does anyway...and the vertex cache
> works wonders). I don't know why Cordovan says triangles are slower . If
> your mesh is a real rectilinear mesh, use GL_QUADS (or QUAD_STRIP), hey,
> that's what they are for.

I have two kinds of mesh:
-First, an organitzed point cloud, that I draw using Quads or
Triangles. This part is easy, because this points are ordered and I do
the decimation if it is necessary.
-Second, a reconstructed mesh from a set of organized point clouds. In
this part the mesh hasn't got any order, so using quads is not easy,
it will be as difficult as stripification. This second part is the
part that I find difficult because is not easy obtaining the flat
mesh.

>But maybe you can avoid that using indexd triangle list:

>Say you have n triangles.

>For any triangle create a single vertex, and assign the face-normal
>to it. Because a triangle has 3 endpoints, you have a free choice
>which one should carry that normal. So better try to use one, that
>hasn't already a normal assigned.

>Now you have n trianges and n vertices. However, it's probably still
>possible, that some positions of the object still don't have a
>corresponding vertex-"object", so you could yet either try to optimize
>the selection mechanism or simply create m additional vertices for
>the remaining positions.

>Finally, create the index-list, so that each triangle has it's
>normal-carrying vertex named at the correct entry.

>Gruss

>Jan Bruns

I will try this option and then I will tell you about the results.

At first I was using Display Lists. Now I use VBO, because I read
somewere that Display Lists are going to be deprecated in OpenGL 2.0.

0
Reply _ 6/6/2007 7:03:21 AM

18 Replies
242 Views

(page loaded in 0.337 seconds)

Similiar Articles:


















7/25/2012 9:03:55 AM


Reply: