All articles
Article 3 min read

Crafting a Particle Firework Effect with HTML and WebGPU

Delve into the creation of a dynamic particle firework effect in HTML using WebGPU and discover the importance of compute shaders along the way.

Introduction

Creating captivating visual effects like particle fireworks can elevate web experiences, making interactions more vibrant and engaging. While traditional methods utilizing HTML and CSS are effective, leveraging modern technologies such as WebGPU can take visual rendering to new heights. This article will guide you on how to implement a simple firework particle effect using HTML, JavaScript, and WebGPU, illuminating the potential of compute shaders in enhancing the complexity of your graphics.

What is WebGPU?

WebGPU is a modern graphics API that provides advanced rendering capabilities directly within web browsers. It offers a way to harness the power of the GPU for efficient processing, enabling developers to create rich visual experiences without relying solely on the CPU. The API allows for much faster data handling and computation, particularly for graphic-intensive applications.

Setting Up the Environment

First, ensure your development environment can utilize WebGPU. As of October 2023, only specific browsers like Chrome and Firefox provide support for WebGPU. Here’s how to set it up:

1.

Install the latest version of Chrome or any compatible browser.

2.

Enable WebGPU: This is often done through the Experimental Features in browser settings.

Basic HTML Structure

Create your basic HTML file for rendering the firework effect. Below is the initial code setup:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Particle Firework Effect</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script src="app.js"></script>
</body>
</html>

This code initializes a full-page canvas where the firework effect will be rendered.

Setting Up the JavaScript Application

Next, create an app.js file that will manage the WebGPU operations and the particle effect. Here’s a basic outline of how this can be structured:

Initialize WebGPU

Firstly, you need to set up WebGPU and obtain a rendering context:

javascript
const canvas = document.getElementById('canvas');
const context = canvas.getContext('webgpu');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const format = 'bgra8unorm';

// Configure the device context
context.configure({
    device: device,
    format: format,
    size: [canvas.width, canvas.height],
});

Create Particle Effect

Now, let's implement the logic for the firework effect using particles.

#### Particle Class

To manage the particles, define a simple class:

javascript
class Particle {
    constructor(x, y, vx, vy, life) {
        this.x = x;
        this.y = y;
        this.vx = vx;
        this.vy = vy;
        this.life = life;
    }

    update() {
        this.x += this.vx;
        this.y += this.vy;
        this.life--;
    }

    isAlive() {
        return this.life > 0;
    }
}

#### Managing Particle System

To create the firework effect, generate particles that mimic explosive behavior:

javascript
const particles = [];

function createFirework(x, y) {
    for (let i = 0; i < 100; i++) {
        const angle = Math.random() * Math.PI * 2;
        const speed = Math.random() * 5 + 1;
        const vx = Math.cos(angle) * speed;
        const vy = Math.sin(angle) * speed;
        particles.push(new Particle(x, y, vx, vy, 100));
    }
}

function updateParticles() {
    particles.forEach((particle, index) => {
        particle.update();
        if (!particle.isAlive()) {
            particles.splice(index, 1);
        }
    });
}

Rendering the Effect

You will ultimately need to render the particles to the screen using GPU commands:

javascript
function render() {
    // Clear the canvas
    const commandEncoder = device.createCommandEncoder();
    const renderPassDescriptor = {
        colorAttachments: [{
            view: context.getCurrentTexture().createView(),
            loadValue: [0, 0, 0, 1],
            storeOp: 'store',
        }],
    };
    const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    
    // Draw all particles
    particles.forEach(particle => {
        // Rendering logic for each particle