Using the Engine API
Let's build a simple Gaussian splat application step by step using the PlayCanvas Engine directly. We'll create a scene with an interactive 3D toy cat splat that you can rotate around.
Starting Point
Let's set up our project with two files: an HTML file and a JavaScript file.
First, create an index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body { margin: 0; overflow: hidden; }
</style>
<script type="importmap">
{
"imports": {
"playcanvas": "https://cdn.jsdelivr.net/npm/playcanvas/+esm"
}
}
</script>
</head>
<body>
<script type="module" src="main.js"></script>
</body>
</html>
Next, create a main.js
file with the basic PlayCanvas application setup:
import { Application, Asset, AssetListLoader, Entity, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO } from 'playcanvas';
// Create application
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const app = new Application(canvas, {
graphicsDeviceOptions: {
antialias: false
}
});
app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
app.setCanvasResolution(RESOLUTION_AUTO);
app.start();
window.addEventListener('resize', () => app.resizeCanvas());
This creates an empty 3D scene using the Application
class with a canvas that:
- Fills the entire browser window (
FILLMODE_FILL_WINDOW
) - Automatically adjusts resolution based on device pixel ratio (
RESOLUTION_AUTO
) - Properly resizes when the window changes size
We can't see anything rendered yet though - we need to load assets and add a camera and content.
We've disabled antialias
in the graphics device options for optimal splat rendering performance. This setting helps reduce the fragment processing load, which is the primary bottleneck in Gaussian splat rendering. Learn more in the Performance guide.
Loading Assets
Before we can display a splat or add camera controls, we need to load the assets our app will use. We'll use the Asset
class to define our assets and the AssetListLoader
to load them efficiently. Add this code to main.js
where the comment says "We'll add our code here step by step":
// Load assets
const assets = [
new Asset('camera-controls', 'script', {
url: 'https://cdn.jsdelivr.net/npm/playcanvas/scripts/esm/camera-controls.mjs'
}),
new Asset('toy', 'gsplat', {
url: 'https://developer.playcanvas.com/assets/toy-cat.compressed.ply'
})
];
const loader = new AssetListLoader(assets, app.assets);
await new Promise(resolve => loader.load(resolve));
We're loading two assets:
- A camera controls script that will let us orbit around the scene
- A compressed PLY file containing a toy cat splat
The AssetListLoader
loads all assets efficiently and we use await
to ensure they're fully loaded before proceeding.
Adding a Camera
To view our scene, we need to create a camera entity using the Entity
class and add a camera component to it. Add this code to main.js
after the asset loading:
// Create camera entity
const camera = new Entity('Camera');
camera.addComponent('camera');
camera.setPosition(0, 0, -2.5);
app.root.addChild(camera);
We've positioned the camera 2.5 units down the negative Z axis. By default, a camera looks down the negative Z axis, so our camera is now looking toward the origin where we'll place our splat.
Adding Camera Controls
Now let's make the camera interactive by attaching the camera controls script using the script component. Add this code to main.js
after the camera creation:
// Add camera controls
camera.addComponent('script');
camera.script.create('cameraControls');
Since we've already loaded the camera controls script using AssetListLoader
, we can directly create the script component. The camera controls will allow you to:
- Left mouse drag: Orbit around the target
- Right mouse drag: Pan the camera
- Mouse wheel: Zoom in and out
Adding the Splat
Now let's add our toy cat splat to the scene using the gsplat component. Add this code to main.js
after the camera controls:
// Create splat entity
const splat = new Entity('Toy Cat');
splat.addComponent('gsplat', { asset: assets[1] });
splat.setPosition(0, -0.7, 0);
splat.setEulerAngles(180, 0, 0);
app.root.addChild(splat);
We reference the splat asset using assets[1]
(the second asset in our array). We've positioned the splat slightly below the origin (-0.7 on the Y axis) and rotated it 180 degrees around the X axis to orient it properly.
Complete Code
Here are the complete files with all the code from the steps above:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body { margin: 0; overflow: hidden; }
</style>
<script type="importmap">
{
"imports": {
"playcanvas": "https://cdn.jsdelivr.net/npm/playcanvas/+esm"
}
}
</script>
</head>
<body>
<script type="module" src="main.js"></script>
</body>
</html>
main.js:
import { Application, Asset, AssetListLoader, Entity, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO } from 'playcanvas';
// Create application
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const app = new Application(canvas, {
graphicsDeviceOptions: {
antialias: false
}
});
app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
app.setCanvasResolution(RESOLUTION_AUTO);
app.start();
window.addEventListener('resize', () => app.resizeCanvas());
// Load assets
const assets = [
new Asset('camera-controls', 'script', {
url: 'https://cdn.jsdelivr.net/npm/playcanvas/scripts/esm/camera-controls.mjs'
}),
new Asset('toy', 'gsplat', {
url: 'https://developer.playcanvas.com/assets/toy-cat.compressed.ply'
})
];
const loader = new AssetListLoader(assets, app.assets);
await new Promise(resolve => loader.load(resolve));
// Create camera entity
const camera = new Entity('Camera');
camera.addComponent('camera');
camera.addComponent('script');
camera.script.create('cameraControls');
camera.setPosition(0, 0, -2.5);
app.root.addChild(camera);
// Create splat entity
const splat = new Entity('Toy Cat');
splat.addComponent('gsplat', { asset: assets[1] });
splat.setPosition(0, -0.7, 0);
splat.setEulerAngles(180, 0, 0);
app.root.addChild(splat);
Final Result
After completing the steps above, you should see an interactive 3D toy cat splat that you can orbit around, pan, and zoom!
Create both files above (index.html
and main.js
) in the same directory and open index.html
in your browser to see your first splat app in action! Then extend it in any way you like using the full power of the PlayCanvas Engine!