Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This tool was created by Epic Games Slovakia, who doesn't carry any liability in case issues related to the sample occur.

© 2026 Epic Games, Inc. RealityScan® is a trademark of Epic Games, Inc. This tool is provided under the RealityScan End User License Agreement: https://www.realityscan.com/eula


pano2views

Browser-based converter from 360 equirectangular panoramas — or 360 video frames — to flat cube faces.

Drop a 2:1 equirectangular JPG/PNG (from any 360 camera — Insta360, GoPro Max, Ricoh Theta, etc.), or an equirect MP4/MOV video — or a whole folder of either — pick a field of view, click Convert. The faces come out as a ZIP, with the original folder structure preserved. Everything runs in the user's browser; no media are uploaded anywhere.

Features

  • Drop folders, images, or videos — drag any combination onto the page, or use "Choose folder" to pick one. Subfolders are walked recursively.
  • Video frame extraction — drop a 360 MP4/MOV and the tool pulls a frame every N seconds (configurable), then converts each frame to a cubemap. Already-stitched equirect videos only; raw .insv / .360 files aren't supported.
  • FOV slider — 60–120°, default 90°. 90° = standard cubemap (faces tile exactly). Higher = overlap (useful for photogrammetry). Lower = gaps.
  • Match source resolution by default — preserves the original pixel detail (e.g. 11968×5984 equirect → ~3000 px per face). Or pick a fixed size.
  • Auto-batching for huge jobs — long videos or massive folders are automatically split into multiple ~800 MB ZIPs so the browser tab doesn't run out of memory.
  • Privacy: WebGL processes images and video locally on the user's GPU. Pull the network cable after page load and it still works.

How it works

A WebGL2 fragment shader does the per-pixel work: for each output pixel, compute the camera-space ray from the FOV, rotate by the per-face yaw/pitch, convert to spherical coordinates, sample the equirect texture with bilinear filtering. JSZip packages the rendered faces into a download.

The conversion is a standard equirectangular-to-perspective projection applied once per cube face.

Output

Images flatten into their source folder — six face JPEGs per image, sitting next to siblings:

pano2views_cubemap_fov90.zip
└── <original-folder-path>/
    ├── <image-stem>_front.jpg
    ├── <image-stem>_right.jpg
    ├── <image-stem>_back.jpg
    ├── <image-stem>_left.jpg
    ├── <image-stem>_up.jpg
    └── <image-stem>_down.jpg

Videos get one folder of their own (many frame-faces would otherwise crowd out sibling images). Timestamps are zero-padded so they sort cleanly:

pano2views_cubemap_fov90.zip
└── <original-folder-path>/
    └── <video-stem>/
        ├── <video-stem>_t00000.00s_front.jpg
        ├── <video-stem>_t00000.00s_right.jpg
        ├── ...
        ├── <video-stem>_t00002.00s_front.jpg
        └── ...

If you drop loose files (no folder), <original-folder-path> is omitted — output sits at the ZIP root.

If Write RealityScan XMP sidecars is ticked (default), each .jpg ships with a matching .xmp carrying fixed calibration — focal derived from the FOV slider, principal point (0, 0), square aspect, no distortion, CalibrationPrior="exact". RealityScan reads the XMP on import and skips re-solving the intrinsics; no pose is written, so alignment is still free.

Files

index.html    UI + styles
layouts.js    face yaw/pitch tables (extensible — add more layouts here)
shaders.js    GLSL vertex + fragment source
render.js     WebGL2 setup, texture upload, per-face draw
app.js        drag-drop, folder walk, FOV slider, ZIP packaging

No build step, no npm, no framework.

Run locally

cd pano2views
python -m http.server 8000

Open http://localhost:8000 in any modern browser. (file:// won't work — image decoding has cross-origin restrictions.)

Deploy

GitHub Pages from the repo root, main branch. After pushing, go to Settings → Pages → set Source = "Deploy from branch" / Branch = main / (root). Site is live in ~30 seconds at https://<username>.github.io/pano2views/.

While the repo is private, the published URL is still publicly reachable but unindexed — anyone with the URL can use the tool. Repo + Pages access control behind GitHub login requires a GitHub Enterprise Cloud plan.

Browser support

Anything with WebGL2 (Chrome 56+, Firefox 51+, Edge 79+, Safari 15+) — ~96% of installed browsers.

Mobile works but is capped by the device's MAX_TEXTURE_SIZE (typically 4096–8192). Insta360 X3 11968×5984 equirects exceed that on most phones — use desktop for max-resolution sources.

Adding a new layout

Append to LAYOUTS in layouts.js:

LAYOUTS.myLayout = {
    label: "My layout",
    description: "Short description for the UI.",
    defaultFov: 100,
    faces: [
        { name: "v1", yaw: 0, pitch: 0 },
        // ...
    ],
};

Re-add a layout dropdown to index.html to expose it (currently hidden for the cubemap-only MVP).

About

No description, website, or topics provided.

Resources

Stars

52 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages