GFXLite is a lightweight 3D rendering engine built on top of WebGPU. It aims to provide a simple and easy-to-understand API for creating 3D scenes, handling geometry, materials, and cameras.
Currently in development and is not yet ready for production use.
GFXLite implements a modern, GPU-driven rendering pipeline designed for high performance and efficiency.
While the API is heavily influenced by Three.js for ease of use, the internals are built from the ground up for WebGPU. It adopts modern render strategies from high-performance frameworks like Bevy, prioritizing GPU-driven techniques over traditional CPU-heavy approaches.
- Unified Instance Storage: Uses monolithic Storage Buffers to store instance data (transforms, colors, etc.) for all objects, avoiding the overhead of multiple small uniform buffers.
- Automatic Batching: The
BatchManagerautomatically groups compatible meshes (same geometry and material) to maximize instance counts per draw call. - Indirect Drawing: leverages
drawIndexedIndirectto heavily reduce CPU-side render loop overhead. The CPU prepares batch data once, and the GPU handles the rest. - GPU Frustum Culling: A Compute Shader pass pre-calculates visibility for all instances in parallel before rendering. Only visible objects are added to the indirect draw buffer, significantly reducing vertex shading load.
To install the dependencies, run:
npm installTo start the development server and see the examples in action:
npm run devOpen your browser and navigate to the URL provided (usually http://localhost:5173).
Here is a simple example of how to create a scene with a box and a camera:
import { Renderer, Scene, PerspectiveCamera, BoxGeometry, Mesh, BasicMaterial, Vector3 } from "gfxlite";
// 1. Setup Renderer
const canvas = document.getElementById("gfx-canvas") as HTMLCanvasElement;
const renderer = new Renderer(canvas);
renderer.resize(window.innerWidth, window.innerHeight);
// 2. Create Scene
const scene = new Scene();
// 3. Create Camera
const camera = new PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 3, 10);
camera.lookAt(new Vector3(0, 0, 0));
// 4. Add Objects
const geometry = new BoxGeometry();
const material = new BasicMaterial({ color: new Vector3(1, 0.5, 0) });
const mesh = new Mesh(geometry, material);
scene.add(mesh);
// 5. Render Loop
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();