[osg-users] Computing Normals for Drawables
s.d.hammett at googlemail.com
Mon Nov 9 05:41:59 PST 2009
2009/11/9 Andrew Burnett-Thompson <aburnettthompson at googlemail.com>:
> Hi guys,
> Interesting conversation on solving this problem. I'm working with James on
> this and he's away this week, so I thought I'd reply to keep the
> conversation going, and also to thank you for your input.
> Just to throw another requirement into the mix, I don't think we can use
> vertex shaders, as we cannot guarantee what hardware the software will be
> run on. Basically integrated graphics is the lowest possible hardware, so
> what's that, DirectX 8? 9? Vertex shaders run on DX8 but you won't get many
> Can this not be done on the CPU side only? Interestingly we did float the
> idea of computing a shared normal array (a sphere coated with normals) for
> all objects in the scene, then provide indices between Geometry vertices and
> the shared normal array, however we really didn't know if this was possible
> in OSG, or if it would work.
> A quick look at osg::Geometry source code there is a function
> setNormalIndices, so perhaps if we were to create a NodeVisitor that did the
> following this could work?
> 1. On creation of the nodeVisitor, create an osg::Vec3Array for shared
> normals. Populate with normals in all directions.
> 2. As the NodeVisitor walks the tree, for each Geometry object use the code
> from SmoothingVisitor to calculate what the normal should be
> 3. Rather than store that normal in an array and pass to the Geometry,
> instead find the closest normal to it in the shared normal array,
> 4. Store the index to the shared normal, and finally set the indices on the
> Geometry using setNormalIndices
> This would be done once on load or creation of an object. It wouldn't matter
> to take the performance hit once per load, nor would it matter if this
> slowed down rendering. We already employ aggressive use of culling to
> achieve decent rendering framerate when the object count is high. The hard
> limit is memory.
> Thanks a lot for your input,
The only way to do it with the fixed pipeline I can think of, is basically
just sort all your geometry into group's by the approximate normal, then
you don't have to store the normal index at all so you'd save more memory.
Doing it that way you're using BIND_OVERALL and vertex buffers so
you're still using
osgs fast path. Makes updating geometry a pain, but that doesn't sound like a
problem from your description.
Also with grouping the geometry this way you aren't restricted to a
using a power of
two number of normals, you can just try different numbers of normals
till you get
reasonable looking results.
More information about the osg-users