Particles shader


#1

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.


#2

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


#3

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


#4

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


#5

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 ) ) )

#6

It worked.

Thank you @gabor_papp :slight_smile:


#7

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?


#8

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: