Aizu-Progressive xr Lab blog

会津大学のVR部であるA-PxLの部員が持ち回りで投稿していくブログです。部員がそれぞれVRに関する出来事やVRにちなんだことについて学んだことを書いていきます。

連絡はサークルTwitterのDMへお願いします。
「面白法人カヤックVR分室」としても活動しています。詳細はこちら

ここから始めるテクスチャ使用~テクスチャとマテリアルの違いについて~

皆さん、テクスチャつかってますか?

どうも、学部1年国分です。いきなりなにを言い出すのかと、そうお思いの方が大半でしょう。
私も書き出しがわからなかったのでこうなってしまったのです、許してください。

はい。皆さんテクスチャ使ってますか?
「この人なんでこんなにテクスチャ推してくるんだろう.....マテリアルで十分じゃない??」
分かります。自分も前はそう思ってました。しかしいつまでもマテリアルに頼っているわけにはいかんのです。
まずマテリアルとテクスチャを使い分けることの意味は何なんでしょうか。よくテクスチャを使っている人のモデルなどを見ると細部まで作りこまれていてすごくリアルなモデルに仕上がっている印象がありますよね。クオリティを上げるために使うのがテクスチャなのか。それもありますが、これだけならマテリアルでも頑張れば出来そうです。ではテクスチャを使うことの真の利点....それは処理の軽減です。

マテリアルとテクスチャの違いの一つとして、一つの色に対しての情報量の違いがあります。マテリアルには色の情報のほかにシェーダーの指定というものがあります。光源の位置によって色がどのように見えるかという処理を色に含んでいるのです。勝手に光源によっての処理をしてくれるので、一見この処理は便利に感じるかもしれません。しかしこれで細かいディティールを付けていくとしましょう。部位によってマテリアルをたくさん付けていくわけですがそのモデルを動かすとき、それについているマテリアルすべての計算処理が同時に行われるわけです。そういうモデルがゲーム上でたくさん存在するとしたら、当然滅茶苦茶重くなってしまいますね。多少のマテリアル使用ならともかくすべてをそれだけで補っていくのには無理があるのです。

そこで登場するのがテクスチャです。テクスチャとは、モデルに張り付ける画像です。マテリアルのようにリアルタイムでの処理ではなく画像で事前に疑似的に様々な処理を表現することができます。またマテリアルのように貼っていくのではなく一気に全体のディティール付けができるので楽に色付けの作業ができます。マテリアルで逐一色を付けていくよりもテクスチャソフトを使用していく方がいいですよね。

今回はテクスチャソフトを使う利点を説明してきました。次からは実際にSubstance Painterというソフトを使って簡単に使い方を説明していきます!

Trail Rendererで軌跡を描く

明けましておめでとうございます、学部2年の森川です。
今回はチームの方で使用するために作成したパーティクルの中で、Trail Rendererを用いた銃弾の軌跡のエフェクトの製作過程をまとめていきたいと思います。

f:id:aizu-vr:20190108212230p:plain


Trail Rendererの説明


 軌跡を表現するのに、"Trail Renderer"というコンポーネントを使用します。"Trail Renderer"の使い方について少し説明しておきます。

  • Materials
      Size : 値の数分Elementの配列を用意します。
      Element : 線(軌跡)の模様に使用するものをここに入れます。

  • Time
      軌跡の寿命を表してます。この値と弾の速さを調整することで、軌跡の長さを調整することができますね!

  • Min Vertex Distance
      簡単に説明してしまうと、軌跡を描写する時の荒さをここで調整することができます。
     値 = 1 を基準として考えるとして、
       値 = 0.1 -> より滑らかに描写される
       値 = 3 -> より荒く描写される
     という感じです。
     今回は銃弾の軌跡ということで弾は湾曲せずに直進して進むので、この値は大きくて良さそうですね。

  • Width
      名前の通り、線の幅の大きさを調整できます。

  • Graph
      先ほどの"Width"では全体の線の太さを調整しましたが、こちらでは線が発生してから消えるまでの太さをより細かく調整することができます。
      操作の仕方はParticleSystemのSizeOverLifetimeのカーブなどと同じです。

f:id:aizu-vr:20190108180915p:plain

 他にも自分で調整できる機能はたくさん存在しますが、ここでは使用しないので気になる方は記事の最後に参考ページを載せてるのでそちらを参照してください。


 それではコンポーネントの簡単な紹介をしたので、早速作っていきましょう!

製作過程

親子関係はこのようにしました

     [銃弾のオブジェクト]
          ∟ [銃弾の軌跡]
              ∟ [軌跡の飾り]

 ここでオブジェクトと軌跡を別々に分けた理由として、オブジェクトを何かに差し替えたいと思った時に便利だからです。軌跡以下の子を新しいオブジェクトの子に差し替えれば新たに値を設定し直すことがなくて済みますね!

 それでは、パーツごとに説明していきますね。

銃弾のオブジェクト

 今回はモデルを仮で"Sphere"を使ってやります。Scaleは(0.1,0.1,0.1)にします。
コンポーネントにオブジェクトが前進するスクリプトを用意してあげます。銃弾なのでこれは必要ですね(´∀`)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMove : MonoBehaviour {

    public float speed;
    public float destroyTime;

    void Start () {
        Destroy(gameObject, destroyTime);
    }
    
    void Update () {
        transform.position += transform.forward * Time.deltaTime * speed;
    }
}

 こいつを追加させてあげるとUnityのInspector上で、銃弾の速さ、銃弾が消滅するまでの時間を調整することができます。他に必要があれば当たり判定の処理などをここに追加してみてもいいかもしれませんね。

銃弾の軌跡

 ここでは先ほど説明したTrail Rendererを使用していきます。空オブジェクトを用意してこれにAddしましょう。子に置いた状態でのオブジェクトのScaleは(10,10,10)。Trail Rendererのそれぞれのパラメーターの値を次のようにします。
     ・Materials - Size : 1
     ・Time : 0.5
     ・Min Vertex Distance : 3
     ・Width : 0.5
     ・Graph
f:id:aizu-vr:20190108213140p:plain

 次に軌跡のマテリアルを用意します。今回使用するテクスチャはこんな感じのものです。
f:id:aizu-vr:20190108213109p:plain
 これをTrail Rendererで使用するためには、マテリアルのシェーダーを

     Legacy Shaders -> Particles -> Alpha Blended

 に設定してあげます。Alpha Blendedとは半透明を示していて、他の半透明マテリアルが重なった場合、SortingFudgeの値が小さい方が画面の手前側に描画されます。他にはAdditiveというものがあり、これは加算を示しています。2つの加算マテリアルが重なった場合、SortingFudgeの値に関係なく色が加算されます。赤+青=紫みたいなイメージです。

 マテリアルを用意できたら、Materials - Element 0 に割り当ててあげましょう。

軌跡の飾り

 ここでは軌跡にちょっとした小さな光の玉を漂わせるパーティクルを追加します。軌跡だけだとちょっと寂しいので・・・w

 各パラメータはこんな感じ
  f:id:aizu-vr:20190108213151p:plain

これで一通り完成しました!
実際に銃弾モデルに追加したコードのSpeedパラメータを100、Destroy Timeを2にして動かしてみます。
f:id:aizu-vr:20190108213126p:plain
銃弾の軌跡っぽいのが出来上がってますね、バンザイー!!(*゚▽゚)ノ

+αで・・・

 これだけじゃちょっと物足りなかったので銃弾の軌跡に少し要素を付け加えてみます。

 まず、先ほど作った軌跡銃弾のオブジェクトをもう一つ用意します。そしたら次のような親子関係に。
     [銃弾のオブジェクト]
          ∟ [銃弾の軌跡]
          |    ∟ [軌跡の飾り]
          |
          ∟[銃弾のオブジェクト]
               ∟ [銃弾の軌跡]
                   ∟ [軌跡の飾り]

 スクリプトは以下のように変更します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMove : MonoBehaviour {

    public float speed;
    public float destroyTime;

    public float rotSpeed; //add
    float rotZ = 0; //add

    void Start () {
        Destroy(gameObject, destroyTime);
    }
    
    void Update () {
        transform.position += transform.forward * Time.deltaTime * speed;
        rotZ += rotSpeed; //add
        transform.rotation = Quaternion.Euler(0, 0, rotZ); //add
    }
}

 新たに追加した変数rotSpeed、rotZはそれぞれ回転速度、オブジェクトのRotationのZ座標を表してます。
 コードを書き直したら、子の銃弾オブジェクトのこのコードを消してください。それと、子の銃弾オブジェクトのPositionのX座標を1にします。そしてMesh Rendererを非アクティブにしてあげましょう。
 最後にrotSpeedの値や、子の銃弾の軌跡の太さを調節してあげてると・・・
f:id:aizu-vr:20190108231633p:plain
 螺旋状に軌跡を描くこともできたりします!


引用元

gametukurikata.com

初歩レイトレーシングレンダラー

学部2年の白嶋です。今回でブログAizuVRのブログを書くのが2回目になります。

目次

概要

今回は、Unityとは全く関係がない内容になりますが、最近流行りのレイトレーシングの初歩を学ぼう! という事でC++レイトレーシング レンダラーを作って行きたいと思います。

レイトレーシングとは?

最近、RTXがリアルタイムレイトレーシングが出来ると話題になっていますよね。 大体のゲームは、ラスタライズという方法で描画していましたが、RTXではラスタライズと一部レイトレーシングで描画しています。 一部でしかレイトレーシングが使われないのは、本来1フレームを描画するのは数時間、何日もかかる処理なので、それをリアルタイムで描画するのはまだ今の性能では無理な話です。なので、ガラスや水面などレイトレーシングが適してる所だけレイトレーシングで描画しているので、なので一部レイトレーシングなのです。

レイトレーシング ON OFF比較

https://www.4gamer.net/games/419/G041969/20181219082/TN/005.jpghttps://www.4gamer.net/games/419/G041969/20181219082/TN/009.jpghttps://www.4gamer.net/games/419/G041969/20181219082/

RTXデモ動画


Battlefield V: Official GeForce RTX Trailer Battlefield V, NVIDIA RTX Ray Tracing, And GeForce RTX Combine To Deliver Next-Gen Graphics in Games – See It In Action In Our Exclusive Trailer

レイトレーシングの描画流れ

https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Ray_trace_diagram.svg/640px-Ray_trace_diagram.svg.png?download Ray tracing (graphics) - Wikipedia

現実世界では、光源から光が放射して物体(以下、「オブジェクト」と言う。)などに反射、屈折などをして、人間の目に光が入り光の周波数によって色を認識しています。 レイトレーシングはその逆の流れで計算をしています。理由は、光源の光のごく一部しか目に入らないので、光源の光を全部計算すると無駄が多くなってしまうからです。

レイトレーシング実装

今回のブログでは、レイトレーシング法で簡単な反射のみ実装していきます。

1.レイの生成

f:id:aizu-vr:20190106103642p:plain

std::vector<Ray> rays;
for (int i = 0; i < getScreen.w * getScreen.h; i++) {
    double x = getScreen.GetWidth(i) - getScreen.w * 0.5;
    double y = getScreen.GetHigh(i) - getScreen.h * 0.5;

    rays.push_back(Ray(getScreen.cameraRay.o, getScreen.cameraRay.d + V(x * getScreen.pov, y * getScreen.pov, 0))); 
}

raysにこれから計算するレイをプッシュバックしてます。 x,yは for文の i に対してスクリーン上のピクセルかを計算しています。x,yでカメラの方向をズラし、それをレイとしてプッシュバックしています。 例) iが getScreen.w * 0.5 + getScreen.h * 0.5、つまりシーンの中心の時、x、yは0になります。その時はカメラの方向をそのままレイとしてプッシュバックします。

応用として、視野角も後々考えないといけませんね。

2.レイの反射

f:id:aizu-vr:20190106114404p:plain f:id:aizu-vr:20190106114219p:plain 光源とオブジェクト間での反射を考えます。

std::optional<HitInfo> RayHit(Screen &getScreen, const Ray &getRay,  double rayPower) {
    //再帰中止
    if (rayPower < 0.01) {
        return std::nullopt;
    }

    for (int s = 0; s < getScreen.spheres.size(); s++) {
        double dotA = Dot(getRay.d, getRay.d);
        double dotB = -2 * Dot(getRay.d  ,getScreen.spheres[s].p - getRay.o);
        double dotC = Dot(getScreen.spheres[s].p - getRay.o, getScreen.spheres[s].p - getRay.o) - std::pow(getScreen.spheres[s].r,2);
        double D_4 = (std::pow(dotB, 2) - 4 * dotA*dotC) / 4;
        double t1 = (-dotB / 2 + std::pow(D_4, 0.5)) / dotA;
        double t2 = (-dotB / 2 - std::pow(D_4, 0.5)) / dotA;
        if (t1 >= DBL_EPSILON) {
            V Q1 = V(getRay.o + t1 * getRay.d);
            HitInfo hit;
            hit.hitObject = getScreen.spheres[s];
            hit.position = Q1;
            hit.hitObjectNormal = Normalize(Q1 - getScreen.spheres[s].p);   
            hit.dot = Dot(hit.position, hit.hitObject.p) / Magnitude(hit.position) / Magnitude(hit.hitObject.p);
            hit.ray = Ray(hit.position, Normalize(getRay.d) + hit.hitObjectNormal);
            //光源の場合、直ちに光を反映
            if (hit.hitObject.emission.Power() > 0) {
                hit.color = hit.dot* hit.hitObject.emission;
                return hit;
            }
            auto hitRecursive = RayHit(getScreen , Ray(hit.position, Normalize(getRay.d) + hit.hitObjectNormal),rayPower*hit.dot);
            if (hitRecursive) {
                if (hitRecursive.value().hitObject.emission.Power() > 0) {
                    hit.color = hitRecursive.value().dot * hitRecursive.value().hitObject.emission;
                }
                else {
                    hit.color = hitRecursive.value().color * hit.dot;
                }
            }
            else {
                //色の影響がごくわずかである
                //あるいは、rayが接触しなかった
                hit.color = Color(0,0,0);
            }
            return hit;
        }
    }
    //結果衝突を検出出来なかった
    return std::nullopt;
}

反射を繰り返し、ピクセルの色を決定する時の色の影響率が低いレイは再帰の途中で停止してます。

3.画像ファイルの書き出し

今回はPPMファイルを出力しています。PPMファイルの中身はテキストで書かれています。全てのピクセルがテキストで表現できるので、余計なライブラリを使わずに簡単に書き出しが出来ます。

計算結果

f:id:aizu-vr:20190106115606j:plain 上手くいきました👍

りぽじとりー

github.com

シェイプキーでキャラの表情を作るよ(blender)

こんにちは。学部一年の山田大生です。

僕はVRChatに自作のモデルで入ることが夢なのですが、なかなか思った通り行かずまだそこには到達できていません。 特に表情ですね。twitterなどでVRChatの切り抜きを結構見かけるんですけど、そこにいるほとんどの人(アバター)がにっこり笑っていたり、驚いた顔をしていたり…kawaii表情なんですよね。 調べてみるとキャラの表情はシェイプキーで作っているようです。シェイプキーはボーンに頼らずに頂点移動ができる機能みたいです。 僕が使っているblenderでもシェイプキーは使えるみたいなのでとりあえず簡単な表情をつくってみることにしました。

これが今僕が作っているモデルです。 このモデルにシェイプキーを付けていきます。 f:id:aizu-vr:20190101205604p:plain モデルを選択してシェイプキーの設定画面を見つけます。(逆三角形のマークのタブの中)。 そこにはまだシェイプキーはありませんが、+マークをクリックすることで新しく追加することができます。 最初に作られるシェイプキーはBasisというシェイプキーです。これはその名の通り基準となるシェイプキーです。 このシェイプキーを作ったときの頂点の位置が次以降作られるシェイプキーの基準となります。基準が設定されたので、シェイプキーを追加します。 2回目以降作られるのはKey~というシェイプキーです。これらが実際に作っていくシェイプキーですね。 僕は最初に目を閉じる表情を作りました。 Key1(後で名前をmabatakiにしました)を選択して編集モードにして、頂点を動かして目を閉じている感じにします。 この時重要なのは頂点を削除したり結合したりしないこと(追加するのもダメみたい…?)。そうすると次のシェイプキーを作るときにモデルがぐしゃぐしゃになってしまいます。 ↓作成中の様子 f:id:aizu-vr:20190101212508p:plain 作り終わってオブジェクトモードにすると、元の表情に戻っているように見えます。 ここでシェイプキーの機能を一部紹介しながら説明します。 2回目以降追加したシェイプキーの横には数字が書いてあります。最初は0.0になっています。 頂点の移動前が0.0、移動後が1.0となります。 その数値を動かすと頂点もその数値に応じて動きます。 f:id:aizu-vr:20190101215432j:plain ちなみに数値の横にある目のアイコンが開いてるときはシェイプキーが表示されます。目が閉じているとシェイプキーによる変化を見えなくすることができます。 これでキャラが目を閉じる表情が作成できました。

さらにもう少し作ります。今度は口の動きを作ります。 シェイプキーは2つ以上同時に適応できます。例えば目を閉じるシェイプキーと口を開けるシェイプキーを同時に表示することもできます。 しかし2つのシェイプキーが同じ頂点を動かすと、頂点がどっちにも引っ張られおかしくなるので注意が必要です。 口の作りも先ほどと同じく、新しく追加したシェイプキー上で頂点を移動させていきます。 僕は"あ""い""う""え""お"の口を作ってみました。 f:id:aizu-vr:20190101221618p:plain f:id:aizu-vr:20190101221705p:plain 口のシェイプキーを使えばリップシンク(自分の声に合わせてモデルの口が動く)の実装もできるみたいですがそれは後々…。 これからはもっとシェイプキーについて理解を深めて、Unityで動かしたりVRMファイルにくっ付けたりしてみたいです。 それでは…またこんど!

自宅で自分を3Dスキャンして踊ってみた。

こんにちは、学部一年の源氏です。  

 現実の物を3Dモデル化する場合は、フォトグラメトリ、深度センサー、レーザースキャンなどがあるそうですが、今回はフォトグラメトリを使用しました。東京では100台を超えるカメラを使い、精巧なモデルを一瞬で作ってくれるスタジオがあるそうです。田舎にいる僕は、なんとか自宅で自分のモデルを作れないかネットを検索していました。スマホでもできるものがあるそうですが、深度センサーの値段が高く、スマホのフォトグラメトリの場合はモデルのゆがみがひどかったので、パソコンでフォトグラメトリを使用することになりました。

大まかな手順↓

1.フォトグラメトリで自分の3Dモデルを作る

2.腕と脚をスキャン仕切れなかったため、サイボーグ化で解決

3.Unityで踊る

以下詳しく↓

1.フォトグラメトリのソフト「3DF Zephyr」を使用して、自分の3Dモデルを作成する 無料版でも、少ない写真枚数から比較的短時間で、良いモデルを作ってくれるみたいです。僕自身無料版に触れた感覚では、オリジナルと差がないほどのモデルを作ってくれました。しかし、いざ自分の3Dモデルを作ろうと、48+αの視点から写真を撮り解析にかけた結果、出力されたのは、現代オブジェクトと化した”人間だった何か”でした。枚数が少ないのかと思い、500枚まで写真を解析してくれる有料版の無料体験版を利用しました。結果、198枚の写真を撮り、利用できる写真(カメラ位置を割り出せた写真)は160枚でした。

f:id:aizu-vr:20181218002853p:plain 点群データ。 ぱっと見いい感じ。

メッシュ化してみると……

腕が!? f:id:aizu-vr:20181217235828p:plain 脚が!? f:id:aizu-vr:20181218003226p:plain

ない!!!

というわけで、サイボーグ化しました。 f:id:aizu-vr:20181218003638p:plain

ウェイトと脚と腕の比率、モデルのゆがみで色々とおかしいですが、踊っている動画です。


bandicam 2018 12 17 23 28 19 477

反省

腕と脚がなかったのは、撮影しているうちに腕と脚の位置がずれたせいだと考えられます。全ての写真の腕の位置を平均化すると結果ほぼ腕ないみたいな感じなのかな?ちゃんとしたデータがあれば正確なモデルを作ってくれます。ソフトのせいではなく、撮り方が悪かったのです。もしもリベンジするなら、ドローン(もしくは別のだれか)が撮った動画からの写真を使おうと思います。(お金があれば数百台のカメラとスタンドを買うという手があるけど、もう東京のスタジオに行っ方が良い)。

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!