[osg-users] Computing Normals for Drawables
s.d.hammett at googlemail.com
Fri Nov 6 11:05:24 PST 2009
2009/11/6 James Buckthorpe <James.Buckthorpe at gmail.com>:
> Hi there,
> Thank you for your responses, I really appreciate the input.
> Can I tell you little more about what I'm working on as that may clarify the problem. The application is a CAD app and it must be able to load in literally millions of objects. The objects are low detail meshes and for a worst case scenario, the scene has around 20million vertices. I'm not really concerned about detail, lighting looking too correct or even rendering performance, I'd gladly sacrifice some rendering performance to load the entire model in!
> What the system must be able to do is load the entire model (we have some guideline models) into memory, under a 32bit OS limit. A legacy app being replaced uses OpenGL slow paths (Begin/End) and computes the normals manually. This has 1 normal per triangle (or less for some flat surfaces) whereas OSG is using 1 normal per vertex. Sure it looks a LOT better and its also higher performance in OSG, but it's also using approximately double the memory to render the same model.
> I have heard about PagedLOD but I am not sure how much of a performance hit this will give us when the objects are loaded/unloaded, as there are literally millions of objects in a small viewable area. I just noticed that disabling the smoothing visitor for objects (ie: having no normals) saved several hundred megabytes, and found out by trial/error that in OSG each vertex Vec3f has a normal (Another Vec3f) and an index associated with it.
> So would you happen to know if there is anything I can do (bar PagedLOD) to reduce the memory consumption in this application? I was hoping to target the normal generation and output one normal per triangle as opposed to one per vertex, as this would shave a few hundred megabytes from the app when under load.
> Thank you,
Well one idea I've had kicking around in my head for several years,
may be possible with a custom vertex shader.
Take a sphere, generate a mesh for it, take the surface normals and store them.
(well actually you don't need to generate the mesh, working out a
normal for a point on the sphere is trivial)
Then for every triangle/quad, simply chose one of the stored normals
which is 'closest' to your calculated normal
and 'associate' the index for that normal with the primitive. After
all if you are flat shading stuff,
the minor difference between the proper normal and the 'closest'
normal will only have a minor effect on the
This scheme requires you be able to specify a 'normal index' array, I
don't think you can do this with the fixed pipeline,
which is why you'd need a customer vertex shader.
I'm not familiar enough with shaders though to say it's actually
possible to do that., but it looks doable.
This would save huge amounts of ram and you'd get away with only using
a byte for the normal index.
More information about the osg-users