Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Surface normals?

29 views
Skip to first unread message

Rui Maciel

unread,
Nov 17, 2009, 2:26:35 AM11/17/09
to
While reading opengl's FAQ I've stumbled on the following entry[1]:

<faq>
18.030 How can I make OpenGL automatically calculate surface normals?

OpenGL won't do this unless you're using evaluators.
</faq>

Is this true? Wouldn't it be simpler and even more efficient to automatically calculate normals from the
order the glVertex() are added?


Rui Maciel

[1] http://www.opengl.org/resources/faq/technical/lights.htm

fungus

unread,
Nov 17, 2009, 5:33:32 AM11/17/09
to
On Nov 17, 8:26 am, Rui Maciel <rui.mac...@gmail.com> wrote:
> While reading opengl's FAQ I've stumbled on the following entry[1]:
>
> <faq>
> 18.030 How can I make OpenGL automatically calculate surface normals?
>
>     OpenGL won't do this unless you're using evaluators.
> </faq>
>
> Is this true?

Yes.

> Wouldn't it be simpler and even more efficient to automatically calculate normals from the
> order the glVertex() are added?
>

How would you do smooth shading? OpenGL sees every polygon
separately so how would you smooth them together?


--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor for real time simulation

Rui Maciel

unread,
Nov 17, 2009, 1:35:32 PM11/17/09
to
fungus wrote:

>> Wouldn't it be simpler and even more efficient to automatically calculate
>> normals from the order the glVertex() are added?
>>
> How would you do smooth shading? OpenGL sees every polygon
> separately so how would you smooth them together?

I expected that automatically generated normals could be a feature that would be made available to the
programmer who could, for example, turn it on through a glEnable() call. Isn't this feature implemented
extensively?


Rui Maciel

Wolfgang Draxinger

unread,
Nov 17, 2009, 3:51:26 PM11/17/09
to
Rui Maciel wrote:

> Is this true? Wouldn't it be simpler and even more efficient to
> automatically calculate normals from the order the glVertex() are added?

In one word: No!

OpenGL is a API, which purpose is, to get the programmer as closely to the
rendering process as possible, sparing him from the gory details, while
keeping the most possible freedom. Advanced rendering techniques require
special treatment of vertex attributes like normals.

Any automatism like automatic normal generation would take away freedom from
the programmer and prevent the implementation of certain rendering
techniques.

Furthermore it would complicate things like rendering sharp edges on a
otherwise smooth surface.

Normals are very easy to calculate, so there's no real need for an
automatism. I presume that you're a 3D rendering newbie. With some
experience you'll see, that such functionality in an API like OpenGL would
be a PITA in the long term. Such things are better put in geometry
processing libraries, what OpenGL is not.


Wolfgang
--
OpenGL tip #42:
How to exactly map texture texels to screen pixels:
<http://preview.tinyurl.com/cgndc8>

Rui Maciel

unread,
Nov 18, 2009, 2:25:36 PM11/18/09
to
Wolfgang Draxinger wrote:

> In one word: No!
>
> OpenGL is a API, which purpose is, to get the programmer as closely to the
> rendering process as possible, sparing him from the gory details, while
> keeping the most possible freedom. Advanced rendering techniques require
> special treatment of vertex attributes like normals.


Regarding the advanced rendering techniques, that sounds interesting. Is it possible to provide a small
example of how normals are handled?


> Any automatism like automatic normal generation would take away freedom
> from the programmer and prevent the implementation of certain rendering
> techniques.

It wouldn't be necessary to force auto-normal calculations as a mandatory option. It appears that there are
already quite a hefty share of optional features which may be set through glEnable(). Is auto-normals
calculation much less useful than, for example, drawing anti-aliased points?


> Furthermore it would complicate things like rendering sharp edges on a
> otherwise smooth surface.
>
> Normals are very easy to calculate, so there's no real need for an
> automatism. I presume that you're a 3D rendering newbie.

I'm very guilty of that, yes. Nonetheless, as I see it, the main case for letting opengl calculate normals
wouldn't be one of making the programmer's job easier but one of efficiency.


> With some
> experience you'll see, that such functionality in an API like OpenGL would
> be a PITA in the long term. Such things are better put in geometry
> processing libraries, what OpenGL is not.

Interesting. Could you please provide an example on how adding to opengl the ability to automatically
calculate normals would lead to problems in the long run?


Rui Maciel

jbwest

unread,
Nov 18, 2009, 11:58:33 PM11/18/09
to

"Rui Maciel" <rui.m...@gmail.com> wrote in message
news:4b044a2e$0$17012$a729...@news.telepac.pt...

No one would ever agree on the "right" way to calculate smooth normals. If
you think about smooth normals for shared vertices, you have to make a pass
over the entire dataset before you can draw the 1st triangle. It's not a
graphics operation, it's an algorithmic one, better suited to a "glu"
function or some other add-on toolkit (they exist...).

jbw


aku ankka

unread,
Nov 19, 2009, 4:07:09 AM11/19/09
to

Efficiency how? If you dynamically send vectices to the graphcis
processor in every draw call, you are generating shitloads of bus
traffic. The way that is efficient is that you put the vertex arrays
into object, define it only once and just bind to the array. This way
the gfx processor can keep the data in it's local memory and rendering
is very fast.

So... the normal vectors can be computed offline, put into the vertex
buffer object and it's VERY efficient. What you propose is just extra
overhead on top of the vertex transfer over the bus. If you want to
put the computing into the graphics processor, write a geometry
shader.

For fine-grained control you want to see much more data at once, so
geometry shader might not be the best place for that. Usually normal
generation control is in the production pipeline, in the tools ARTISTS
use. Programmers are rarely good at that (doing great graphics!), so
better give ARTISTS the tools they can use.

aku ankka

unread,
Nov 19, 2009, 4:12:38 AM11/19/09
to
The bottom line: the programmer's ability is measured by the talent of
the artist doing the content. People see amazingly cool 3d graphics,
they go: "whooaaaa what an amazing 3d engine.."

The programmers job is to give efficient enough rendering pipe so that
it can render as much detail as possible and add as much dynamic
effects and animation as possible efficiently. To write fast code in
other words. All this is futile if the code doens't work.

The ONLY way for the programmer to be visible in the final product is
to fuck something up. If the application keeps crashing, THEN the
programmer will get the recognition they deserve. In any other
contingency, it's the programmer getting artist's credit. =)

(slow performance can be attributed to content that is not compatible
with the code and target hardware =)

Wolfgang Draxinger

unread,
Nov 19, 2009, 12:09:09 PM11/19/09
to
Rui Maciel wrote:

> Regarding the advanced rendering techniques, that sounds interesting. Is
> it possible to provide a small example of how normals are handled?

Look up any toping on advanced lighting techniques. Anisotropic Materials
(instead of a normal vector, they carry tangent tensors).

> It wouldn't be necessary to force auto-normal calculations as a mandatory
> option. It appears that there are already quite a hefty share of optional
> features which may be set through glEnable().

> Is auto-normals calculation
> much less useful than, for example, drawing anti-aliased points?

Antialiasing is a feature placed very deep in the gory details of the
rasterization process. Even on modern programmable GPUs antialiasing is
still more or less hardwired. Thus it makes perfect sense to expose such a
feature as a part of the API itself.

If you take a close look on what things are built into OpenGL, you'll find,
that those are all things, which are difficult to implement manually. Some
legacy parts of the API, like lighting and fog, now are superseeded by the
use of shaders. But still these things are not done on the CPU, but on the
graphics hardware, and as such require some support by the API.

> I'm very guilty of that, yes. Nonetheless, as I see it, the main case for
> letting opengl calculate normals wouldn't be one of making the
> programmer's job easier but one of efficiency.

Calculating the normals is done only once, namely at the creation of the
geometry data (i.e. modelling by the artist). All that's left to do is
copying the normal data into the graphics memory.

Having the renderer API calculating the normal data merely from the
vertices, requires to recalculating things for every rendered frame. THIS is
inefficient.

> Interesting. Could you please provide an example on how adding to opengl
> the ability to automatically calculate normals would lead to problems in
> the long run?

Not in the long run, Already! If OpenGL did calculate normals itself, it was
impossible to implement things like anisotropic lighting, which rely on a
somewhat different treatment of the normal data: Instead of a plain surface
normal, i.e. a vector pointing straigt away from the surface, the normal
value is actually the tangent on the surface, pointing into the direction of
the strongest anisotropy. Together with a second tangent (the bitangent),
which carries a orthogonal-to-the-normal component one gets the tangent
tensor.
Brushed metal, the grooves on a record and hait are a very good examples
of anisotropic materials - the tangent vector would be pointing into the
direction of the brush strokes, grooves, hair strands.

OpenGL has evolutionied for 15 years, a lot of skilled people participated
in it's design. That automatic normal generation is not there certainly has
it's reason and is a well thought over decision.

Rui Maciel

unread,
Nov 19, 2009, 1:11:25 PM11/19/09
to
aku ankka wrote:

> Efficiency how? If you dynamically send vectices to the graphcis
> processor in every draw call, you are generating shitloads of bus
> traffic. The way that is efficient is that you put the vertex arrays
> into object, define it only once and just bind to the array. This way
> the gfx processor can keep the data in it's local memory and rendering
> is very fast.

As I understand it, that doesn't negate the potential benefits of off-loading normals computations to opengl.
As long as the vertices are defined and geometry can be deduced then it would be possible to automatically
calculate the normal vectors, with the added benefit of being able to avoid transferring data around and
taking advantage of dedicated hardware to perform those operations.


> So... the normal vectors can be computed offline, put into the vertex
> buffer object and it's VERY efficient.

Wouldn't it be simpler if opengl could also take care of those normals?


> What you propose is just extra
> overhead on top of the vertex transfer over the bus. If you want to
> put the computing into the graphics processor, write a geometry
> shader.

I don't have a good grasp of the pipeline process, which may be the key to understand why it would be better
to avoid letting opengl handle this issue. Nonetheless, when the programmer calls glNormal()doesn't data get
transfered around?


> For fine-grained control you want to see much more data at once, so
> geometry shader might not be the best place for that. Usually normal
> generation control is in the production pipeline, in the tools ARTISTS
> use. Programmers are rarely good at that (doing great graphics!), so
> better give ARTISTS the tools they can use.

What about those applications where artists don't necessarily come into play, such as CAD and scientific
visualization?


Rui Maciel

Rui Maciel

unread,
Nov 19, 2009, 1:32:33 PM11/19/09
to
Wolfgang Draxinger wrote:

> Rui Maciel wrote:
>
>> Regarding the advanced rendering techniques, that sounds interesting. Is
>> it possible to provide a small example of how normals are handled?
>
> Look up any toping on advanced lighting techniques. Anisotropic Materials
> (instead of a normal vector, they carry tangent tensors).

Sounds interesting. I'll look it up, although it may be a bit out of my league for me to be able to get a
firm grasp on the subject.


>> Is auto-normals calculation
>> much less useful than, for example, drawing anti-aliased points?
>
> Antialiasing is a feature placed very deep in the gory details of the
> rasterization process. Even on modern programmable GPUs antialiasing is
> still more or less hardwired. Thus it makes perfect sense to expose such a
> feature as a part of the API itself.
>
> If you take a close look on what things are built into OpenGL, you'll
> find, that those are all things, which are difficult to implement
> manually. Some legacy parts of the API, like lighting and fog, now are
> superseeded by the use of shaders. But still these things are not done on
> the CPU, but on the graphics hardware, and as such require some support by
> the API.

Oh I see. So the design philosophy behind opengl is to offer a set of primitives to be used as basic
building blocks by the programmer instead of offering an extensive API. Is that the gist of it?


>> I'm very guilty of that, yes. Nonetheless, as I see it, the main case for
>> letting opengl calculate normals wouldn't be one of making the
>> programmer's job easier but one of efficiency.
>
> Calculating the normals is done only once, namely at the creation of the
> geometry data (i.e. modelling by the artist). All that's left to do is
> copying the normal data into the graphics memory.
>
> Having the renderer API calculating the normal data merely from the
> vertices, requires to recalculating things for every rendered frame. THIS
> is inefficient.

I was thinking more of scientific visualization cases where basically the entire scene is dynamically
generated from a given input. For example, finite element method programs may handle complex meshes that,
after the processing phase, may end up nothing like the original configuration, without preserving the
relative position of a single mesh node and therefore ending up with entirely different elements. People
writing that sort of software would probably enjoy the possibility of avoiding calculating all those normal
vectors.

<snip />

Thanks for the insight, Wolfgang. Great read. Kudos!


Rui Maciel

Wolfgang Draxinger

unread,
Nov 19, 2009, 2:19:11 PM11/19/09
to
Rui Maciel wrote:

