先日2016/7/2にLive2Dカンファレンス、alive2016がありました
そのなかで栗坂こなべ氏が「瞳の反射」についてLTと展示を行っていて
「背後空間の光源が瞳の奥に映る」という部分で
この部分がリアルタイムに変化するとより表現が広がんじゃないか?ということで
モデルの準備
まずはモデルを用意します
テクスチャーが一個まるまる変質するので映す映像のテクスチャーは専用でつくらなければなりません
画像は2の倍数でないと認識しないので注意が必要です
おまけに写った時の位置関係も重要ですからカメラ画像から整形したものを使用したほうがいいでしょう
そして別段変形の予定がなければ三角形は2個で大丈夫ですが瞳に合わせて変形するのでそこそこ割っておきます
瞳に入れるときは黒目か白目でクリッピングして加算。そして大体50%ほどに透過する
お好みで細かい連動処理をいれてもいいでしょう。
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();
}
}
結果サンプル