Explosion        

There are several ways to make explosion graphics in Ogre, and most involve using animated billboard sprites or particles or some combination of both. The method described on this page is a very basic method that will give you a single animated sprite that always faces the camera and loops through the explosion animation once and then disappears.

We will be using the particle system with a 3d/volume texture and a very simple custom shader.

Pros of this method:

  • The frames of the animation will be blended together so the animation looks smooth.
  • Unlike using an anim_texture your explosions will always start with the first frame and end on the last frame and won't repeat.
  • Unlike using billboardsets with an atlas you don't have to manually update the index value for your billboards to progress the animation.


Cons of this method:

  • You use the alpha value of the vertex to control the speed of the animation and not to control the alpha value of the particle.
  • Volume textures aren't as easy to create as typical animated sprite textures like atlases or single frames.


For another way of doing an animated particle without a volumetric texture, see Random Particle Texture (HLSL).

First grab your explosion animation frames and convert them into a volume texture called explode.dds using something like the DrTex.exe utility that comes with the DirectX SDK. You will want each frame of your animation to occupy it's own slice in the volume texture. If you are unfamiliar with volume textures, just think of them as a stack of 2d textures on top of one another. I ordered mine so that the bottom slice has the first frame of the animation and the top slice has the last frame.

For your convenience here is an explosion volume texture I created using Positech Games Free Explosion Generator

 Plugin disabled

Plugin file cannot be executed.


Here is a free volumetric texture creator if DxTex isn't working and you don't have photoshop.

You are free to use this explosion texture for whatever without attribution.

In your code create the particle effect like so:

// create a particle system named explosions using the explosionTemplate
ParticleSystem* particleSystem = sceneManager->createParticleSystem("explosions", "explosionTemplate");

// fast forward 1 second  to the point where the particle has been emitted
particleSystem->fastForward(1.0);

// attach the particle system to a scene node
sceneNode->attachObject(particleSystem);


Create an explosion.particle file in your materials/scripts folder

particle_system explosionTemplate
{
	material        	explosionMaterial  // The material for the particles
	particle_width  	50                 // The width of the particle
	particle_height 	50                 // The height of the particle
	cull_each       	true
	quota           	1
	billboard_type  	point
	sorted			true

	emitter Point
	{
	   angle           180
	   duration	   1    // This controls the duration of the emitter in seconds (1 second)
    	   emission_rate   1    // This controls how many particles are emitted per second - just 1
    	   time_to_live    1   	// Each particle lives this many seconds - just 1 second
	}

   	affector ColourFader
   	{
   		alpha -1        // Each second the alpha value is changed by this amount - so in one second our alpha goes from 1 to 0
   	}
}

Create an explosion.material file in your materials/scripts folder:

vertex_program explodeVertexProgramHLSL hlsl
{
	source explode.hlsl
	entry_point main_vp
	target vs_2_0
}

vertex_program explodeVertexProgramGLSL glsl
{
	source explode_vp.glsl
}

vertex_program explodeVertexProgram unified
{
	delegate explodeVertexProgramHLSL
	delegate explodeVertexProgramGLSL
}

fragment_program explodeFragmentProgramHLSL hlsl
{
	source explode.hlsl
	entry_point main_fp
	target ps_2_0
}

fragment_program explodeFragmentProgramGLSL glsl
{
	source explode_fp.glsl
	default_params
	{
		param_named tex int 0
	}
}

fragment_program explodeFragmentProgram unified
{
	delegate explodeFragmentProgramHLSL
	delegate explodeFragmentProgramGLSL
}

material explosionMaterial
{
	technique
	{
		pass
		{
			lighting off
			scene_blend add
			depth_write off
			
			vertex_program_ref explodeVertexProgram
			{
				param_named_auto worldViewProj worldviewproj_matrix
			}
			
			fragment_program_ref explodeFragmentProgram
			{
			}

			// texture unit 0 - our volume texture
			texture_unit
			{
				texture explode.dds 3d
				tex_address_mode clamp
				filtering linear linear none
			}
		}
	}
}

Create the explode.hlsl file in your materials/programs folder:

/*
  Our explosion vertex program that just passes the alpha value of the vertex
  on to the fragment program
*/
void main_vp(float4 position : POSITION,
			float2 uv		  : TEXCOORD0,
			float4 color	: COLOR0,
							  
			out float4 oPosition : POSITION,
			out float2 oUv	   : TEXCOORD0,
			out float4 oColor   : COLOR0,

			uniform float4x4 worldViewProj)
{
	oPosition = mul(worldViewProj, position);
	oUv = uv;
	oColor = color;
}

void main_fp(
	float4 position	: POSITION,
	float2 uv		: TEXCOORD0,
	float4 color	: COLOR0,

	uniform sampler3D tex:register(s0),
	
	out float4 oColour	: COLOR)
{
	oColour = tex3D( tex, float3(uv.x, uv.y, 1.0 - color.a));
}


Create the explode_vp.glsl file in your materials/programs folder:

/*
  Our explosion vertex program that just passes the alpha value of the vertex
  on to the fragment program
*/
uniform mat4 worldViewProj;

void main()
{
   gl_FrontColor = gl_Color;
   gl_TexCoord[0] = gl_MultiTexCoord0;
   gl_Position = ftransform();
}


Create the explode_fp.glsl file in your materials/programs folder:

uniform sampler3D tex;

void main()
{
   vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
   vec3 textureAccessIndex = vec3(0.0, 0.0, 0.0);
   textureAccessIndex.x = gl_TexCoord[0].s;
   textureAccessIndex.y = gl_TexCoord[0].t;
   textureAccessIndex.z = gl_Color.a * 16.0;
   color = texture3D(tex, textureAccessIndex);
   gl_FragColor = color;
}


Thanks to Roberto (che1404) for the GLSL version!! http://ogre3d.org/forums/viewtopic.php?f=5&t=64140

TODO - This system can be extended so we're not creating a single particle system for each explosion! Also other particle effects can be EASILY added like sparks, smoke and debris.