LoginSignup
11
7

More than 5 years have passed since last update.

[Unity] Oculus Utilitiesに含まれているOVRScreenFade(フェード)が面白かったのでメモ

Last updated at Posted at 2015-11-20

通常のゲームであればPost Effectでフェードイン・アウトを実現すれば比較的簡単に実装できると思う。
が、以前の記事で書いた方法をVRで試すとうまく行かなかった。
(使っているCardboard SDKとの相性の問題もあるかも。(おそらく)歪みをPostEffectで処理しているせいだと思ってる)

で、Oculusではそのあたりどうしているのかというと、どうやら画面全体を覆う板ポリを描いてそれを徐々に黒くする(あるいは黒から透明にする)という方法で実現しているみたい。(板ポリはあくまで概念で実際にはピクセルシェーダを操作しているんだと思うけど)

C#コード

Utilityに含まれているCSコードは以下のようになっている。

using UnityEngine;
using System.Collections;

public class OVRScreenFade : MonoBehaviour {

    public float fadeTime = 2.0f;
    public Color fadeColor = new Color(0.01f, 0.01f, 0.01f, 1.0f);

    private Material fadeMaterial = null;
    private bool isFading = false;
    private YieldInstruction fadeInstruction = new WaitForEndOfFrame();

    void Awake() {
        fadeMaterial = new Material(Shader.Find("Oculus/Unlit Transparent Color"));
    }

    void OnEnable() {
        StartCoroutine(FadeIn());
    }

    void OnLevelWasLoaded(int level) {
        StartCoroutine(FadeIn());
    }

    void OnDestroy() {
        if (fadeMaterial != null) {
            Destroy(fadeMaterial);
        }
    }

    IEnumerator FadeIn() {
        float elapsedTime = 0.0f;
        fadeMaterial.color = fadeColor;
        Color color = fadeColor;
        isFading = true;
        while (elapsedTime < fadeTime) {
            yield return fadeInstruction;
            elapsedTime += Time.deltaTime;
            color.a = 1.0f - Mathf.Clamp01(elapsedTime / fadeTime);
            fadeMaterial.color = color;
        }
        isFading = false;
    }

    void OnPostRender() {
        if (isFading) {
            fadeMaterial.SetPass(0);
            GL.PushMatrix();
            GL.LoadOrtho();
            GL.Color(fadeMaterial.color);
            GL.Begin(GL.QUADS);
            GL.Vertex3(0f, 0f, -12f);
            GL.Vertex3(0f, 1f, -12f);
            GL.Vertex3(1f, 1f, -12f);
            GL.Vertex3(1f, 0f, -12f);
            GL.End();
            GL.PopMatrix();
        }
    }
}

やっていることはシンプルで、このスクリプトが読み込まれたタイミングで処理が始まり、毎フレームごとに FadeIn メソッドが呼ばれるようにしている。
そしてその処理の中で徐々にマテリアルの色を透明にしていく(=フェードイン)という流れだ。

OnPostRender メソッド内の GL クラスがなんなのかまだ調べてないけど、シェーダに対する処理なのは間違いない。で、内容的には Z値だけ若干カメラの奥方向に移動した四角形を描いてそれをシェーダに送っているのだと思う。

GL - Unity - Scripting API

シェーダコード

シェーダのコードは驚くほどシンプル。
Z値に対する書き込みをオフにし、普通の透過処理に必要なブレンドモードにした上で、あとは色を設定しているのみ。
Pass になにも書かれていないのはC#のコード側で SetPass されるためと思う。

Shader "Oculus/Unlit Transparent Color" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader {
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque" }
        LOD 100

        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
        Color [_Color]

        Pass { }
    } 
}

以上、Oculus Utilitiesに含まれているフェードの仕組みでした。
こうした既存のものを参考にするのはとても勉強になるなぁ。

11
7
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
11
7