Page 1 of 2

Softviewers normal vector behavior

Posted: Wed 18. Feb 2009, 23:05
by Joe
the JOGL renderer seems always to calculate normal vectors for both sides of a face (even if I rotate the face, both sides have a correct lightning). The softviewer too, but not under all circumstances. If ...

Code: Select all

appearance.setAttribute(CommonAttributes.POLYGON_SHADER + "." + CommonAttributes.SMOOTH_SHADING, false);
... is set, the faces have only one normal vector. This leads to the fact, that the faces have a lighted side and a black side, because there's only one normal vector. If ...

Code: Select all

appearance.setAttribute(CommonAttributes.POLYGON_SHADER + "." + CommonAttributes.SMOOTH_SHADING, true);
... is set, every face has on every side a normal vector, so that every face has a correct shading on both sides.

Short summary: If smooth shading is disabled, only the JOGL viewer renders all faces with the correct shading. The softviewer discards in this state one of the two normals, so that only one side of the face is shaded, the other side is black.

Is it a bug in the softviewer or do I have to set some attributes to force both viewers to the same behavior?

Many thanks and best regards, Joe

Posted: Wed 25. Feb 2009, 21:58
by steffen
sounds like a bug...

Posted: Thu 26. Feb 2009, 16:20
by timh
sounds like a bug...
yep. fixed it (hopefully).

Posted: Thu 19. Mar 2009, 21:51
by Joe
Thanks, it has really been fixed. But now I see a similar behavior in the JOGL viewer. Here are 4 screenshots, which show what I mean. Flat shading is done correctly for all geometries and both viewers.

Flatshading with JOGL:

Flatshading with softviewer:

But if smooth shading is activated, the JOGL viewer sometimes has problems with the normal vectors:

Smoothshading with JOGL:

Smoothshading with softviewer:

Most of the loaded files are rendered correctly with smooth shading. But there seems to be some geometry, which need two sideed normal vectors.

Best regards and many thanks for this great library!

Posted: Fri 20. Mar 2009, 11:05
This looks like your geometry is ill-behaving it doesn't have a unified winding direction it uses for describing the triangles inside the mesh, this is normally not nice behaving. Sounds like it has been exported by some CAD application. They tend to do that.

Posted: Fri 20. Mar 2009, 17:57
by Joe
I hope that jReality can fix this for smooth shading too, because with flatshading it can already deal with the winding problem correctly.

Posted: Mon 23. Mar 2009, 15:47
Joe wrote:I hope that jReality can fix this for smooth shading too, because with flatshading it can already deal with the winding problem correctly.
Depends if the surface normals are stored as part of the model you load in or it computes it automatically.

Posted: Wed 25. Mar 2009, 17:24
by gunn
I'm interested to know why the smooth-shading picture for the JOGL backend looks so odd.

To help debug, there are two static methods, one old and one new, which could help.

First, IndexedFaceSetUtility.displayFaceNormals(...) will display the face normals, and

Second, (new) PointSetUtility.displayVertexNormals(...) does the same for the vertex normals.

Typical usage:

Code: Select all

IndexedFaceSet ifs;
SceneGraphComponent world = new SceneGraphComponent();
world.addChild(IndexedFaceSetUtility.displayFaceNormals(ifs, .1, Pn.EUCLIDEAN));
The second parameter is a scaling factor, and the third is probably not of interest here.

To see the vertex normals, replace the last line with

Code: Select all

world.addChild(PointSetUtility.displayVertexNormals(ifs, .1, Pn.EUCLIDEAN));
There are various possibilities. Since the problem happens with smooth shading, it's important to know how the JOGL backend does smooth shading. It uses vertex normals if they are present, or if not, it will repeat the face normal for each vertex of the face when rendering the face. The displayVertexNormals() method will throw an exception if there are no vertex normals attached to the instance, so you'll quickly find out if the geometry has vertex normals, and if so, this method will display them.

If it doesn't have vertex normals, you can create them for you geometry using the method IndexedFaceSetUtility.calculateAndSetVertexNormals() (or one of its variants). Compare the smooth-shaded results when you use these vertex normals.

My suspicion is that the normals provided with the object are inconsistently oriented. This should be clear when you display the normals as outlined here.

Posted: Sun 5. Apr 2009, 19:31
by Joe
At first, sorry for my late reply.
I inserted the normal vector generation for the faces. Below are the results. It seems the the normal vectors of neighbour faces have the opposite directions. But the flat shading of JOGL and the flat- and smooth shading of the softviewer handle it in an other (in my oppinion better) way.

Flat shading with JOGL:

Smooth shading with JOGL:

Flat shading with soft viewer:

Smooth shading with soft viewer:

Posted: Sat 11. Apr 2009, 22:06
by Joe

Posted: Thu 23. Apr 2009, 22:27
by Joe
Due to the fact, the softviewer and the JOGL flat shading can handle the alternating normals, will the JOGL smooth shading be adapted?

Posted: Mon 27. Apr 2009, 12:52
by gunn
My preference would be to try to solve the problem first by correcting the geometry to have consistent normals. Having non-consistent normals will not only effect rendering algorithms but will also have undesired side-effects on many geometry processing algorithms.

May I suggest that you experiment with the following static method in de.jreality.geometry.IndexedFaceSetUtility ?

Code: Select all

makeConsistentOrientation(IndexedFaceSet ifs)
This method will attempt to rearrange the face indices which define the IndexedFaceSet instance, in such a way that all faces are consistently oriented. It does this not by calculated normals and comparing, but simply by trying to ensure that every edge AB that occurs in two faces, occurs once in the order AB and once in the order BA. If this isn't possible (because, for example, the geometry represents a Moebius band), it doesn't do anything and returns false. Otherwise it makes the changes and returns true.

Posted: Tue 28. Apr 2009, 20:39
by Joe
I use jReality for a file viewer, so I can't ensure, that the processors, which wrote the CAD files, create correct windings / orientations.

When I use the helper function "makeConsistentOrientation", the flat shading, which was OK, has the same chessboard pattern like the smooth shading without the helper function, so in my opinion its a step back in quality.

Would it be a problem to apply the same orientations algorithm to the smooth shading as for the flat shading or the smooth shading of the softviewer?

If its a problem, tell me and I'll never ask again.

Posted: Tue 28. Apr 2009, 20:50
by gunn
It is a problem, simply because the JOGL backend isn't using any algorithm when it renders flat shading. I mean, it's not any different than what it's doing when it renders smooth shading. I myself don't understand at all the effects you're getting with smooth shading (checkerboard). But I've had enough experience fighting with OpenGL's ideas of normals, front facing, clockwise vs counter-clockwise orientation, etc, to know that I'd rather work around the problem.

One other idea: after you call makeConsistentOrientation() you might benefit from calling IndexedFaceSetUitility.calculateAndSetNormals() or one of its variations. That might straighten out the normals that might have been incorrectly calculated due to the bad indexing of the faces.

Posted: Tue 28. Apr 2009, 21:09
by steffen
Hi, I just wanted to figure out what goes wrong, but I am not able to reproduce the problems.

I am also not able get such a smooth shaded picture as the one you have made with the software viewer, I see actually no difference between smooth and flat shading. Are you doing anything else to the geometry after loading (smooth normals, vertex merging, subdivision)?

I have just updated jogl in the svn project, maybe that also might help...