LoginSignup
9
11

More than 5 years have passed since last update.

Live2Dキャラの瞳に姿を映そう

Posted at

先日2016/7/2にLive2Dカンファレンス、alive2016がありました
そのなかで栗坂こなべ氏が「瞳の反射」についてLTと展示を行っていて
「背後空間の光源が瞳の奥に映る」という部分で
この部分がリアルタイムに変化するとより表現が広がんじゃないか?ということで

モデルの準備

まずはモデルを用意します
テクスチャーが一個まるまる変質するので映す映像のテクスチャーは専用でつくらなければなりません
追加.PNG
画像は2の倍数でないと認識しないので注意が必要です
おまけに写った時の位置関係も重要ですからカメラ画像から整形したものを使用したほうがいいでしょう
そして別段変形の予定がなければ三角形は2個で大丈夫ですが瞳に合わせて変形するのでそこそこ割っておきます
wari.PNG
瞳に入れるときは黒目か白目でクリッピングして加算。そして大体50%ほどに透過する
目.PNG
お好みで細かい連動処理をいれてもいいでしょう。

Webカメラの取り込み

Unity側のプログラムです
動作としてはWebCamTextureを起動してUpdateで
毎回SetPixle32とGetPixle32で受け渡しをしてやります
対応するテクスチャーは大きさが合わないのでWebCamから生成したテクスチャーを
setTextureで差し替え

hitomi.cs
using UnityEngine;
using System;
using System.Collections;
using live2d;
using System.Text.RegularExpressions;

[ExecuteInEditMode]
public class SimpleModel : MonoBehaviour 
{
    public TextAsset mocFile ;
    public Texture2D[] textureFiles ;

    // Webカメラ取り込み
    public WebCamTexture camTex;
    // とり込み結果反映用
    private Texture2D camTex2D;

    private Live2DModelUnity live2DModel;
    private Matrix4x4 live2DCanvasPos;

    private EyeBlinkMotion ebm;

    void Start ()
    {
        if (live2DModel != null) return;
        Live2D.init();
        ebm = new EyeBlinkMotion();
        ebm.setEyeMotion(100, 50, 100);
        ebm.setInterval(5000);

        // Webカメラ処理 今回はFaceRig探してる
        WebCamDevice[] devices = WebCamTexture.devices;

        foreach ( var ele in devices)
        {
            if(Regex.IsMatch(ele.name,"Face"))
            {
                camTex = new WebCamTexture(ele.name);
                camTex.Play();
                camTex2D = new Texture2D(camTex.width, camTex.height);
            }
        }

        live2DModel = Live2DModelUnity.loadModel(mocFile.bytes);
        for (int i = 0; i < textureFiles.Length; i++)
        {
            live2DModel.setTexture(i, textureFiles[i]);
            textureFiles[i].hideFlags = HideFlags.None;

        }

        //Webカメラの処理結果に最終テクスチャを差し替え
        live2DModel.setTexture(3, camTex2D);

        float modelWidth = live2DModel.getCanvasWidth();
        live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50.0f, 50.0f);
    }

    void Update()
    {
        if (live2DModel == null) return;
        live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);

        if (!Application.isPlaying)
        {
            live2DModel.update();
            return;
        }

        //Webカメラから反映用のテクスチャに移す処理
        camTex2D.SetPixels32(camTex.GetPixels32());
        camTex2D.Apply(); //コレを呼ばないと処理が完了しないとかなんとか

        ebm.setParam(live2DModel);

        live2DModel.update();
    }

    void OnRenderObject()
    {
        if (live2DModel == null) return;
        live2DModel.draw();
    }

    void OnApplicationQuit()
    {
        camTex.Stop();
    }
}

結果サンプル

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