> Oh I see. So the design philosophy behind opengl is to offer a set of
> primitives to be used as basic building blocks by the programmer instead
> of offering an extensive API. Is that the gist of it?

Yes. This is what we told you all the time. OpenGL is a very low level
rendering API.

> [ visualization case example ]

Like you presumed, for this kind of application, one uses special purpose
visualization libraries, which may build atop, among others, OpenGL.

Wolfgang Draxinger

unread,
Nov 19, 2009, 2:26:22 PM11/19/09
to
Rui Maciel wrote:

> What about those applications where artists don't necessarily come into
> play, such as CAD and scientific visualization?

Also there it's better to supply normals explicitly. Take your example CAD:
In a CAD geometry is processed as analytic primitives, i.e. a exact
mathematical definition. Prior to suppling such primitives to OpenGL one
must convert them into vertices and edge lists, i.e. tesselate it. When
tesselating an analytic representation into vertices, one can directly
derive the normals, too, thus sparing the detour of reconstructing
approximate normals from approximately sampled vertices. (It's faster, too).

aku ankka

unread,
Nov 19, 2009, 3:38:08 PM11/19/09
to
On Nov 19, 8:11 pm, Rui Maciel <rui.mac...@gmail.com> wrote:

> aku ankka wrote:
> As I understand it, that doesn't negate the potential benefits of off-loading normals computations to opengl.
> As long as the vertices are defined and geometry can be deduced then it would be possible to automatically
> calculate the normal vectors, with the added benefit of being able to avoid transferring data around and
> taking advantage of dedicated hardware to perform those operations.

Not really. The "service" this functionality would offer wouldn't be
anything the client application couldn't do just as easily and only
advantage would be more driver bloat. The hardware is using
"streaming" model for many practical reasons, so waiting to have all
the data, then stalling to do something with it would be equivalent to
resolve, or at least pipe stall. I mean, this is assuming some sort of
hardware acceleration would be attempted.

You realize that the renderer couldn't start until it gets the last
vertex of the last triangle, since the normal generator has to see the
whole data-set to get all the connectivity information that is
required. Infact, doing that w/o indexed primitives would be, well,
not very good results. And, if you use indexed primitives then the
normal generation would be limited to one batch (eg. a draw command).
Unless you add API to define when a normal set begins and ends, eg.
boundary definition API and that would be more hassle than it's worth.

glVertex and it's friends is not really high-performance rendering
path, unless you are building display lists. So "optimizing" that path
wouldn't be very productive. And, if you use indexed primitives, the
data is indeed already bind at draw elements time, so this approach
has SOME merit but anyway.

What you need is complete API overhaul to make your suggestion
practical and it still wouldn't offer anything the client app couldn't
do!


> Wouldn't it be simpler if opengl could also take care of those normals?

Not really; see above.


> I don't have a good grasp of the pipeline process, which may be the key to understand why it would be better
> to avoid letting opengl handle this issue. Nonetheless, when the programmer calls glNormal()doesn't data get
> transfered around?

Not really, not on a modern hardware anyway. The data is transfered in
larger batches. Internally it makes sense to use temporary VBO and use
the same rendering back-end that renders VBO's (or DL's or similar).

Eventually the data gets transfered, of course. =)


> What about those applications where artists don't necessarily come into play, such as CAD and scientific
> visualization?

I would do research on OpenCL kernels and geometry shaders to come up
with ways to synthesize the data then. But still, if the vertices
don't move in model coordinates there isn't much need to recompute the
normals for each draw command.

jbwest

unread,
Nov 19, 2009, 8:40:59 PM11/19/09
to

"Rui Maciel" <rui.m...@gmail.com> wrote in message
news:4b058f3f$0$9660$a729...@news.telepac.pt...

It's *impossible* to calculate "good" normals for a finite element array
from just vertices & connectivity. You can't "know" where to put sharp
"creases" in the model. A cube ends up looking like a fuzzy blob. Or you
DONT have shared smooth vertex normals and height fields look like crap. You
are under the misapprehention that computing normals for a complex geometry
is simple -- it is NOT. It requires additoinal knowledge held by the domain
application, and not a triangle rendering library.

Think about how you would generate smooth normals for a topo map. Now add
a sharp cliff -- what would you do?. "smear" through it with smooth
normals-- that won't work. What, then about a "less sharp" cliff ? See? You
can't do it.


jbw

0 new messages