Fireworks with Shaders
As with any code, it is important to have a firm idea of what you want to achieve, what is possible to code, and the design.
Requirements
The requirements are for a collection of colored facets to burst out from a central position so that each fragment lies on the surface of an expanding sphere. All fragments should be equally spaced on the sphere and should change color during the expansion, fading over time.
First Stage Design
A sphere created in Babylon.js is made up of facets where vertices of adjoining facets share normals to ensure a smooth surface. Converting the sphere to a flat shaded mesh will give each facet its own set of normals which will be the mathematical normals for the plane of the facet. To make a facet travel outwards from the centre over time, its position at any time will be start position + normal * function of time.
The sphere is flat shaded, and the normals for the three vertices of each facet will be the same. The original position of each vertex and its normal are accessible to the shader as attributes, so passing time as a uniform will be enough.
To obtain an initially fast expansion that then slows down, a logarithmic function of time will be used.
Second Stage Design
The color and transparency of all the facets will be the same at the same time, so a change to each component of the color of a vertex can be applied as a function of time.
Third Stage Design
After the first coding of the shaders, adjustments were made manually to the time functions to obtain a satisfactory appearance for the burst of facets.
Shader Material Code
Vertex Shader Main Function
void main(void) { vec3 p = position; vec3 j = vec3(0., -1.0, 0.); p = p + normal * log2(1. + time) * 25.0; gl_Position = worldViewProjection * vec4(p, 1.0);}Fragment Shader Main Function
void main(void) { gl_FragColor = vec4(1. - log2(1. + time)/100., 1. * log2(1. + time), 0., 1. - log2(1. + time/2.)/log2(1. + 3.95));}Sphere
import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";var sphere = MeshBuilder.CreateSphere("sphere", { diameter: 10 }, scene);sphere.convertToFlatShadedMesh();sphere.material = shaderMaterial;Animation Loop
var t = 0;var time = 0;scene.registerBeforeRender(function () { if (time < 8) { sphere.material.setFloat("time", time); time += 0.1; } else { sphere.dispose(); }});Fireworks
External Example - Shader Material
PG: Fireworks