playcanvas-opti-pixel
v1.2.0
Published
GPU instancing, LOD, BVH frustum culling, and occlusion culling for [PlayCanvas](https://playcanvas.com/).
Readme
playcanvas-opti-pixel
GPU instancing, LOD, BVH frustum culling, and occlusion culling for PlayCanvas.
The library is built around a few independent systems that share the same ID and AABB conventions. Use only what you need.
| System | Start here | | --- | --- | | Hierarchical GPU instancing + LOD | Choosing an instancer | | Occlusion culling (HZB, queries, CPU software) | Choosing an occlusion backend | | Bounding volume hierarchy | BVH | | Shared stores, queues, data textures | Extras |
Full table of contents: docs/README.md.
Install
npm install playcanvas-opti-pixel playcanvasPeer: PlayCanvas 2.x (developed against playcanvas@^2.19). WebGL2 and WebGPU are both supported; not every occlusion backend is available on both.
import {
HierarchicalInstancer,
AABBStore,
SoftwareOcclusionTester,
OCCLUSION_OCCLUDED,
} from "playcanvas-opti-pixel";Minimal examples
Instancing with two LOD levels:
const instancer = new HierarchicalInstancer(app.graphicsDevice, { capacity: 1024 });
instancer.addLOD(lod0MeshInstances, rootEntity, 0);
instancer.addLOD(lod1MeshInstances, rootEntity, 40);
for (let i = 0; i < count; i++) {
instancer.setMatrixAt(i, matrices[i]);
}
instancer.computeBVH();
app.on("update", (dt) => {
instancer.update(dt, camera.camera, camera.getPosition());
});CPU software occlusion (skip draws that fail the last completed test):
const aabbs = new AABBStore(app.graphicsDevice, 4096);
const tester = new SoftwareOcclusionTester(aabbs, { width: 256, height: 128 });
const occludeeId = tester.lock(worldAabb);
tester.occluders.lockBox(occluderWorldMatrix);
app.on("update", (dt) => {
tester.enqueue(occludeeId);
tester.execute(camera.camera);
tester.frameUpdate(dt);
if (tester.getOcclusionStatus(occludeeId) !== OCCLUSION_OCCLUDED) {
// draw — treat OCCLUSION_UNKNOWN as visible
}
});OCCLUSION_UNKNOWN (-1) means there is no finished result yet. Draw in that case; do not hide the object.
Module map
Exports live in src/index.ts.
- Instancer —
BasicHierarchicalInstancer,SimpleHierarchicalInstancer,HierarchicalInstancer,BasicArrayHierarchicalInstancer, LOD fade helpers - Occlusion —
OcclusionCullingSystem, HZB (WebGL / WebGPU), occlusion queries (WebGL),SoftwareOcclusionTester+OccluderStore - BVH —
BVH,HybridBuilder - Extras —
AABBStore, square / mat4 / color data textures, index and GPU queues
Internal worker code, HZB shaders, and buffer layouts are not part of the public docs. See comments in src/ if you are changing the implementation.
API reference: GitHub Pages (built on main). Locally: npm run docs:api → docs/api/index.html.
