Generating Custom 360-Degree Panoramic Textures in Unity

Target Environment

  • Unity Version: 2022.3.20f1
  • Render Pipeline: Universal Render Pipeline (URP)
The workflow for generating a custom 360-degree panoramic image consists of three distinct stages:
  1. Capturing the 3D environment and rendering it into a source Cubemap.
  2. Extracting the six individual faces from the Cubemap.
  3. Stitching these faces into a single equirectangular panorama.

Step 1: Cubemap Capture

The initial phase requires capturing the scene from a specific point of view into a standard 6-face Cubemap. The following script automates this process by creating a temporary camera object, positioning it, and rendering the scene into the target Cubemap asset.

using UnityEngine;
using UnityEditor;
 
public class SceneCaptureTool : ScriptableWizard
{
    public Transform anchorPoint;
    public Cubemap targetCubemap;
 
    private void OnWizardUpdate()
    {
        helpString = "Assign a transform for the camera position and a target cubemap.";
        isValid = (anchorPoint != null) && (targetCubemap != null);
    }
 
    private void OnWizardCreate()
    {
        // Instantiate a temporary camera
        GameObject tempCamObj = new GameObject("TempCubemapCam");
        Camera captureCam = tempCamObj.AddComponent<Camera>();
        
        // Align with the target transform
        tempCamObj.transform.position = anchorPoint.position;
        tempCamObj.transform.rotation = Quaternion.identity;
        
        // Perform the render
        captureCam.RenderToCubemap(targetCubemap);
        
        // Cleanup
        DestroyImmediate(tempCamObj);
    }
 
    [MenuItem("Tools/Capture Scene to Cubemap")]
    private static void InitWizard()
    {
        ScriptableWizard.DisplayWizard<SceneCaptureTool>("Capture Scene", "Render");
    }
}

Step 2: Extracting Cubemap Faces

Once the Cubemap is generated, the individual faces must be extracted as standard image files. This script iterates through the six faces of the selected Cubemap, converts the pixel data into Texture2D objects, and saves them as JPG files in the same directory as the source asset.

using UnityEngine;
using UnityEditor;
using System.IO;

public class FaceExtractor : MonoBehaviour
{
    [MenuItem("Assets/Extract Cubemap Faces")]
    private static void ExtractFaces()
    {
        Cubemap source = Selection.activeObject as Cubemap;
        if (source == null)
        {
            Debug.LogError("Selection is not a Cubemap.");
            return;
        }

        string assetPath = AssetDatabase.GetAssetPath(source);
        string folderPath = Path.GetDirectoryName(assetPath);
        string baseName = Path.GetFileNameWithoutExtension(assetPath);

        foreach (CubemapFace faceType in System.Enum.GetValues(typeof(CubemapFace)))
        {
            // Create a temporary texture for the face
            Texture2D tempTex = new Texture2D(source.width, source.height, TextureFormat.RGB24, false);
            Color[] facePixels = source.GetPixels(faceType);
            
            tempTex.SetPixels(facePixels);
            tempTex.Apply();

            // Encode and save to disk
            byte[] jpgData = tempTex.EncodeToJPG();
            string outputPath = Path.Combine(folderPath, $"{baseName}_{faceType}.jpg");
            File.WriteAllBytes(outputPath, jpgData);

            Object.DestroyImmediate(tempTex);
        }

        Debug.Log("All faces extracted successfully to: " + folderPath);
        AssetDatabase.Refresh();
    }
}

Step 3: Combining Faces into a Panorama

The final step involves transforming the six orthogonal images into a single continuous equirectangular projection. While external tools like "Cubemap to Panorama" utilities can handle this, it is also possible to implement this entirely within Unity. Developers can write a custom Shader that performs the spherical projection logic. By applying this shader to a material and rendering it to a RenderTexture, the output can be saved as the final 360-degree panoramic image.

Tags: unity URP Cubemap Panorama Graphics Programming

Posted on Wed, 29 Jul 2026 16:36:45 +0000 by crishna369