「普通の」というのはOculusの歪み補正などがかかってない普通のカメラ映像ってことです。

OculusRiftの映像というとよく見るのはこういう感じですね。

NailCanvasVR-20141030 (0-01-44-04)

「あ、Oculusの映像なのね」と知ってる人なら一目で分かってこれはこれでいいのですが、

映像が小さくなるし歪み補正やら色収差補正がかかっていて、

 

もっと絵として綺麗な状態で出したいんじゃ〜〜、

 

という内なる欲求が出たので稚拙ながら作ってみました。

 

このスクリプトを使うとOculusの視野内にカメラビューのウインドウが表示されまして、

Sキーを押すとそのウインドウの画角でPNG画像として書き出されます。

カメラビューイメージ2

↓こういう感じで。

OculusScreenshotCamera-20141102-054658

OculusRiftを装着しながら、見えている景色をそのまま保存したいと思ったわけであります。

 

やってることは単に板ポリにRenderTextureを貼ってるだけ。

板ポリに貼ってるだけ

なので普通に他オブジェクトに潜ったりします。

 

 

だがしかし、とりあえず開発しながらスクショ撮りまくれるやん。やったね!

 

もっとちゃんと作って「Oculusの空間内で35mmカメラを模擬」とかやるとちょっと面白そうな気も。

 

OculusScreenshotCamera-20141102-070700 OculusScreenshotCamera-20141102-070833 OculusScreenshotCamera-20141102-070937 OculusScreenshotCamera-20141102-083556

 

 

両手をLeapMotionにかざしたままスクショを撮りたい場合は、、、

 

足で押したらええんちゃうかな。↓

 

OculusScreenshotCamera-20141102-085601

 

スクリプトの使い方は、

Oculusの「OVRCameraRig」の下にある「CenterEyeAnchor」にスクリプトをアタッチするだけ。

使い方説明1

インスペクターのVertical FOVの値を変えると画角を変えられます。

使い方説明2

この数値を60にすると、だいたいOculusで見たときの横幅いっぱいまでカバーした広角の画像が撮れます。

今回自分は指をある程度大きく写したかったので38を初期値にしていますが、撮りたい絵によって変えてください。

68以上にするとカメラビューのオブジェクトが写り込んでしまいます。

ちゃんとやるならレンダリングから外すなり、オブジェクトに潜らないようZテスト外すなりするところですが、

とりあえず「C」キーでウインドウが非表示になるのでその状態でスクショ。オッケー。

 

保存される画像は横幅1920pixのPNG形式になっています。必要に応じて変更してください。

保存先は、 Application.persistentDataPathになっていてUnityエディタのコンソールに保存先のパスが表示されます。

あとは使い方によってマウスボタンでスクショとかにすると動きながら撮りやすいかも?

 

 

わたくしのプログラム脳はMSX-BASICで止まっているのでコードを晒すと失笑されそうなわけですが、汎用的に使えそうな気もするので載せてみます。

これじゃダメだろ!というダメ出しや、もっといい方法や既に同じようなプラグイン等があれば是非ご教授ください。(ツイッター@VoxelKei)

 

(追記:ちょっと変更しました→「OculusRiftで普通のスクショとそうでないスクショを撮るスクリプト」)

 

OculusScreenshotCamera.cs
using UnityEngine;
using System.Collections;
using System.IO;

public class OculusScreenshotCamera : MonoBehaviour
{
    public float verticalFOV = 38f;//縦方向の画角。必要に応じて変更してください。
    private Camera screenshotCamera;
    private RenderTexture renderTexture;
    private GameObject cameraViewObj;

    void Start ()
    {
        // スクリーンショット用のRenderTextureを生成
        renderTexture = new RenderTexture (1920, 1080, 16, RenderTextureFormat.ARGB32);

        // スクリーンショット用のカメラを生成
        screenshotCamera = gameObject.AddComponent<Camera> ();
        screenshotCamera.aspect = 1.778f;
        screenshotCamera.fieldOfView = verticalFOV;
        screenshotCamera.nearClipPlane = 0.1f;
        screenshotCamera.farClipPlane = 100.0f;//スケールの大きなシーンで使用する場合は数値を大きくしてください。
        screenshotCamera.targetTexture = renderTexture;

        // 確認用のカメラビューオブジェクトを生成
        cameraViewObj = GameObject.CreatePrimitive (PrimitiveType.Quad);
        cameraViewObj.name = "ScreenshotCameraWindow";
        cameraViewObj.transform.parent = transform;
        cameraViewObj.GetComponent<Renderer> ().material = new Material (Shader.Find ("Unlit/Texture"));
        cameraViewObj.GetComponent<Renderer> ().material.mainTexture = renderTexture;
        // 白枠オブジェクト
        GameObject outline = GameObject.CreatePrimitive (PrimitiveType.Quad);
        outline.transform.parent = cameraViewObj.transform;
        outline.transform.localPosition = new Vector3 (0, 0, 0.005f);
        outline.transform.localScale = new Vector3 (1.05f, 1.05f, 1.05f);
        outline.GetComponent<Renderer> ().material = new Material (Shader.Find ("Unlit/Color"));

        // 視野の下あたりに移動
        cameraViewObj.transform.localEulerAngles = new Vector3 (30f, 0, 0);
        cameraViewObj.transform.localPosition = new Vector3 (0, -0.25f, 0.3f);
        cameraViewObj.transform.localScale = new Vector3 (0.1422f, 0.08f, 1f);

        // 起動時は非表示にする場合はコメントアウトを外してください
        //cameraViewObj.SetActive (false);
    }

    void Update ()
    {
        // 「C」キーで確認用のカメラビューの表示非表示切り替え
        if (Input.GetKeyDown (KeyCode.C)) {
            if (cameraViewObj.activeInHierarchy) {
            cameraViewObj.SetActive (false);
            } else {
                cameraViewObj.SetActive (true);
            }
        }
        // 「S」キーでスクリーンショットを保存
        if (Input.GetKeyDown (KeyCode.S)) {
            TakeScreenShot ();
        }
    }

    void TakeScreenShot ()
    {
        // RenderTextureから直接エンコード出来ないので、Texture2DにコピーしてからEncodeToPNGする
        Texture2D captureImage = new Texture2D (1920, 1080, TextureFormat.RGB24, false);
        RenderTexture.active = renderTexture;
        captureImage.ReadPixels (new Rect (0, 0, 1920, 1080), 0, 0);
        RenderTexture.active = null;

        byte[] bytes = captureImage.EncodeToPNG ();//Jpeg保存する場合は、EncodeToJPGに変更してください。
        System.DateTime now = System.DateTime.Now;
        string filename = "OculusScreenshotCamera-" + now.ToString ("yyyyMMdd-HHmmss");
        File.WriteAllBytes (Application.persistentDataPath + "/" + filename + ".png", bytes);
        Debug.Log ("== OculusScreenshotCamera == saved image in : " + Application.persistentDataPath + "/" + filename + ".png");
    }
}

 

初めてSyntaxHighlighterを使ったんだけど、

インデントが反映されないのはどうしたらいいのでしょう・・・

(追記:SH TinyMCE Buttonというwordpressプラグインを使ったら出来た)