LoginSignup
37
35

More than 5 years have passed since last update.

Unityの基本機能だけを使ってSceneのキューブマップ(全天球画像)を作る

Last updated at Posted at 2016-04-10

追記:Unity2018以降はもっと簡単に作成できます

今までは無料のアセットを使ってやっていたのですが、

Camera.RenderToCubemap
機能:カメラからキューブマップにレンダリングします。

こんな便利な機能があったなんて知らなかった!
そして使ってみて超便利だったので共有します。

キューブマップにしたいシーンを作成

キューブマップを作るのに「まずキューブマップを用意します」では本末転倒になってしまうので、Sphereに全天球画像を貼り付けたりして作成します。
スクリーンショット 2016-04-10 20.39.04.png

ダミーのキューブマップ用テクスチャを用意

適当なテクスチャをプロジェクトにドロップします。
このテクスチャは後でキューブマップを作る際に上書きされてしまうので、消えてもいいものを使ってください。
* 追記:cubemapは、後でセーブされたものに差し替える必要があります。

ダミーのキューブマップ用テクスチャの設定を変更

ダミーのキューブマップ用テクスチャを選択し、Inspectorから設定を変更します。

  • Texture Type を Cubemap に変更

CubeMapマテリアルを用意

Create > Material でマテリアルを作成し、Shader > Skybox > 6Sided を選択、テクスチャにダミーのキューブマップテクスチャを指定します。

エディタースクリプトを用意

Editorフォルダを作成し、その中にこちらのUnityサンプルスクリプトを作成します。

  • 追記:サンプルのままだと保存されないので、こちらを参考にスクリプトを修正しました(天地逆に出力されていたのを修正)。
// // http://docs.unity3d.com/ja/current/ScriptReference/Camera.RenderToCubemap.html
// http://stackoverflow.com/questions/34458622/unity-save-cubemap-to-one-circle-image
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;
using System.IO;

public class RenderCubemapWizard : ScriptableWizard {

    public Camera camera;
    public Cubemap cubemap;

    void OnWizardUpdate () {
        string helpString = "Select transform to render from and cubemap to render into";
        bool isValid = (camera != null) && (cubemap != null);
    }

    void OnWizardCreate () {
        if (camera == null) {
            camera = Camera.main;
        }
        // render into cubemap      
        camera.RenderToCubemap( cubemap );
        cubemap.Apply ();
        ConvertToPng ();
    }

    [MenuItem("GameObject/Render into Cubemap")]
    static void RenderCubemap () {
        ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
            "Render cubemap", "Render!");
    }

    void ConvertToPng()
    {
        Debug.Log(Application.dataPath + "/" +cubemap.name +"_PositiveX.png");
        var tex = new Texture2D (cubemap.width, cubemap.height, TextureFormat.RGB24, false);
        var bytes = getPlanePixels(tex,CubemapFace.PositiveX);      
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name +"_PositiveX.png", bytes);       

        bytes = getPlanePixels(tex,CubemapFace.NegativeX);     
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name +"_NegativeX.png", bytes);       

        bytes = getPlanePixels(tex,CubemapFace.PositiveY);     
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name +"_PositiveY.png", bytes);       

        bytes = getPlanePixels(tex,CubemapFace.NegativeY);     
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name +"_NegativeY.png", bytes);       

        bytes = getPlanePixels(tex,CubemapFace.PositiveZ);     
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name +"_PositiveZ.png", bytes);       

        bytes = getPlanePixels(tex,CubemapFace.NegativeZ);     
        File.WriteAllBytes(Application.dataPath + "/"  + cubemap.name   +"_NegativeZ.png", bytes);       
        DestroyImmediate(tex);

    }

    byte[] getPlanePixels(Texture2D _tex, CubemapFace _face){
        Texture2D tmpTex = new Texture2D (cubemap.width, cubemap.height, TextureFormat.RGB24, false);
        tmpTex.SetPixels(cubemap.GetPixels(_face));
        Color[] vline;
        for (int x = 0; x < cubemap.width; ++x) {
            vline = tmpTex.GetPixels (x, 0, 1, cubemap.height);
            _tex.SetPixels (x, 0, 1, cubemap.height,vline.Reverse().ToArray());
        }
        return _tex.EncodeToPNG();     
    }

}

スクリプトを実行する

GameObjectメニューから Render into Cubemap を実行します。
スクリーンショット 2016-04-10 20.43.00.png

ダイアログウインドウが現れるので、
Render From Position にカメラを、Cubemapにダミーのキューブマップ用テクスチャを指定して実行します
スクリーンショット 2016-04-10 20.43.24.png

完成!

  • 追記:最終的に出力された6枚の画像をキューブマップのそれぞれの面に設定して完成です。
  • スクリーンショット 2016-04-11 22.51.20.png

  • Window > Lighting > Skyboxでキューブマップマテリアルを指定します。

スクリーンショット 2016-04-10 20.45.11.png

スクリーンショット 2016-04-10 20.46.39.png

37
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
35