|
|
【Vocaloid初音ミクとMikuMikuDanceという驚愕のソフトウェア】 |
||
【リンクフリー】 私設研究所ネオテックラボ Neo-Tech-Lab.co.uk 【記載者】 私設研究所Neo-Tech-Lab.com 上田智章 |
|
|
ここにチェックボックス型外部コンテンツ・メニューが入ります。 | ||
|
|
【メニュー】 [index] ■メモ [PMD1] ●【VBA】ポリゴン・フィルとテクスチャー・マッピング [PMD2] ●【VBA】透視変換 [PMD3] ●【VBA】光源計算 [Sensor]★【NyARToolkitCS】拡張現実センサ【ソース公開】C# [PMD6] ■【NyARToolkitCS】MMDのPMDで拡張現実(モデル描画)C# [PMD4] ■【NyARToolkitCS】MMDのPMDで拡張現実(表情処理)C# [PMD5] ●IK bone制御 [Kinect]★【Kinect Sensor】拡張現実センサ2【ソース公開】C# [TTS] ★【iSpeech APIの音声合成TTS】【ソース公開】JavaScript [シンセ]★『JavaScriptでWebシンセサイザ/ボーカロイド(なんちゃって版)を自作してみた』 |
|
【Webシンセサイザ/ボーカロイドのページ】JavaScriptだけでシンセサイザやボーカロイドの歌唱/音声合成を実装してみようとする試みを始めました。【対象ブラウザ】Google Chrome12, Mozilla FireFox5, Apple Safari ●『なんちゃって初音ミク』NTL版Text-To-Speech API [JavaScript Ver.0.06] ●『なんちゃって初音ミク』Ieavan Polkka [JavaScript Ver.0.06] スタンダード・ドラム・セット付 音が出るまでに10~30秒を要します。気長にお待ちください。 【WebGLのページ】JavaScriptでリアルタイム3次元グラフィックスが楽しめる時代の到来までもうすぐです。現在、Google Chrome12、Mozilla FireFox5、及び開発版のSafari、Operaで使うことができます。 WebGLは、JavaScriptエンジンv8とDirectXを利用して高速化したOpenGLを融合して構成されたものです。 2011年5月に指摘されたセキュリティー問題はありますが、処理速度の高速性から利便性も高いので、将来的には普及するのではないでしょうか? ●WebGLとは? ●事前準備:利用できるウェブブラウザは? ●事前準備:FireFox5でWebGLが動作しない場合には? ●WebGLのサンプル ●WebGLのデモ ●クロスドメインテクスチャーを将来も利用できる方法 ●ローカルのPMDファイルを読み込んでJSON形式に変換し、3次元モデルを表示 ●物理エンジンBullet.jsのWebGLデモの紹介(Pl4n3氏のragdollデモの修正版)[btBoxShapeとbtCapsuleShape] |
【参考】鏡音リンを透視変換表示するExcel VBA |
バグ修正のお知らせ■バグを発見したので、NTL_Lib3DCG_ver048.zipをお使い下さい。詳しくはメモを書きましたのでこちらをご覧ください。 ■■■記載日2009年10月2日■■■ 【MikuMikuDanceのモデル(PMD)をExcel VBAで透視変換表示】さて、zバッファによる3次元陰面処理をかけてグローシェーディング・ポリゴン・フィルとテクスチャー・マッピングまで実装が完了したので、次は透視変換だ。 3次元グラフィックスの世界では、ハードウェアに近い下位処理のポリゴン・フィルなどの処理では加算や除算程度しか出てこないが、上位の処理になるにつれ、段々と数学的になってくる。あぁ、嫌だ。 透視変換とは『カメラ位置に近い程、画面上で大きく表示する』処理のことで遠近感を出すために使われる手法だ。何やら難しそうだが、実はサブルーチンを1個追加するだけで実現してしまう。 サブルーチンNTL_Matrix_LookAtを使ってVertex(頂点座標データ)だけ座標変換をかけてやるだけだ。 透視変換を行うには、 1) カメラ位置(眼の座標)を示す3次元座標Eye (x_Vector型) 2) 注視点座標(眼で見つめている場所)Target (x_Vector型) 3) 上方ベクトル(自分にとってどちらが上の方向であるかを示すベクトル)EyeUp (x_Vector型) 以上、3つのパラメータを指定する必要がある。 【スクリーン平面への投影理論】 図1に示すように、視点Eye(観測者の位置)をP、注視点Target(見ている場所)をO、座標変換される点をQとし、視点Pから注視点Oへのベクトルを、 視点Pから点Qへのベクトルをとする。ここで、点Oを含み、ベクトルと直交する 3次元空間中に存在する平面W(スクリーン平面)を考え、線分の 延長線と交差する平面W上の点Rへ点Qを投影する問題を考える。 【図1】座標変換 平面WはOを始点とし、ベクトルと直交するベクトルから成ると考えることができる。従って、投影された点をRとし、点Pおよび点Oから点Rへのベクトルを、とすると、次の2式が成立する。 (1) [直交しているから] (2) 上記、2式より (3) ここで、 (4) とおくことができるので、(3)式に(4)式を代入して よって (5) となりαが求まる。 従って、(4)式より、が求まり、さらに(2)式に代入してが得られる。 以上のように、任意の3次元の点(座標)がスクリーン平面W上に投影される。 【2次元座標への変換】 ベクトルは3次元空間に存在する平面W上のベクトルである。これを平面W上の2次元座標に変換する。点Oを始点とする平面W上の互いに直交する2つの単位ベクトルを、とする。これらのベクトルは視野の横(左右方向)軸および縦(上下方向)軸である。ベクトルとこれらの単位ベクトルの内積をとると、 (8) (9) となり、ベクトルは、上に投影される。これによって、3次元座標が2次元座標に変換されたことになる。 【図2】2次元座標への変換 【平面W上の直交する2つの単位ベクトル】 それでは一体どうやって、平面W上の互いに直交する2つの単位ベクトル、を求めればよいのだろうか? まず、注視点座標Targetとカメラ位置(眼の位置)Eyeから視線ベクトルevを求めることができる。 ev.x = Target.x - Eye.x ev.y = Target.y - Eye.y ev.z = Target.z - Eye.z これを正規化したものが単位ベクトルezとなる。 ここで、視線ベクトルevと上方ベクトルEyeUpを加えたベクトルを上記理論のと考え、この線分と平面wが交差する点を点Rと考える。そうすると(5)式を使って係数αが求まる。さらに(4)式からを得ることができる。さらにこれを(2)式に代入してベクトルが求まるのでこれを正規化してexとすればよいのである。 ここまでで、単位ベクトルezとeyが得られているので、この外積を取ればどちらのベクトルにも直交するベクトルexを得ることができるのである。 【スクリーンへの投影】 以上の方法で変換すれば、任意の3次元座標を見る位置や方向に基づいて、スクリーン上の2次元座標(x,y)に投影することができるが、陰面処理をかけるためにはz値が必要だ。 ここで、z値とは『観測者にとって近いか遠いかを示す距離』のことなので、ベクトルのez方向成分を求めることを意味している。つまりこの2つの内積をとればよい。 【図3】単位ベクトルの求め方 |
Public Ex As x_Vector ' 単位ベクトル(ex) Public Ey As x_Vector ' 単位ベクトル(ey) Public Ez As x_Vector ' 単位ベクトル(ez) Public Ev As x_Vector ' 視線ベクトル(Eye Line Vector) ' ****************************************************************************** ' ***** 【透視変換処理】 ' ****************************************************************************** ' 眼の座標, 注視点座標, 上方ベクトル, 頂点数, 入力頂点座標, 出力頂点座標 Public Sub NTL_Matrix_LookAt(Eye As x_Vector, Target As x_Vector, EyeUp As x_Vector, n As Long, inVertex() As PMD_vertex, outVertex() As x_Vector) Dim Ev2 As Single, Alpha As Single, wx As Single, wz As Single Ev.x = Target.x - Eye.x '【視線ベクトルPOの計算】 Ev.y = Target.y - Eye.y Ev.z = Target.z - Eye.z Ev2 = Ev.x * Ev.x + Ev.y * Ev.y + Ev.z * Ev.z Alpha = 1# / Sqr(Ev2) Ez.x = Ev.x * Alpha '【正規化した単位ベクトルez】 Ez.y = Ev.y * Alpha Ez.z = Ev.z * Alpha '【単位ベクトルeyの計算】 Alpha = Ev2 / ((Ev.x + EyeUp.x) * Ev.x + (Ev.y + EyeUp.y) * Ev.y + (Ev.z + EyeUp.z) * Ev.z) Ey.x = Alpha * (Ev.x + EyeUp.x) - Ev.x Ey.y = Alpha * (Ev.y + EyeUp.y) - Ev.y Ey.z = Alpha * (Ev.z + EyeUp.z) - Ev.z Alpha = 1# / Sqr(Ey.x * Ey.x + Ey.y * Ey.y + Ey.z * Ey.z) '【正規化のために1/絶対値を求める】 Ey.x = Ey.x * Alpha '【正規化した単位ベクトルey】 Ey.y = Ey.y * Alpha Ey.z = Ey.z * Alpha '【単位ベクトルexの計算】単位ベクトルexは視線単位ベクトルEzと単位ベクトルeyに直交するベクトル。外積で求める。 Ex.x = Ey.y * Ez.z - Ey.z * Ez.y Ex.y = Ey.z * Ez.x - Ey.x * Ez.z Ex.z = Ey.x * Ez.y - Ey.y * Ez.x '【透視変換処理】 For i = 0 To n - 1 '【平面座標への投影処理】 outVertex(i).x = inVertex(i).pos.x - Eye.x ' PQ outVertex(i).y = inVertex(i).pos.y - Eye.y outVertex(i).z = inVertex(i).pos.z - Eye.z Alpha = Ev2 / (outVertex(i).x * Ev.x + outVertex(i).y * Ev.y + outVertex(i).z * Ev.z) '【z座標は視線ベクトル方向の奥行き】 wz = outVertex(i).x * Ez.x + outVertex(i).y * Ez.y + outVertex(i).z * Ez.z outVertex(i).x = Alpha * outVertex(i).x outVertex(i).y = Alpha * outVertex(i).y outVertex(i).z = Alpha * outVertex(i).z '【2次元座標への変換】上記変換は単位ベクトルex,eyからなる平面上の3次元座標への変換なので、スクリーン座標に変換する。 wx = (outVertex(i).x - Ev.x) * Ex.x + (outVertex(i).y - Ev.y) * Ex.y + (outVertex(i).z - Ev.z) * Ex.z outVertex(i).y = (outVertex(i).x - Ev.x) * Ey.x + (outVertex(i).y - Ev.y) * Ey.y + (outVertex(i).z - Ev.z) * Ey.z outVertex(i).x = wx outVertex(i).z = wz Next i End Sub |