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] (...) [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
|
|
|
|