Hi there,

Here is something I wrote for an upcoming chapter of my slowly
progressing OSG tutorial, which maybe can, er, shed some light into
this. I haven't reviewed this text yet, so it may contain errors. Yet,
I think it may be useful.

LMB

--- 8< --- 8< ---

The only reason why lights are not exactly like the rest of the
rendering state is that, unlike almost everything else, they have a
positional nature: depending on where your light bulbs, candles,
torches or bonfires are located, the scene will be rendered
differently. Now, think about it: position is the key difference, and
OSG already has very good support to represent positions in the scene
(through hierarchies of transform nodes, like the
<tt>osg::PositionAttitudeTransform</tt> we have been using). Thus,
wouldn't it make a lot of sense to use transform nodes to set the
position of light sources? Yes, it would &mdash; and that's indeed how
things work in OSG. However, given the way that OpenGL handles lights,
we ended up with something that is a bit unintuitive.

Let's begin with the things that are just like the regular rendering
state we have seen before. There is one rendering mode
(<tt>GL_LIGHTING</tt>, which we have used in a previous example
program) that can be used to completely disable lighting in a
subgraph. When lighting is enabled, individual light sources can be
independently enabled or disabled using modes named
<tt>GL_LIGHT0</tt>, <tt>GL_LIGHT1</tt>, and so on (the number of
supported lights varies from implementation to implementation, but at
least eight are guaranteed to be there; if you ever need to know,
<tt>GL_MAX_LIGHTS</tt> contains the actual number of supported
lights).

So, there is nothing special on how we enable or disable individual
lights on a scene graph or subset of it. The two open questions are
how to set the light parameters (like color and direction) and how to
position them in the scene. Here is where things start to be
different. The answers to both questions are related to a node class,
<tt>osg::LightSource</tt>, which plays a few different roles.

First, a <tt>osg::LightSource</tt> has attached to it an instance of
an <tt>osg::Light</tt>, which is the <tt>osg::StateAtrribute</tt>
controlling the attributes of a light source. Playing with the
<tt>osg::Light</tt> methods, you can set the light color, or configure
it as, say, a point light that emits light to all directions or as a
spot light. The <tt>osg::Light</tt> has another fundamental
information, which is the light number. Light number <em>n</em> will
only illuminate parts of the scene graph that have the
<tt>GL_LIGHT<em>n</em></tt> mode enabled.

Second, the position of the <tt>osg::LightSource</tt> on the scene
(given by the transforms that appear between the root of scene graph
and the <tt>osg::LightSource</tt> itself) determines the position of
the light source in the world. Well, almost: the <tt>osg::Light</tt>
also contains a position attribute, but the position set there is
relative to the position of the <tt>osg::LightSource</tt>.

So, in summary: when you want a light in your scene, you add a
<tt>osg::LightSource</tt> to the scene graph, in a way that it is
properly translated to the position you want the light source to be
in. Then, you configure the light parameters on the
<tt>osg::Light</tt> that comes for free with your
<tt>osg::LightSource</tt> &mdash; don't forget to set the light
number. This will illuminate all the parts of scene graph that have
the corresponding <tt>GL_LIGHT<em>n</em></tt> mode enabled. Finally,
don't forget that disabling the <tt>GL_LIGHTING</tt> mode, the whole
lighting computation is bypassed.

What is so unintuitive about this? It is the fact that, if we think
about it, the <tt>osg::LightSource</tt> is not really emitting light.
It merely sets the position and attributes of a light source. If you
want parts of the scene being illuminated by this light, you still
must to enable the corresponding <tt>GL_LIGHT<em>n</em></tt> mode in
the desired subgraphs. (Yes, if you want to enable a light to the
whole scene you can just enable the mode in the graph root &mdash; the
state will be inherited normally).

There is one final practical tip to be given here. If you look at the
OSG reference documentation, you'll notice that an
<tt>osg::LightSource</tt> is an <tt>osg::Group</tt>. Can you guess why
this is useful? If you said "because all its children will be lit", go
to the blackboard and copy the previous paragraph 100 times! This is
useful because you may want to render some geometry (like a light
bulb) to represent your light source in the 3D world &mdash; and that
is the place to add it.


On Mon, Aug 30, 2010 at 6:19 AM, myth0904 <[email protected]> wrote:
> Hi Robert,
>
> Thanks for reply.
>
> Actually, i have attached osg::light to lightSource node.
> What makes me confused is why different results comes up when using the two
> ways of attaching light to lightSource node:
>
> first one: using setLight method
>> osg::LightSource* ls = new osg::LightSource;
>> ls->setLight(new osg::Light(0));
>
> The other one: using setAttribute
> osg::LightSource* ls = new osg::LightSource;
> ls->getOrCreateStateSet()->setAttribute(new osg::Light(0));
>
> ________________________________
> Rogerz
> 2010-08-30
> ________________________________
> 发件人: Robert Osfield
> 发送时间: 2010-08-30 16:19:08
> 收件人: OpenSceneGraph Users
> 抄送:
> 主题: Re: [osg-users] what's the difference between these two ways ofdefining
> light?
>
> Hi Rogerz?
> The OSG has to binding positional state like glLight/osg::Light with a
> modelview matrix to position it correctly in space, which is why there
> is a special node in the scene graph for positioning it - the
> osg::LightSource node.  If you don't attach your osg::Light to this
> special node then the light will be applied at an arbitrary point with
> an arbitrary modelview matrix that is current when it's applied - the
> result will be undefined, there is nothing the OSG can do about this -
> which is why the LightSource node exists - so use it.
> Robert.
> On Mon, Aug 30, 2010 at 4:25 AM, myth0904 <[email protected]> wrote:
>> I wanna add a head light into the scene, ie.,the light is always attched
>> with camera.
>>
>> For adding a light source into the scene, there are two different ways as i
>> know:
>>
>> 1 using osg::LightSource::  setLight method
>>
>>
>> osg::LightSource* ls = new osg::LightSource;
>> ls->setLight(new osg::Light(0));
>> ls->setReferenceFrame(osg::LightSource::ABSOLUTE_RF);
>> geode->setStateSet(ls->getOrCreateStateSet());
>>
>>
>> 2 using setAttribute method
>>
>> ls->getOrCreateStateSet()->setAttribute(new osg::Light(0));
>> geode->setStateSet(ls->getOrCreateStateSet());
>>
>>
>> I think two different ways should give the same result. Actually, they are
>> different.
>>
>> No. 1 Method:  the light behaves like directional light, but not head light.
>>
>> No.2 method:  just like head light.
>>
>>
>> who could tell me why the two ways are different?
>> which is correct?
>>
>>
>>
>> ________________________________
>> Rogerz
>> 2010-08-30
>> _______________________________________________
>> osg-users mailing list
>> [email protected]
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
>>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to