How To: Create a Cubemap in the Assets Folder Through Code

I’m trying to create an object, specifically a cube-map, and put that cube-map in the Assets folder for easy use. how would I do that? I’ve tried using the Directory and Application classes, but I can’t figure it out!

I figured it out!

class RenderCubemapWizard extends ScriptableWizard 
{
    var cameraPosition : Transform;
    var cubemapToOverride : Cubemap;
   
    //Variables
    private static var projectPath : String;
   
    function OnWizardUpdate () 
    {
        helpString = "Select a camera to render from and cubemap to render into.\nIf you don't select a cubemap, one will be created.";
    }
   
    function OnWizardCreate () 
    {
        // create temporary camera for rendering
        var go = new GameObject( "CubemapCamera", Camera );
        // place it on the object
        go.transform.rotation = Quaternion.identity;
        if (cameraPosition == null)
        {
            Debug.Log ("You have to drag a Camera onto the 'cameraPosition' slot.");
            DestroyImmediate( go );
            return;
        }
        if (cubemapToOverride != null)
        {
            // render into cubemap   
            go.camera.RenderToCubemap( cubemapToOverride );
            DestroyImmediate( go );
        }
        else if (cubemapToOverride == null)
        {
            var newCubemap : Cubemap = new Cubemap(128, TextureFormat.ARGB32, false);
            go.camera.RenderToCubemap( newCubemap );
            AssetDatabase.CreateAsset(newCubemap, "Assets/NewCubemap.cubemap");
        }
       
        // destroy temporary camera
        DestroyImmediate( go );
    }
   
    @MenuItem("Keenan's Cool Tools /Render Camera into Cubemap")
    static function RenderCubemap () 
    {
        ScriptableWizard.DisplayWizard.<RenderCubemapWizard>("Render cubemap", "Render!");
    }
}
1 Like

Doesn’t seem like this will use compressed textures though.

Here is correct approach that also allows for compressed textures.

#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.IO;

public class RenderCubemapUtil : ScriptableWizard
{
    public Transform renderFromPosition;
    public int size = 512;
    public string newCubmapPath;

    void OnWizardUpdate()
    {
        isValid = renderFromPosition != null && size >= 16 && !string.IsNullOrEmpty(newCubmapPath);
    }

    void OnWizardCreate()
    {
        if (!isValid) return;

        // create temporary camera for rendering
        var go = new GameObject("CubemapCamera");
        go.AddComponent<Camera>();

        try
        {
            // place it on the object
            go.transform.position = renderFromPosition.position;
            go.transform.rotation = Quaternion.identity;

            // create new texture
            var cubemap = new Cubemap(size, TextureFormat.RGB24, false);

            // render into cubemap
            go.GetComponent<Camera>().RenderToCubemap(cubemap);

            // convert cubemap to single horizontal texture
            var texture = new Texture2D(size * 6, size, cubemap.format, false);
            int texturePixelCount = (size * 6) * size;
            var texturePixels = new Color[texturePixelCount];

            var cubeFacePixels = cubemap.GetPixels(CubemapFace.PositiveX);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 0);
            cubeFacePixels = cubemap.GetPixels(CubemapFace.NegativeX);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 1);

            cubeFacePixels = cubemap.GetPixels(CubemapFace.PositiveY);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 3);
            cubeFacePixels = cubemap.GetPixels(CubemapFace.NegativeY);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 2);

            cubeFacePixels = cubemap.GetPixels(CubemapFace.PositiveZ);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 4);
            cubeFacePixels = cubemap.GetPixels(CubemapFace.NegativeZ);
            CopyTextureIntoCubemapRegion(cubeFacePixels, texturePixels, size * 5);

            texture.SetPixels(texturePixels, 0);

            // write texture as png to disk
            var textureData = texture.EncodeToPNG();
            File.WriteAllBytes(Path.Combine(Application.dataPath, $"{newCubmapPath}.png"), textureData);

            // save to disk
            AssetDatabase.SaveAssetIfDirty(cubemap);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
        finally
        {
            // destroy temporary camera
            DestroyImmediate(go);
        }
    }

    private void CopyTextureIntoCubemapRegion(Color[] srcPixels, Color[] dstPixels, int xOffsetDst)
    {
        int cubemapWidth = size * 6;
        for (int y = 0; y != size; ++y)
        {
            for (int x = 0; x != size; ++x)
            {
                int iSrc = x + (y * size);
                int iDst = (x + xOffsetDst) + (y * cubemapWidth);
                dstPixels[iDst] = srcPixels[iSrc];
            }
        }
    }

    [MenuItem("GameObject/Render into Cubemap")]
    static void RenderCubemap()
    {
        DisplayWizard<RenderCubemapUtil>("Render cubemap", "Render!");
    }
}
#endif
1 Like