SkyBoxの背景Textureを滑らかに他の背景Textureにするやつ


環境

  • Unity5.5
  • DOTween

最近そういう処理が必要になったので調べてみたら、そんなに難しくなかったので書きました。

skybox対応の背景を切り替えるシェーダーを書きました pic.twitter.com/7EASBkudVN

— UKS*KUZ (@superDebu12) 2017年4月6日

Shader側のPropertyには

  • skyboxに必要な各方向のTexture6枚を2パターン
  • ブレンド値 : _blend

を定義します。

_blendの値を見てTextureをガッチャンコさせます。

BlendSkybox.shader
Shader "Skybox/Blend" {
Properties {
    _Tint ("Tint Color", Color) = (.5, .5, .5, .5)
    _Blend ("Blend", Range(0.0,1.0)) = 0.5
    _FrontTex ("Front (+Z)", 2D) = "white" {}
    _BackTex ("Back (-Z)", 2D) = "white" {}
    _LeftTex ("Left (+X)", 2D) = "white" {}
    _RightTex ("Right (-X)", 2D) = "white" {}
    _UpTex ("Up (+Y)", 2D) = "white" {}
    _DownTex ("Down (-Y)", 2D) = "white" {}
    _FrontTex2("2 Front (+Z)", 2D) = "white" {}
    _BackTex2("2 Back (-Z)", 2D) = "white" {}
    _LeftTex2("2 Left (+X)", 2D) = "white" {}
    _RightTex2("2 Right (-X)", 2D) = "white" {}
    _UpTex2("2 Up (+Y)", 2D) = "white" {}
    _DownTex2("2 Down (-Y)", 2D) = "white" {}
}

SubShader {
    Tags { "Queue" = "Background" }
    Cull Off
    Fog { Mode Off }
    Lighting Off
    Color [_Tint]
    Pass {
        SetTexture [_FrontTex] { combine texture }
        SetTexture [_FrontTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
    Pass {
        SetTexture [_BackTex] { combine texture }
        SetTexture [_BackTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
    Pass {
        SetTexture [_LeftTex] { combine texture }
        SetTexture [_LeftTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
    Pass {
        SetTexture [_RightTex] { combine texture }
        SetTexture [_RightTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
    Pass {
        SetTexture [_UpTex] { combine texture }
        SetTexture [_UpTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
    Pass {
        SetTexture [_DownTex] { combine texture }
        SetTexture [_DownTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
    }
}

Fallback "Skybox/6 Sided", 1
}

 Script側

Script側では_blendの値をDoTweenで動かしてます。

CustomSkyBox.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class CustomSkyBox : MonoBehaviour {

    [SerializeField]
    private Light directionalLight;

    [SerializeField]
    private Material material;

    private bool isBlendComplete;
    private float _blend;

    [SerializeField]
    private float blendDuration;

    void Awake()
    {
        _blend = 0.0f;
        directionalLight.intensity = 0.0f;
    }

    void Start()
    {
        StartCoroutine (gameLogic());
    }

    IEnumerator gameLogic()
    {
        bool toggle = true;
        while (true) {
            yield return new WaitForSeconds (5.0f);

            yield return StartCoroutine(CO_BlendSkyBoxTexture (toggle));
            toggle = !toggle;
        }

    }

    public IEnumerator CO_BlendSkyBoxTexture(bool toggle)
    {
        isBlendComplete = true;
        float startValue = toggle ? 0.0f : 1.0f;
        float endValue = toggle ? 1.0f : 0.0f;

        DOTween.To (blend => _blend = blend, startValue, endValue, blendDuration)
            .OnComplete (() => {
                isBlendComplete = false;
            });

        yield return new WaitWhile (() => isBlendComplete == true);

    }

    void Update()
    {
        UpdateMaterial ();
    }

    void UpdateMaterial()
    {
        directionalLight.intensity = (1.0f - _blend) * 8.0f;
        material.SetFloat ("_Blend", _blend);
    }
}

すごい適当な解説

skyboxはmaterialに設定された6つのTextureを見て背景に描画してるっぽい(詳しいことは調べてない)ので、そのTextureに対して遷移先のTextureをブレンドしてやれば実装出来た。