Helper to extract an equirectangular panorama PNG from any three.js scene.
Disclaimer: this library is from 2016. It has been rewritten for current three.js, so code written for version 1.x needs changes
three.js still doesn’t have this built in (checked on r186). What changed from the 2016 version:
update() returns the panorama and can skip the download, and there’s a dispose()Here’s a demo with some cubes: Demo

Use npm to install it, alongside three.js
npm i three three.cubemap-to-equirectangular
and import it in your code
import * as THREE from 'three';
import { CubemapToEquirectangular } from 'three.cubemap-to-equirectangular';
It’s a plain ES module, so it also works without a bundler as long as an import map resolves three and three/addons/ (see examples/index-managed.html).
Define a new instance of CubemapToEquirectangular.
// create renderer, scene, camera, etc.
const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( /* ... */ );
// Create a managed CubemapToEquirectangular
const equiManaged = new CubemapToEquirectangular( renderer, true );
// or create an unmanaged CubemapToEquirectangular
const equiUnmanaged = new CubemapToEquirectangular( renderer, false );
With Managed mode, the THREE.CubeCamera creation, update, render, etc. is all taken care of. You only have to call:
equiManaged.update( camera, scene );
at any point in your code that you want to extract a panorama. The cube map created will be 2048x2048 and the exported panorama will be 4096x2048. Note: The cubemap can easily be 4096x4096, but that seems to work on most mobiles, too
update() returns the panorama as an ImageData. To get it without downloading the PNG, call:
const imageData = equiManaged.update( camera, scene, false );
Demo of Managed mode: Demo
If you want to use a different CubeMap camera, or do something custom with the render, you will have to set the Unmanaged mode.
You will have to create and manage your THREE.CubeCamera:
const cubeCamera = new THREE.CubeCamera( .1, 1000, new THREE.WebGLCubeRenderTarget( 4096, {
type: THREE.HalfFloatType,
generateMipmaps: true,
minFilter: THREE.LinearMipmapLinearFilter
} ) );
The half float type keeps the linear colors of the render intact, and the mipmaps let the panorama be filtered.
Then manage all your scene update and rendering. When you want to export a panorama, call:
// this is where the developer updates the scene and creates a cubemap of the scene
cubeCamera.position.copy( camera.position );
cubeCamera.update( renderer, scene );
// call this to convert the cubemap rendertarget to a panorama
equiUnmanaged.convert( cubeCamera );
Demo of Unmanaged mode: Demo
To export a different size, call setSize( width, height ):
equi.setSize( 2048, 1024 );
To release the render targets when you’re done, call dispose():
equi.dispose();
three.js r155 or later, and WebGL 2. For three.js r116 and earlier use version 1.x of this library.
MIT licensed
Copyright (C) 2016 Jaume Sanchez Elias, http://www.clicktorelease.com