CubeMapからパノラマ画像を生成し、Sphereで天球を作る

Objectとしての天球をスカイボックスのように見せて、表現の幅を広げる話です。
今回は、このような演出を作りました。
CubeMapをパノラマ画像に変換し、それをSphereに適用して天球を作り、演出を試すところまでの備忘録を残します。

目次

カメラに映る景色をパノラマ画像として出力

CubeMap — 6面のテクスチャで立方体を作り、天球を表現
パノラマ画像 — エクイレクタングラー形式 (正距円筒図法)の画像で天球を表現


CubeMapのままだとShaderの自由が効かず、扱いにくい場合があります。
使いたいSkyboxの素材がCubeMapしか無かったので、パノラマ画像に変換する方法を模索しました。

実践

こちらの記事のおかげで出来ました!
素晴らしい記事をありがとうございます。
Unityでカメラのequirectangular画像を作成してみる


上記記事の「やったこと」欄の内容を辿る。

1. 新規Shader作成、CubemapToEquirectangular をコピペさせて頂く。
2. 新規Script作成、CubeMapCamera.cs をコピペさせて頂く。
3. 新規Material作成、1 の Shader を割り当てる。
4. これをCameraにApp Component、インスペクターの参照を渡す。
  CameraにCameraをアタッチ
  ConvMaterialに3のMaterialをアタッチ


ちょっとだけ改造。

5. 今回はImage表示する必要がないので、下記をコメントアウトする。
  42行目 image.GetComponent().material.mainTexture = equirectangularTexture;
6. 1回撮るだけなので、Update() の内容を全てStart() に移す。(または撮りたいタイミングに合うよう書き換える)
7. 画像として保存するためのScriptを、2行書き加える。

    byte[] bytes = equirectangularTexture.EncodeToPNG(); //テクスチャをPNGにする
    File.WriteAllBytes(Application.dataPath + "/SavedScreen.png", bytes); //プロジェクトフォルダへ書き出し



全部まとめると、改造後はこのようになりました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;

public class CubeMapCamera : MonoBehaviour
{

    public Camera camera;
    public Cubemap cubemap;
    //public Image image;
    public Material convMaterial;

    public int outputWidth = 4096;
    public int outputHeight = 2048;
    public int cubeWidth = 1280;

    private RenderTexture renderTexture;
    private Texture2D equirectangularTexture;

    // Use this for initialization
    void Start()
    {
        if (camera == null)
        {
            camera = Camera.main;
        }

        if (cubemap == null)
        {
            cubemap = new Cubemap(cubeWidth, TextureFormat.RGBA32, false);
        }

        if (convMaterial == null)
        {
            Shader conversionShader = Shader.Find("Conversion/CubemapToEquirectangular");
            convMaterial = new Material(conversionShader);
        }
        renderTexture = new RenderTexture(outputWidth, outputHeight, 24);
        equirectangularTexture = new Texture2D(outputWidth, outputHeight, TextureFormat.ARGB32, false);
        //image.GetComponent<Image>().material.mainTexture = equirectangularTexture;
    

        //ここから下を、任意のタイミングで発火させる。
        camera.RenderToCubemap(cubemap);

        Graphics.Blit(cubemap, renderTexture, convMaterial);
        equirectangularTexture.ReadPixels(new Rect(0, 0, outputWidth, outputHeight), 0, 0, false);
        equirectangularTexture.Apply();

        byte[] bytes = equirectangularTexture.EncodeToPNG(); //テクスチャをPNGにする
        File.WriteAllBytes(Application.dataPath + "/SavedScreen.png", bytes); //プロジェクトフォルダへ書き出し
    }
}

これでUnityエディタを再生→停止すると、パノラマ画像がAssets直下に保存されます。

Sphereで天球を作る2種類のやり方

1つは、Shaderを書き換えて「両面レンダリング」にすること。(Cull off にする)
もう1つは、内側がオモテになっているMeshを使うことです。


こんな便利なモデルを公開して下さっている方がいらっしゃいました。ありがたや、、、
Sphere100.fbx 360用全天球用FBXモデル(法線内側動画向き)

Skyドームをいじってみる

先程のお借りした天球モデルfbxをインポート後、Materialを変えるだけです。

これを複数並べても面白そうですね!

カメラがSphereの中に入ると、この夕焼け空をSkyboxとして適用しているような見た目になります。
パノラマ画像に変換しておいたので、シェーダーの自由がきいて更に扱いやすいです。

Skyドームを透明化してみました。
中にいると、空が変わったように見えます。

他にもSkybox の標準Materialでは出来なかった表現・Unity標準Skyboxでは出来なかった表現が色々出来るようにまりました。
オブジェクト化したことで回転の軸が自由になったのも嬉しいところ。昼夜表現などに使えそうです。
演出の幅が広がりますね!



今回の表現の完成形は、次作にて。
ご覧いただきありがとうございました!

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
目次