Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
/* OpenSceneGraph example, osgparticleshader.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <osg/ShapeDrawable>
|
|
|
|
#include <osg/MatrixTransform>
|
|
|
|
#include <osg/Point>
|
|
|
|
#include <osg/PointSprite>
|
|
|
|
#include <osgDB/ReadFile>
|
|
|
|
#include <osgDB/WriteFile>
|
|
|
|
#include <osgGA/TrackballManipulator>
|
|
|
|
#include <osgGA/StateSetManipulator>
|
|
|
|
#include <osgViewer/ViewerEventHandlers>
|
|
|
|
#include <osgViewer/Viewer>
|
|
|
|
|
|
|
|
#include <osgParticle/ParticleSystem>
|
|
|
|
#include <osgParticle/ParticleSystemUpdater>
|
|
|
|
#include <osgParticle/ModularEmitter>
|
|
|
|
#include <osgParticle/ModularProgram>
|
|
|
|
|
|
|
|
#include <osgParticle/AccelOperator>
|
|
|
|
#include <osgParticle/DampingOperator>
|
|
|
|
#include <osgParticle/BounceOperator>
|
|
|
|
#include <osgParticle/SinkOperator>
|
|
|
|
|
|
|
|
void createFountainEffect( osgParticle::ModularEmitter* emitter, osgParticle::ModularProgram* program )
|
|
|
|
{
|
|
|
|
// Emit specific number of particles every frame
|
|
|
|
osg::ref_ptr<osgParticle::RandomRateCounter> rrc = new osgParticle::RandomRateCounter;
|
|
|
|
rrc->setRateRange( 500, 2000 );
|
|
|
|
|
|
|
|
// Accelerate particles in the given gravity direction.
|
|
|
|
osg::ref_ptr<osgParticle::AccelOperator> accel = new osgParticle::AccelOperator;
|
|
|
|
accel->setToGravity();
|
|
|
|
|
|
|
|
// Multiply each particle's velocity by a damping constant.
|
|
|
|
osg::ref_ptr<osgParticle::DampingOperator> damping = new osgParticle::DampingOperator;
|
|
|
|
damping->setDamping( 0.9f );
|
|
|
|
|
|
|
|
// Bounce particles off objects defined by one or more domains.
|
|
|
|
// Supported domains include triangle, rectangle, plane, disk and sphere.
|
|
|
|
// Since a bounce always happens instantaneously, it will not work correctly with unstable delta-time.
|
2015-04-13 18:43:56 +08:00
|
|
|
// At present, even the floating error of dt (which are applied to ParticleSystem and Operator separately)
|
Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
// causes wrong bounce results. Some one else may have better solutions for this.
|
|
|
|
osg::ref_ptr<osgParticle::BounceOperator> bounce = new osgParticle::BounceOperator;
|
|
|
|
bounce->setFriction( -0.05 );
|
|
|
|
bounce->setResilience( 0.35 );
|
|
|
|
bounce->addDiskDomain( osg::Vec3(0.0f, 0.0f, -2.0f), osg::Z_AXIS, 8.0f );
|
|
|
|
bounce->addPlaneDomain( osg::Plane(osg::Z_AXIS, 5.0f) );
|
|
|
|
|
|
|
|
// Kill particles going inside/outside of specified domains.
|
|
|
|
osg::ref_ptr<osgParticle::SinkOperator> sink = new osgParticle::SinkOperator;
|
|
|
|
sink->setSinkStrategy( osgParticle::SinkOperator::SINK_OUTSIDE );
|
|
|
|
sink->addSphereDomain( osg::Vec3(), 20.0f );
|
|
|
|
|
|
|
|
emitter->setCounter( rrc.get() );
|
|
|
|
program->addOperator( accel.get() );
|
|
|
|
program->addOperator( damping.get() );
|
|
|
|
program->addOperator( bounce.get() );
|
|
|
|
program->addOperator( sink.get() );
|
|
|
|
}
|
|
|
|
|
|
|
|
int main( int argc, char** argv )
|
|
|
|
{
|
|
|
|
osg::ArgumentParser arguments( &argc, argv );
|
|
|
|
|
|
|
|
std::string textureFile("Images/smoke.rgb");
|
|
|
|
while ( arguments.read("--texture", textureFile) ) {}
|
|
|
|
|
|
|
|
float pointSize = 20.0f;
|
|
|
|
while ( arguments.read("--point", pointSize) ) {}
|
|
|
|
|
|
|
|
double visibilityDistance = -1.0f;
|
|
|
|
while ( arguments.read("--visibility", visibilityDistance) ) {}
|
|
|
|
|
|
|
|
bool customShape = false;
|
|
|
|
while ( arguments.read("--enable-custom") ) { customShape = true; }
|
|
|
|
|
|
|
|
bool useShaders = true;
|
|
|
|
while ( arguments.read("--disable-shaders") ) { useShaders = false; }
|
|
|
|
|
|
|
|
/***
|
|
|
|
Customize particle template and system attributes
|
|
|
|
***/
|
|
|
|
osg::ref_ptr<osgParticle::ParticleSystem> ps = new osgParticle::ParticleSystem;
|
|
|
|
|
|
|
|
ps->getDefaultParticleTemplate().setLifeTime( 5.0f );
|
|
|
|
|
|
|
|
if ( customShape )
|
|
|
|
{
|
|
|
|
// osgParticle now supports making use of customized drawables. The draw() method will be executed
|
|
|
|
// and display lists will be called for each particle. It is always a huge consumption of memory, and
|
|
|
|
// hardly to use shaders to render them, so please be careful using this feature.
|
|
|
|
ps->getDefaultParticleTemplate().setShape( osgParticle::Particle::USER );
|
|
|
|
ps->getDefaultParticleTemplate().setDrawable( new osg::ShapeDrawable(new osg::Box(osg::Vec3(), 1.0f)) );
|
|
|
|
useShaders = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The shader only supports rendering points at present.
|
|
|
|
ps->getDefaultParticleTemplate().setShape( osgParticle::Particle::POINT );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the visibility distance of particles, due to their Z-value in the eye coordinates.
|
|
|
|
// Particles that are out of the distance (or behind the eye) will not be rendered.
|
|
|
|
ps->setVisibilityDistance( visibilityDistance );
|
|
|
|
|
|
|
|
if ( useShaders )
|
|
|
|
{
|
|
|
|
// Set using local GLSL shaders to render particles.
|
|
|
|
// At present, this is slightly efficient than ordinary methods. The bottlenack here seems to be the cull
|
|
|
|
// traversal time. Operators go through the particle list again and again...
|
|
|
|
ps->setDefaultAttributesUsingShaders( textureFile, true, 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The default methods uses glBegin()/glEnd() pairs. Fortunately the GLBeginEndAdapter does improve the
|
|
|
|
// process, which mimics the immediate mode with glDrawArrays().
|
|
|
|
ps->setDefaultAttributes( textureFile, true, false, 0 );
|
|
|
|
|
|
|
|
// Without the help of shaders, we have to sort particles to make the visibility distance work. Sorting is
|
|
|
|
// also useful in rendering transparent particles in back-to-front order.
|
|
|
|
if ( visibilityDistance>0.0 )
|
|
|
|
ps->setSortMode( osgParticle::ParticleSystem::SORT_BACK_TO_FRONT );
|
|
|
|
}
|
|
|
|
|
|
|
|
// At last, to make the point sprite work, we have to set the points size and the sprite attribute.
|
|
|
|
osg::StateSet* stateset = ps->getOrCreateStateSet();
|
|
|
|
stateset->setAttribute( new osg::Point(pointSize) );
|
|
|
|
stateset->setTextureAttributeAndModes( 0, new osg::PointSprite, osg::StateAttribute::ON );
|
|
|
|
|
|
|
|
/***
|
|
|
|
Construct other particle system elements, including the emitter and program
|
|
|
|
***/
|
|
|
|
osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter;
|
|
|
|
emitter->setParticleSystem( ps.get() );
|
|
|
|
|
|
|
|
osg::ref_ptr<osgParticle::ModularProgram> program = new osgParticle::ModularProgram;
|
|
|
|
program->setParticleSystem( ps.get() );
|
|
|
|
|
|
|
|
createFountainEffect( emitter.get(), program.get() );
|
|
|
|
|
|
|
|
/***
|
|
|
|
Add the entire particle system to the scene graph
|
|
|
|
***/
|
|
|
|
osg::ref_ptr<osg::MatrixTransform> parent = new osg::MatrixTransform;
|
|
|
|
parent->addChild( emitter.get() );
|
|
|
|
parent->addChild( program.get() );
|
|
|
|
|
|
|
|
// The updater can receive particle systems as child drawables now. The addParticleSystem() method
|
|
|
|
// is still usable, with which we should define another geode to contain a particle system.
|
|
|
|
osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater = new osgParticle::ParticleSystemUpdater;
|
2010-09-20 19:50:24 +08:00
|
|
|
//updater->addDrawable( ps.get() );
|
Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
|
|
|
|
osg::ref_ptr<osg::Group> root = new osg::Group;
|
|
|
|
root->addChild( parent.get() );
|
|
|
|
root->addChild( updater.get() );
|
|
|
|
|
2010-09-20 19:50:24 +08:00
|
|
|
// FIXME 2010.9.19: the updater can't be a drawable; otehrwise the ParticleEffect will not work properly. why?
|
|
|
|
updater->addParticleSystem( ps.get() );
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
|
|
|
geode->addDrawable( ps.get() );
|
|
|
|
root->addChild( geode.get() );
|
|
|
|
|
Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
/***
|
|
|
|
Start the viewer
|
|
|
|
***/
|
|
|
|
osgViewer::Viewer viewer;
|
|
|
|
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
|
|
|
|
viewer.addEventHandler( new osgViewer::StatsHandler );
|
|
|
|
viewer.addEventHandler( new osgViewer::WindowSizeHandler );
|
|
|
|
viewer.setSceneData( root.get() );
|
|
|
|
viewer.setCameraManipulator( new osgGA::TrackballManipulator );
|
|
|
|
|
|
|
|
// A floating error of delta-time should be explained here:
|
|
|
|
// The particles emitter, program and updater all use a 'dt' to compute the time value in every frame.
|
2015-04-13 18:43:56 +08:00
|
|
|
// Because the 'dt' is a double value, it is not suitable to keep three copies of it separately, which
|
Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
// is the previous implementation. The small error makes some opeartors unable to work correctly, e.g.
|
|
|
|
// the BounceOperator.
|
|
|
|
// Now we make use of the getDeltaTime() of ParticleSystem to maintain and dispatch the delta time. But..
|
|
|
|
// it is not the best solution so far, since there are still very few particles acting unexpectedly.
|
|
|
|
return viewer.run();
|
2010-09-20 19:50:24 +08:00
|
|
|
|
|
|
|
// FIXME 2010.9.19: At present, getDeltaTime() is not used and the implementations in the updater and processors still
|
|
|
|
// use a (t - _t0) as the delta time, which is of course causing floating errors. ParticleEffect will not work if we
|
|
|
|
// replace the delta time with getDeltaTime()... Need to find a solution.
|
Form Wang Rui, "An initial GLSL shader support of rendering particles. Only the POINT
type is supported at present. The attached osgparticleshader.cpp will
show how it works. It can also be placed in the examples folder. But I
just wonder how this example co-exists with another two (osgparticle
and osgparticleeffect)?
Member variables in Particle, including _alive, _current_size and
_current_alpha, are now merged into one Vec3 variable. Then we can
make use of the set...Pointer() methods to treat them as vertex
attribtues in GLSL. User interfaces are not changed.
Additional methods of ParticleSystem are introduced, including
setDefaultAttributesUsingShaders(), setSortMode() and
setVisibilityDistance(). You can see how they work in
osgparticleshader.cpp.
Additional user-defined particle type is introduced. Set the particle
type to USER and attach a drawable to the template. Be careful because
of possible huge memory consumption. It is highly suggested to use
display lists here.
The ParticleSystemUpdater can accepts ParticleSystem objects as child
drawables now. I myself think it is a little simpler in structure,
than creating a new geode for each particle system. Of course, the
latter is still compatible, and can be used to transform entire
particles in the world.
New particle operators: bounce, sink, damping, orbit and explosion.
The bounce and sink opeartors both use a concept of domains, and can
simulate a very basic collision of particles and objects.
New composite placer. It contains a set of placers and emit particles
from them randomly. The added virtual method size() of each placer
will help determine the probability of generating.
New virtual method operateParticles() for the Operator class. It
actually calls operate() for each particle, but can be overrode to use
speedup techniques like SSE, or even shaders in the future.
Partly fix a floating error of 'delta time' in emitter, program and
updaters. Previously they keep the _t0 variable seperately and compute
different copies of dt by themseleves, which makes some operators,
especially the BounceOperator, work incorrectly (because the dt in
operators and updaters are slightly different). Now a getDeltaTime()
method is maintained in ParticleSystem, and will return the unique dt
value (passing by reference) for use. This makes thing better, but
still very few unexpected behavours at present...
All dotosg and serialzier wrappers for functionalities above are provided.
...
According to some simple tests, the new shader support is slightly
efficient than ordinary glBegin()/end(). That means, I haven't got a
big improvement at present. I think the bottlenack here seems to be
the cull traversal time. Because operators go through the particle
list again and again (for example, the fountain in the shader example
requires 4 operators working all the time).
A really ideal solution here is to implement the particle operators in
shaders, too, and copy the results back to particle attributes. The
concept of GPGPU is good for implementing this. But in my opinion, the
Camera class seems to be too heavy for realizing such functionality in
a particle system. Myabe a light-weight ComputeDrawable class is
enough for receiving data as textures and outputting the results to
the FBO render buffer. What do you think then?
The floating error of emitters
(http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-May/028435.html)
is not solved this time. But what I think is worth testing is that we
could directly compute the node path from the emitter to the particle
system rather than multiplying the worldToLocal and LocalToWorld
matrices. I'll try this idea later.
"
2010-09-14 23:47:29 +08:00
|
|
|
}
|