Particles shader

Hi,

I want to create sine wave in which small particles will be moving. I am confused whether I should go for VBO FBO or should use shaders for that.
Below is the link which shows something similar I am trying to do.
http://www.ultrahaptics.com/

Please help me with that as I am new to VBO FBO and Shaders.

If any standard approach for doing such particle animation then suggest please.

There are many ways to do this.

One way is to start from the Cinder VboMesh sample. which shows how to make a waving plane.

To build a point mesh instead of a solid plane you can do this:

layout.usage( GL_DYNAMIC_DRAW ).attrib( geom::POSITION, 3 );

auto plane = geom::Plane().size( vec2( 20, 20 ) ).subdivisions( ivec2( 50, 50 ) );
auto triMesh = TriMesh::create( plane );
mParticles = gl::VboMesh::create( triMesh->getNumVertices(), GL_POINTS, { layout } );
mParticles->bufferAttrib( geom::POSITION, triMesh->getNumVertices() * sizeof( vec3 ), triMesh->getPositions< 3 >() );

The rest of the code is pretty much the same.

-Gabor

Tried doing with this code.
Point mesh is not getting created.

Please link or post your code so we can check what the issue is.

The code was sent as a direct message. I reply here with the changed sample.
mParticles was mVboMesh in the sample that caused a confusion, so didn’t rename it below.

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/GeomIO.h"
#include "cinder/ImageIo.h"
#include "cinder/CameraUi.h"

#include "Resources.h"

using namespace ci;
using namespace ci::app;

using std::vector;

class VboMeshApp : public App {
 public:
	void	setup() override;
	void	update() override;
	void	draw() override;

  private:
	gl::VboMeshRef	mVboMesh;

	CameraPersp		mCamera;
	CameraUi		mCamUi;
};

void VboMeshApp::setup()
{
	gl::VboMesh::Layout layout;
	layout.usage( GL_DYNAMIC_DRAW )
		.attrib( geom::POSITION, 3 );

	auto plane = geom::Plane().size( vec2( 20, 20 ) ).subdivisions( ivec2( 50, 50 ) );
	auto triMesh = TriMesh::create( plane );
	mVboMesh = gl::VboMesh::create( triMesh->getNumVertices(), GL_POINTS, { layout } );
	mVboMesh->bufferAttrib( geom::POSITION,
			triMesh->getNumVertices() * sizeof( vec3 ),
			triMesh->getPositions< 3 >() );

	mCamUi = CameraUi( &mCamera, getWindow() );
}

void VboMeshApp::update()
{
	float offset = getElapsedSeconds() * 4.0f;

	// Dynmaically generate our new positions based on a sin(x) + cos(z) wave
	// We set 'orphanExisting' to false so that we can also read from the position buffer, though keep
	// in mind that this isn't the most efficient way to do cpu-side updates. Consider using VboMesh::bufferAttrib() as well.
	auto mappedPosAttrib = mVboMesh->mapAttrib3f( geom::Attrib::POSITION, false );
	for( int i = 0; i < mVboMesh->getNumVertices(); i++ ) {
		vec3 &pos = *mappedPosAttrib;
		mappedPosAttrib->y = sinf( pos.x * 1.1467f + offset ) * 0.323f + cosf( pos.z * 0.7325f + offset ) * 0.431f;
		++mappedPosAttrib;
	}
	mappedPosAttrib.unmap();
}

void VboMeshApp::draw()
{
	gl::clear( Color( 0.15f, 0.15f, 0.15f ) );

	gl::setMatrices( mCamera );

	gl::ScopedGlslProg glslScope( gl::getStockShader( gl::ShaderDef() ) );

	gl::draw( mVboMesh );
}

CINDER_APP( VboMeshApp, RendererGl( RendererGl::Options().msaa( 16 ) ) )
1 Like

It worked.

Thank you @gabor_papp :slight_smile:

Hi

Is there any simple way with which glow effect can be given to particle mesh?

Or do we have to use some shaders for that?

You could use an image like this one and use additive blending. Image taken from this tutorial on OpenGL particle effects. Use the tutorial for ideas, not for code :slight_smile: