A geometry shader in hlsl using FX composer to resemble an explosion. This shader can be used on any object you put the shader on.
This is the source code of the shader.
//GLOBAL VARIABLES //**************** float4x4 gMatrixWorldViewProj : WORLDVIEWPROJECTION; float4 gColorDiffuse : COLOR = float4(1.0, 1.0, 1.0, 1.0); float4x4 gMatrixWorld : WORLD; float3 gLightDirection:DIRECTION < string UIName = "Light Direction"; string Object = "TargetLight"; > = float3(0.577f, 0.577f, 0.577f); float gTimer< string UIName = "Timer Elapsed"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 5.0f; float UIStep = 0.01f; > = 0.0f; float gThickness< string UIName = "Thickness"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 0.5f; float UIStep = 0.01f; > = 0.0f; float gSpeed< string UIName = "Explosion Speed"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 1.0f; float UIStep = 0.01f; > = 0.0f; float gExplosionForce< string UIName = "Explosion Force"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 10.0f; float UIStep = 0.01f; > = 0.0f; float gBreakability< string UIName = "Strength"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 10.0f; float UIStep = 0.01f; > = 0.0f; //float3 gEyePos //< //string UIName = "Eye Position" //>=float3(10,5,0); float3 gGravity < string UIName = "Gravity Vector"; > = float3(0.577f, 0.577f, 0.577f); float3 gExplosionLocation < string UIName = "Explosion Location"; > = float3(0.0f, 0.0f, 0.0f); float gExplosionFalloffTime< string UIName = "Falloff Time"; string UIWidget = "Slider"; float UIMin = 0.0f; float UIMax = 10.0f; float UIStep = 0.01f; > = 0.0f; //STATES //****** RasterizerState gRasterizerState { FillMode = SOLID; CullMode = NONE; }; SamplerState samLinear { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap;// of Mirror of Clamp of Border AddressV = Wrap;// of Mirror of Clamp of Border }; BlendState EnableBlending { BlendEnable[0] = TRUE; SrcBlend = SRC_ALPHA; DestBlend = INV_SRC_ALPHA; }; DepthStencilState EnableDepth { DepthEnable = TRUE; DepthWriteMask = ALL; }; //********** // STRUCTS * //********** struct VS_INPUT { float3 Position : POSITION; float4 Color : COLOR; float3 Normal : NORMAL; }; struct VS_OUTPUT { float4 Position : SV_POSITION; float4 Color : COLOR; float3 Normal : NORMAL; }; struct GS_DATA { float4 Position : SV_POSITION; float4 Color : COLOR; float3 Normal : NORMAL; }; //MAIN VERTEX SHADER //****************** VS_OUTPUT MainVS(VS_INPUT input){ VS_OUTPUT output = (VS_OUTPUT)0; //Set the variables output.Position = float4(input.Position,1.0f); output.Color = gColorDiffuse; output.Normal = normalize(input.Normal); return output; } //GEOMETRY SHADER //***************** void CreateVertex(inout TriangleStream<GS_DATA> triStream, float3 pos, float3 normal, float4 color) { GS_DATA output = (GS_DATA)0; output.Position = mul(float4(pos, 1), gMatrixWorldViewProj); output.Normal = mul(normal, (float3x3)gMatrixWorld); output.Color = color; triStream.Append(output); } [maxvertexcount(24)] void Explosiongenerator(triangle VS_OUTPUT vertices[3], inout TriangleStream<GS_DATA> triStream) { //---------------- //GEOMETRY SHADER //---------------- float3 triCenter, explosionVector, offset, gravity; //CALCULATE VECTOR AWAY FROM EXPLOSION CENTER triCenter = (vertices[0].Position + vertices[1].Position + vertices[2].Position) / 3; float3 fromCenter = normalize(triCenter-gExplosionLocation); float explosionForce = gExplosionForce-(distance(triCenter,gExplosionLocation)); if(explosionForce<=gBreakability) { explosionForce = 0; } //CREATE THE OFFSET FROM THE STARTLOCATION if(gTimer*gSpeed>=explosionForce) { offset = fromCenter*explosionForce*explosionForce + 0.5*-fromCenter*pow(explosionForce,2); }else{ offset = fromCenter*gTimer*gSpeed*explosionForce + 0.5*-fromCenter*pow(gTimer*gSpeed,2); } //GRAVITY gravity = 0.5*gGravity*pow(gTimer*gSpeed,2); if(explosionForce==0) { offset = float3(0,0,0); gravity = float3(0,0,0); } //CALCULATE THE FINAL POSITIONS OF THE CENTER float3 point1, point2, point3; point1 = vertices[0].Position+offset+gravity; point2 = vertices[1].Position+offset+gravity; point3 = vertices[2].Position+offset+gravity; if(point1.y <= 0) { point1.y = 0; } if(point2.y <= 0) { point2.y = 0; } if(point3.y <= 0) { point3.y = 0; } //CALCULATE OTHER POINTS FOR THICKNESS float3 point4, point5, point6; if(gThickness > 0) { point4 = point1-(vertices[0].Normal*gThickness); point5 = point2-(vertices[1].Normal*gThickness); point6 = point3-(vertices[2].Normal*gThickness); } //RECALCULATE NORMALS float3 normal1,normal2,normal3; float3 normalAll; if(gTimer*gSpeed>0 && explosionForce>0) { //if(acos(dot(triCenter-))) //{ //} normal1 = -normalize(cross(point3-point1,point2-point1)); normal2 = normal1; normal3 = normal1; }else{ normal1=vertices[0].Normal; normal2=vertices[1].Normal; normal3=vertices[2].Normal; } //Create Existing Geometry CreateVertex(triStream,point1,normal1,vertices[0].Color); CreateVertex(triStream,point2,normal2,vertices[1].Color); CreateVertex(triStream,point3,normal3,vertices[2].Color); //Create other side (thickness) if(gThickness > 0) { triStream.RestartStrip(); CreateVertex(triStream,point4,-normal1,vertices[0].Color); CreateVertex(triStream,point5,-normal2,vertices[1].Color); CreateVertex(triStream,point6,-normal3,vertices[2].Color); if(gTimer*gSpeed>0) { //SIDES OF THICKNESS (6 times) //FIRST normalAll = normalize(cross(point3-point1,point4-point1)); triStream.RestartStrip(); CreateVertex(triStream,point1,normalAll,vertices[0].Color); CreateVertex(triStream,point3,normalAll,vertices[1].Color); CreateVertex(triStream,point4,normalAll,vertices[2].Color); //SECOND normalAll = normalize(cross(point3-point4,point6-point4)); triStream.RestartStrip(); CreateVertex(triStream,point4,normalAll,vertices[0].Color); CreateVertex(triStream,point3,normalAll,vertices[1].Color); CreateVertex(triStream,point6,normalAll,vertices[2].Color); //THIRD normalAll = normalize(cross(point2-point3,point5-point3)); triStream.RestartStrip(); CreateVertex(triStream,point3,normalAll,vertices[0].Color); CreateVertex(triStream,point2,normalAll,vertices[1].Color); CreateVertex(triStream,point5,normalAll,vertices[2].Color); //FOURTH normalAll = normalize(cross(point6-point5,point3-point5)); triStream.RestartStrip(); CreateVertex(triStream,point5,normalAll,vertices[0].Color); CreateVertex(triStream,point6,normalAll,vertices[1].Color); CreateVertex(triStream,point3,normalAll,vertices[2].Color); //FIFTH normalAll = normalize(cross(point1-point2,point4-point2)); triStream.RestartStrip(); CreateVertex(triStream,point2,normalAll,vertices[0].Color); CreateVertex(triStream,point1,normalAll,vertices[1].Color); CreateVertex(triStream,point4,normalAll,vertices[2].Color); //SIXTH normalAll = normalize(cross(point5-point4,point2-point4)); triStream.RestartStrip(); CreateVertex(triStream,point4,normalAll,vertices[0].Color); CreateVertex(triStream,point5,normalAll,vertices[1].Color); CreateVertex(triStream,point2,normalAll,vertices[2].Color); } } } //MAIN PIXEL SHADER //***************** float4 MainPS(GS_DATA input) : SV_TARGET { input.Normal=-normalize(input.Normal); float alpha = input.Color.a; float3 color = input.Color.rgb; float s = max(dot(gLightDirection,input.Normal), 0.4f); return float4(color*s,alpha); } //TECHNIQUES //********** technique10 DefaultTechnique { pass p0 { SetRasterizerState(gRasterizerState); SetDepthStencilState(EnableDepth, 0); SetBlendState(EnableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); SetVertexShader(CompileShader(vs_4_0, MainVS())); SetGeometryShader(CompileShader(gs_4_0, Explosiongenerator())); SetPixelShader(CompileShader(ps_4_0, MainPS())); } }