To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.cad.devOpen lugnet.cad.dev in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 CAD / Development / 9580
9579  |  9581
Subject: 
Re: surface normals and vertex normals for OpenGL
Newsgroups: 
lugnet.cad.dev
Date: 
Sun, 7 Mar 2004 06:03:16 GMT
Viewed: 
1893 times
  
In lugnet.cad.dev, Brian Durney wrote:
Hello,
I have some LDraw animation projects in mind and am starting by making a simple
viewer using OpenGL.  I have a program that will read a file and display it,
but I run into problems with the shading because it only does flat shading.  I
think I need to specify vertex normals to get smooth shading, but the LDraw
format doesn't lend itself to that kind of thing since the polygons are
specified independently and could be scattered throughout the file.  Are vertex
normals what I need, and is there a good way to calculate them for LDraw files?

When calculating surface normals I've run into some parts that get some strange
shading.  I'm guessing that it's because some polygons are CW and others are
CCW.  One particular file that I looked at (3626BPS4.DAT, minifig head with SW
grey beard) is not BFC, so it wouldn't be a surprise if they weren't consistent.
Assumming that that's the problem, is it necessary to go through the file
manually, polygon by polygon, to determine which way the normals should go and
whether they're consistent, or is there some way to automate that (or part of
it)?

I suspect this has been talked about in this group before, but probably not all
in one thread.  I'll try to summarize the things to look out for.

First of all, you are correct in that any files that aren't BFC-certified have
polygons with indeterminate winding.  Because of this, it is pretty much
impossible to generate accurate normals for these files.  Fortunately, OpenGL
was designed such that this isn't an insurmountable problem.  You have at least
two options that will solve the problem.  The first (which LDView uses) is to
enable two-sided lighting.  You do this like so:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);

Note that you also need to make sure that all your surface properties are set to
apply to both the front and back faces, and that GL_CULL_FACE is disabled.  In
general, you should be able to search your code for GL_FRONT and change it to
GL_FRONT_AND_BACK.

Another alternative that doesn't require two-sided lighting is to create two
polygons facing in opposite directions for each non-BFC polygon you encounter
(make sure the GL_CULL_FACE is enabled and glCullFace is set to GL_BACK).  I
suspect that this will be slower to render than just enabling two-sided
lighting, but it should work.

The faceted problem is a little harder to solve, but not impossible.  I solved
it in LDView at two levels.  The first level was to recognize certain primitives
(files from the LDraw\P directory), and ignore their geometry, generating my own
replacement geometry with appropriate surface normals.  Note that the BFC
problem still applies, so the normals don't necessarily correctly face "out",
but they are consistent with the winding I chose.  The problem here is that
there are a bunch of primitives, and some of them aren't exactly trivial to
produce (I personally found the 1/8th sphere to be the most difficult).  On the
other hand, doing the substition lets you speed up rendering, because you can
use triangle strips, triangle fans, and quad strips.

The other way to smooth things out is to take advantage of the fact that
conditional lines (LDraw line-type 5) tell you which surfaces are supposed to be
smooth.  You can make use of this fact to calculate shared normals (averaging
together multiple facet normals) for smooth areas.  I implemented this in LDView
as well, and it works OK.  It's not the end all/be all, because conditional
lines are only really normally necessary in an LDraw file for concave surfaces.
Additionally, my particular implementation requires that both endpoints of the
conditional line match two points on two adjoining polygons, and that doesn't
always happen.  There is a long thread on the process here, though:

http://news.lugnet.com/cad/dev/?n=7198

There is an alternate method that I believe is mentioned in the above thread,
but may not be (I'm not about to re-read the whole thing to find out).  And that
is to use edge lines (type 2 lines with color number 24) to tell you all the
edges that AREN'T supposed to be smooth.  You then smooth everything else
(although it's probably a good idea to have an angle threshold just to be sure).
I suspect that this would work pretty well, but I'm not sure how many false
positives would result.  In theory there shouldn't be any, but it's hard to be
sure until someone implements it.  As far as I know, nobody has done so.

Both smoothing algorithms optimally need to be applied to each part.  You
definitely don't want to smooth across multiple parts, but you do ideally want
to smooth across the sub-models inside parts.  This requires you to recognize
which files are parts, and be able to act across all the polygons in the part as
a whole.  I personally "flatten" parts, which means I copy all the geometry from
sub-models referenced by the part into the part itself, converting the
coordinates appropriately while doing so.

If you're interested, you're welcome to look at the LDView source code.  There's
a lot there, but it's freely available for you to look at or even copy into your
own project.  You can find it here:

http://home.san.rr.com/tcobbs/LDView/Downloads.html

Hope this helps.

--Travis Cobbs



Message has 2 Replies:
  Re: surface normals and vertex normals for OpenGL
 
(...) <SNIP> (...) That does help a lot. Thanks much. Brian Durney (21 years ago, 9-Mar-04, to lugnet.cad.dev)
  Re: surface normals and vertex normals for OpenGL
 
(...) [snip] (...) [snip] (...) It is neither impossible nor particularly hard. I will snip the rest of the post here and explain. There is an interesting property of closed surfaces that can allow you to determine the normals for all polygons (or (...) (21 years ago, 11-Mar-04, to lugnet.cad.dev)

Message is in Reply To:
  surface normals and vertex normals for OpenGL
 
Hello, I have some LDraw animation projects in mind and am starting by making a simple viewer using OpenGL. I have a program that will read a file and display it, but I run into problems with the shading because it only does flat shading. I think I (...) (21 years ago, 7-Mar-04, to lugnet.cad.dev)  

9 Messages in This Thread:



Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR