zawazawa雑記

UnityのTerrainで生やした花を光らせる方法

問題

TerrainのDetailsでプレファブの花を登録して生やしたわけですが、花マテリアルに設定したEmissionが機能してくれない!!

この文章を見る感じ、ビルトインシェーダ をいじらないといけないっぽいのでやってみる。

answers.unity.com

最終的な見た目

f:id:zawazawahtn:20181222131758p:plain
花びらが青く光ってくれてる

実装方法

Unityアーカイブページからビルトインシェーダ をダウンロード 2018.2.11のビルトインシェーダ zipファイルを展開後、そのままasset に追加。これを書き換えればUnityの元々保持しているスクリプトを上書きできるらしい。

以下のWabingGrassシェーダ をいじると、TerrainにおいてDetailsに登録されている花のshaderを変更することができる。ここにEmissionマップをくっつけたい。

f:id:zawazawahtn:20181222125440p:plain
ヒエラルキーこんな感じになる

EmissionをこのWavingGrass.shaderにつける 具体的には、 o.Emission = _EmissionColor; のようにして_EmissionColorを宣言する。すると以下のような図になる。ただしこれは全体にかかっていて、花びらのみにかかってるものではない。

f:id:zawazawahtn:20181222131514p:plain
花全体が光ってしまっている。花びらのみ光らせたい。

解決方法 花びらのみを光らせたいので、_MainTexのうち青い部分のみを光らせるというコードを追加した。

こちらを参考にしました。 onoty3d.hatenablog.com

WavingGrass.shader

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "Hidden/TerrainEngine/Details/WavingDoublePass" {
Properties {
    _WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
    _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
    _WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
    _Cutoff ("Cutoff", float) = 0.5
    _EmissionTex ("Emission Texture", 2D) = "white" {}  //追加
    _EmissionColor("Emission Color", Color) = (0,1.04,1.28,0)   //追加
    _Near("Near", Range(0, 0.5)) = 0.1  //追加
}

SubShader {
    Tags {
        "Queue" = "Geometry+200"
        "IgnoreProjector"="True"
        "RenderType"="Grass"
        "DisableBatching"="True"
    }
    Cull Off
    LOD 200
    ColorMask RGB

CGPROGRAM
#pragma surface surf Lambert vertex:WavingGrassVert addshadow exclude_path:deferred
#include "TerrainEngine.cginc"

sampler2D _MainTex;
fixed _Cutoff;

//追記->
half4 _EmissionColor;
sampler2D _EmissionTex;
fixed _Near;

fixed GetHue(fixed3 rgb) {
    fixed hue = 0;
    fixed minValue = min(rgb.r, min(rgb.g, rgb.b));
    fixed maxValue = max(rgb.r, max(rgb.g, rgb.b));
    fixed delta = maxValue - minValue;
    if (delta != 0) {
        if (maxValue == rgb.r) {
            hue = (rgb.g - rgb.b) / delta;
        }
        else if (maxValue == rgb.g) {
            hue = 2.0 + (rgb.b - rgb.r) / delta;
        }
        else {
            hue = 4.0 + (rgb.r - rgb.g) / delta;
        }

        hue /= 6.0;

        if (hue < 0) {
            hue += 1.0;
        }
    }
    return hue;
}
//<-追記

struct Input {
    float2 uv_MainTex;
    fixed4 color : COLOR;
};

void surf (Input IN, inout SurfaceOutput o) {
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
    o.Albedo = c.rgb;
    o.Alpha = c.a;
    clip (o.Alpha - _Cutoff);
    o.Alpha *= IN.color.a;

    //追記->
    fixed4 col = tex2D(_MainTex, IN.uv_MainTex);
    fixed4 e = tex2D(_EmissionTex, IN.uv_MainTex);
    fixed distance = GetHue(col.rgb) - GetHue(_EmissionColor);
    if (distance > 0.5) {
        distance = 1.0 - distance;
    }
    else if (distance < -0.5) {
        distance = 1.0 + distance;
    }
    else {
        distance = abs(distance);
    }

    if (distance < _Near)
    {
        o.Emission = _EmissionColor * e;
    }
    //<-追記
}

ENDCG
}

    SubShader {
        Tags {
            "Queue" = "Geometry+200"
            "IgnoreProjector"="True"
            "RenderType"="Grass"
        }
        Cull Off
        LOD 200
        ColorMask RGB

        Pass {
            Tags { "LightMode" = "Vertex" }
            Material {
                Diffuse (1,1,1,1)
                Ambient (1,1,1,1)
            }
            Lighting On
            ColorMaterial AmbientAndDiffuse
            AlphaTest Greater [_Cutoff]
            SetTexture [_MainTex] { combine texture * primary DOUBLE, texture }
        }

        // Lightmapped
        Pass
        {
            Tags{ "LIGHTMODE" = "VertexLM" "RenderType" = "Opaque" }

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #include "UnityCG.cginc"
            #pragma multi_compile_fog
            #define USING_FOG (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))

            float4 _MainTex_ST;

            struct appdata
            {
                float3 pos : POSITION;
                float3 uv1 : TEXCOORD1;
                float3 uv0 : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
            #if USING_FOG
                fixed fog : TEXCOORD2;
            #endif
                float4 pos : SV_POSITION;

                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert(appdata IN)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(IN);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

                o.uv0 = IN.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
                o.uv1 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;

            #if USING_FOG
                float3 eyePos = UnityObjectToViewPos(IN.pos);
                float fogCoord = length(eyePos.xyz);
                UNITY_CALC_FOG_FACTOR_RAW(fogCoord);
                o.fog = saturate(unityFogFactor);
            #endif

                o.pos = UnityObjectToClipPos(IN.pos);
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag(v2f IN) : SV_Target
            {
                fixed4 col;
                fixed4 tex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv0.xy);
                half3 bakedColor = DecodeLightmap(tex);

                tex = tex2D(_MainTex, IN.uv1.xy);
                col.rgb = tex.rgb * bakedColor;
                col.a = 1.0f;

                #if USING_FOG
                col.rgb = lerp(unity_FogColor.rgb, col.rgb, IN.fog);
                #endif

            return col;

            }

        ENDCG
        }
    }

    Fallback Off
}

これでめでたく花部分の色を抽出してその色に光らせることができた!

できなかったこと

その1

C#スクリプトから当該shaderをいじろうとしてもうまくいかなかった。

Material material = new Material(Shader.Find("Hidden/TerrainEngine/Details/WavingDoublePass"));
material.SetTexture("_EmissionTex", emissionMap); 

このように話してる人もいる。 f:id:zawazawahtn:20181222131130p:plain

その2

これはダメだったというかやり方がわからなかったので、どなたか方法を知ってる人がいたら教えてください。

  • WavingGrass.shaderに直接EmissionMapにTextureを指定する
  • .cgincを作成し、EmissionMapとなる2Dtextureをreturnさせる

Unity ML-Agentsを一通り動かすまでのメモ

あくまで個人のメモです。基本的には以下の記事が詳しく書かれています。

qiita.com

Colaboratory – Google

メモ

SHELL切り替え

Anaconda上で学習をしようとすると、zshでは起動しなかったのでbashに変えました。原因は調べてないです。

//起動シェルを確認
$ echo $SHELL
//シェル一覧
$ cat /etc/shells
//起動シェルの変更
$ chsh -s /bin/bash

v0.4とv0.5でディレクトリ構成がガラッと変わる

Pythonディレクトリがなくなり代替としてml-agentsというものができる

build場所

ml-agent直下

学習実行

mlagents-learn config/trainer_config.yaml --env=3DBall --run-id=firstRun --train

※../config/trainer_config.yamlだとfile not foundになった

tensorboardで可視化

/Users/****/projects/Unity-ML-Agents/ml-agents/ml-agents で

tensorboard --logdir=summaries

を叩いてlocalhost:6006にアクセス

詰まったとこ

  • conda install tensorflowとconda install tensorboardをしないといけない
  • localhost6006にアクセスしても"No dashboards are active for the current data set."って言われる。よくわからなかったので未解決。

学習結果ファイルの取り込み

ターミナルかFinderで学習結果を以下フォルダにコピーします。

学習結果ファイル: ml-agents/models/firstRun-0/3DBall_firstRun-0.bytes 保存先: UnitySDK/Assets/ML-Agents/Examples/3DBall/TFModels/

Google Colabでの実行

ターミナルで以下を実行

pip install jupyter_http_over_ws
jupyter serverextension enable --py jupyter_http_over_ws
jupyter notebook \
  --NotebookApp.allow_origin='https://colab.research.google.com' \
  --port=8888 \
  --NotebookApp.port_retries=0

Google colabで以下を実行

cd /Users/****/projects/Unity-ML-Agents/ml-agents
!/anaconda3/envs/mlagents/bin/mlagents-learn /Users/****/projects/Unity-ML-Agents/ml-agents/config/trainer_config.yaml --env=/Users/****/projects/Unity-ML-Agents/ml-agents/ball3DMove --run-id=onColab --train

自分で問題を設定してみる

3DBallの問題に、前方のゴールを目指して移動しながらボールを保持する、というタスクも追加する。

  • 1試行目
Vector Action Continuous(3)
・0:z回転
・1:x回転
・2:z移動
Reward ステップ毎:+0.1(に変更)
ボール落下:-1.0(エピソード完)
ゴール到達:+1.0(エピソード完)
ステップ毎のアクション z方向への移動を追加
  • 結果

    • 最初の報酬設計だとボールの維持による報酬が大きすぎてゴールへ到達しない。報酬を以下のように変えてみる。
  • 2試行目

Reward ボール落下:-1.0(エピソード完)
ゴール到達:+1.0(エピソード完)
変更方針 ボールの維持による報酬が大きすぎたため、維持しているだけでは報酬を与えないことに
  • 結果

    • ゴールが遠すぎたのか、反対側へ行くものが多くなった。ゴールの距離を半分にしてみる。
  • 3試行目

ゴールまでに進まないといけない距離を半分にしてみる。

  • 結果

    • Goalまで運べるようになった!
  • おまけ 同じ条件でGoogle colab上でも動かしてみる

  • 結果
    • 同じ条件なのに反対側に進むという収束結果に。報酬の平均もマイナス値で、反対方向への探索がうまく行ってないみたい。goal方向に向かうことによる何かしらの小報酬が必要なのかな。やはり強化学習は報酬設計が大事という実感が得られた。

おしまい

ARKit2.0の状態保存と端末同期を使ってARPetを作ってみた

やったこと

ARKit2.0がぼちぼち出てきます出ました。それに伴いより多くの人が簡単に

  • Persistent AR Experience / 状態保存
  • Multiuser AR Experience / 端末同期

を実装し、多くの人に届ける事ができるようになります。これをいち早くキャッチアップし、実装しようと思いました。

どうやったか

ただ実装するだけではつまらないと感じたので、システム全体の流れがわかるようなアプリケーションにしました。また、今回はAR表現の進歩で実現が可能になりそうな「ARPet」を作ってみることにしました。

開発環境

  • macOSX
  • Unity-ARKit-Pluginのarkit2.0_beta branch
  • iOS12
  • Unity2017.4.2
  • Photon Unity Network
  • Xcode10

状態保存

UnityARWorldMapシーンをそのものを使えば基本的に大丈夫です。 このシーンでやってることは、「検出した平面や空間情報を端末に保存するやで。ロードする時は端末に保存されてるファイルを読み込んで保存した時と同じ風景を探すやで」って感じです。

またこの方法ではオブジェクトの保存ができません。参考に↓

f:id:zawazawahtn:20180831181226p:plain

ARWorldmapのSave&Loadにオブジェクトを結びつけたい場合は自分でそのオブジェクトのTransform情報の入ったjsonファイルを作成する必要があるみたいです。他にいい方法があれば教えてください。

端末同期

個人的に鬼門でした。実装を始めた当初は公式でも言及していたSharedSpheresを使用するつもりだったのですが、実装を始めて間も無くこの記事が出てしまいました。

blogs.unity3d.com

そうです、SharedSpheresは今後死んでしまうunetを使用していたのです。

そこで今回はPhoton Unity Networkを使用することにしました。

具体的には、

  • ARWorldMapを作成して受信端末に送信するためにARWorldMapをシリアライズする
byte[] locWorldBytes = localWorldMap.SerializeToByteArray(); 
  • PhotonではRPCでバイト列を送受信できるので(可能な型)受信端末に送信する
photonViewWorld.RPC("ShareWorldMap", PhotonTargets.OthersBuffered, locWorldBytes); 
  • 受信端末で以下のコードが動き、バイト列がデシリアライズされてARWorldMapが復元される
[PunRPC]
void ShareWorldMap(byte[] world_bytes){
    ARWorldMap worldMap = ARWorldMap.SerializeFromByteArray(world_bytes); 
・・・
  • その後受信端末側でAR体験をするためのconfig情報(検出平面や検出平面のexpandをするかどうかなど)を設定したsessionを開始する

おわりに

こちらのアプリはメルカリでサマーインターンをした時に作成したものです。そちらの記事もよかったら読んで下さい。

zawazawahtn.hatenablog.com

© UTJ/UCL

メルカリSummer Internship 2018に参加してみた

長いことブログの更新をしていませんでした。というのもこの1ヶ月間、とてもありがたいことに株式会社メルカリのサマーインターン (詳細) に参加していました。この記事ではその経験をつらつら書いていきたいと思います。

今後メルカリで働きたい、雰囲気を知りたい、インターンで何をやっていたか気になる、という人たちにとって有益なものとなれば幸いです。

こんな感じの内容を書きます。

成果物に関しては別の記事で書くことにします。

メルカリに入ってみて

レベルが高い

まずこの一言につきます。会社のValueの一つとしても掲げられているように、皆さん「Be Professional」の意識が高い。個人的に結構びっくりしたことがあって、それは入社オリエンの時に言われた一言。

「Bottomに合わせない。必要な情報は自分で取ってくる。」

これを言える、言ってのけてしまうあたり最初はちょっとビビりました。なんか久しぶりのビシビシした空気を感じました。 もちろんインターン生に対しても求められるレベルは高く、「成果出してね笑」とも言われました(もらえる日給を考えれば至極当たり前・これを言われて俄然やる気出た)。

情報が転がってる

次にこれに驚きました。本当に情報が転がってるんです。技術的な話ではありません(技術的に足りない部分はネットなり本なり読んでください、それぐらいのことはできますよね、ってことだと思う)。

ここでいう情報とは、企業の売り上げとか新規プロジェクト、採用フロー、個人の日報などです。もちろん、インサイダー情報になるものもあるので扱いに慎重にならなければいけないのですが、社員はおろかインターン生にも見せてしまうのか...といった感じ。その分やはり企業への帰属意識とかも高まるでしょうし、無駄な権限のアレコレをしなくて済んで開発やコミュニケーションの効率が上がります。 強い攻めの姿勢を感じました。

下は歓迎会の様子

サマーインターンの様子

自分は今年から募集開始のR4DのXRコースに参加していました。他のコースとは違い、VR/ARに関するテーマを自分で持ってきてoutputする形式だったので本流のアプリには直接的には関わることがありません。しかしR4Dとしては自分たちが研究している技術領域でメルカリに貢献することを目指しています。

インターンの課題としては、インターン生(4人)それぞれの自由な持ち込み型のものでした。テーマとしては、

  • ARkit2を使ったデジタルペットアプリ(自分)
  • 音声信号を振動に変える触覚デバイスを使ったハプティクス体験の開発
  • Hololensでの人体テクスチャのリアルタイム取得・生成を用いた擬似幽体離脱体験
  • Android端末とUnityのシリアル通信ライブラリの開発とVRアプリケーションの開発

って感じでした。綺麗にテーマがVR/MR/AR/ハプティクスと別れていたのはメンターの@ikkouの計らいか...?

業務

基本的に10時~19時(?だったと思います)ですがわりと前後してました。かなり自由。朝会と夕会以外のMTG的なものは週一の全体会ぐらいで、会議に時間を取られるということは全くありませんでした(メンターさんが忙しそうでしたが)。集中できる環境でした。

インターン同期

チームの同期とよく昼ごはんとか行ってたのですが、ちょくちょく社内イベントで他のチームの同期とも顔を合わせられました。おかげで同期にどんな人がいて、どんなに優秀か知れて刺激になりました。

最終日の発表

さて次に、初日に「成果出してね笑」と言われた成果物発表です。1人約7分の発表で1ヶ月の成果をおさめるのがなかなか難しかったですが、どの人の発表を聞いていても勉強になりました。(とは言っても自分の知識ではアプリ側のフロントやバックエンドなどの話は3割ぐらいしか理解できませんでしたが...)

個人的に面白かったのがAIチームの人たちの発表で、商品の画像から自動で商品タイトルを生成する時に、名詞だけでなく商品固有のキーフレーズを抽出してそれも考慮して生成する、というものがあり感動しました。

そこで感じたのが、やはり自分たち(R4DXRチーム)のやってることはまだまだメルカリのビジネスの上に乗っかってないなと思いました。自分の突き詰めたい技術・世界とメルカリのビジネス領域でうまく合致するポイントを見つけてそこを皆さんに聞いて知って欲しいと感じました。

f:id:zawazawahtn:20180915173518j:plain:w400
発表の様子

こちらも合わせて読んでみてください。

mercan.mercari.com

毎日が楽しい

なんでかって言うと、毎晩どこかしらでパーティやら社内部活やらで盛り上がってるところです。

一番印象に残ってるのがコレ

マグロの解体ショー&流しそうめん大会

...最初は意味が分からなかった。一応プロダクトチーム全体の打ち上げ的な名目だったけどそれ以外の人たちもわんさかいて盛大なパーティになっていました。こーゆーイベントがたくさんあるのも、社内に外国からの社員の方がたくさんいて(それでも全然まだまだ日本人がほとんどですが)、異文化交流の一つの姿なのかなって思いました。

パーティが苦手な人もいるかとは思いますが、個人的にはこれはとてもありがたかったです。というのも、うまく進捗が産めなかった日も、一人で帰って落ち込んだままベッドに入るより、帰りがけに楽しいイベントがあれば明日も頑張ろうってなります。精神的に健全さが保たれました。いのちだいじに。

CEDEC2018参加してみた

f:id:zawazawahtn:20180827223138j:plain:w150

目次

CEDEC2018←こちらが公式サイトです。

参加に至った文脈としては、現在(2018/8)1ヶ月間サマーインターンに参加しているメ社のR4DXRチームで行く機会があったって感じです。

ゲーム・XRを中心とした現場の開発や研究のsessionを主に聞いてきましたが、結論として「とてもいい経験でした」。参加の機会をくださったメ社とR4DXRチームの皆さんには感謝です。

自分の聞いたsesisonはこちらです。インタラクションは全部やりました(多分)

  • [SIGGRAPH Asia×CEDECコラボセッション] SIGGRAPH Asia 2018 の楽しみ方
  • ハシラスが考えるこれからのVR
  • 「ジャンプチ ヒーローズ」「FINAL FANTASY XV」でのPhoton採用事例紹介
  • VRにおけるディープラーニング利用: 手の位置のみの簡易なモーションキャプチャのリアリティを向上する研究
  • 8000種類のカードを見分ける、ディープラーニングを使用した画像認識
  • Google マップで現実世界のゲームを作ろう
  • ミックスドリアリティ・アトラクション『PAC IN TOWN』におけるリアルとデジタルの融合を象徴する新たな遊び”collaborative play”の紹介とVRDC@GDC 2018に登壇して思ったこと
  • VR/AR/MRの融合:高実在感コンテンツの未来
  • Saya -Virtual Human Projects-
  • IT の未来を語る:PlayStation® x IT 教育がつくる次世代エンタテインメント
  • 空撮フォトグラメトリー技術とレーザースキャン技術の融合による広大な現実空間の3Dデータ化方法

セッションピックアップ

ハシラスが考えるこれからのVR

内容はこちらの記事の内容が包括的だと感じました。 jp.ign.com

ハシラスはゲームセンターなどに据え置ける大型のアトラクションを中心としたアーケードゲームを中心に開発を行なっているが、その文脈での未来を発表してくださった。 そこでは下の記事にみられる「オルタランド」を提唱しており、そこでは「別の自分になって、別の世界に行って、仲間と過ごすこと」ができるという。

www.moguravr.com

確かにこのようなアーケードゲームにおいて人件費は赤字直結の課題であるのでこれがうまく解決できればアーケードゲーム内のVRコーナーはもっと大きなものになると感じた。

ただ一方で、「別の自分になって、別の世界に行って、最高の一人の空間を楽しむ」という未来の可能性もあると感じてきていて、本来根暗の自分にはこっちの方がありがたかったりする。

VR/AR/MRの融合:高実在感コンテンツの未来

こちらはCygames Reserachの発表でした。

最高のXR体験をユーザーに提供するためには、

  • リアルだけ頑張ってもダメ(リアル脱出ゲーム的な)
  • バーチャルだけ頑張ってもダメ(HMD搭載型VRアトラクション的な)
  • 両方をシームレスに繋ぐ必要がある(これはとても共感できる)

日常の中の非日常などではなく、永遠に続く非日常こそユーザーが真に受け取りたいものだという仮定。 そのような強烈な体験をユーザーが体験するためには

  • 圧倒的な没入感
  • 圧倒的な実在感
  • 没入感と実在感の両立させるための取り組み(Hololensを使ったMRコンテンツ)

(ここで「実在感」とは例えばCGコンテンツが現実のコンテキスト・コンテンツと齟齬なく感じられること、と仰っていました。目の前にあたかもキャラがいる!みたいな)

取り組みとして「VR四騎士」を挙げての説明でした。(いち騎空士としてこのイベントは行っておきたかったなー。こちらの方の体験記がとてもリアルでよく伝わりました)

privatter.net

個人的な意見として、

  • この事例で行なったことは、リダイレクションの研究と逆行するもの
  • リダイレクションの研究は、いかに現実世界の形をVR空間内でごまかすかに主眼を置いたもの
  • ではVR空間でのリダイレクションを行なっているコンテンツは「実在感」を失ってしまうのか?そうは思わない。
  • コンテンツやユーザー体験で重視するポイントを洗い出し、「実在感」を出す部分と「現実世界を歪める」部分とを使い分けすれば良い
Saya -Virtual Human Projects-

www.youtube.com

telyuka←こちらが製作者の方たちのHPです。

正直自分はSXSWも行ってなくメディアを通してしか知らなかったので、直接(?)Sayaさんにお会いしたのは初めてでした。

とにかくこの一言に尽きる

「すっごく可愛いです!!!」

現在は「揺らぎ」と「不確実性」を内包する彼女にできることを模索中だそうで、今後の活動もチェックしたいです。

モーションの動きにもひと手間ふた手間かかっていて、一つのモーションをループさせるのに最初と最後のフレームでのつじつま合わせを極めていらっしゃいました。(よくあるキャラがピョンッて飛んじゃうやつ) まずボーンのつじつま合わせをし、それでも髪の毛や服のシワなどのシミュレートの結果に微妙なズレが生じてしまうのでそれもつじつま合わせをし、って感じでした。根気のいる作業です。

個人的な意見

  • あまりにもリアルすぎるところがこのプロジェクトの鋭いところ
  • ここまで来てようやく一般人にも伝わる凄さ、というのが辛い現実だと思っている
  • だからこそ一般に広がるチャンスを持っている
  • 不気味の谷超えてるな。。。
    • Q: 越えるためのテクニックは?
    • A:
    • →そんなに意識していない
    • →この年代の美しさ、可愛さは一番大事にしないといけない(思いが伝わる一言)
    • →ただひたすらに作り込みをする

インタラクション展示

導電繊維を用いた軽量かつ多彩な手形状計測用データグローブ

上司のツイートを引用

こちらが公式のページのようです。これは現状ハプティクデバイスではなく、指の曲げや指と指の接触判定を行え、また予めチップ的なものを埋め込まれているものを把持すれば自分が何を掴んでいるか把握することができる、といったものです。

各指に周波数の違う電流を流しているということでしたが、結構アバウトな作りでちゃんと周波数帯が別れて取得できるのはすごいな(素人並感)と思いました。

簡易脳波計を用いた「脳波VRゲーム」、「脳波MRゲーム」、「脳波VRライブ」

またしても上司のツイートの引用

おでこ二箇所と耳の後ろ一箇所(アース)の簡易的なものでしたが、初体験だったのでいい経験になりました。

説明の際に、「集中する」と反応するみたいなことを言われたのですが、「集中とはww」ってなりました笑。まあでも別のこと考えたり色々脳裏で想像してたりしたら反応したのでよかったです笑。

最後に

自分は敢えて一枚も写真を取らなかったのですが、すぐにこれはよくなかったなと思いました(見る方だけに集中しようとしていた)。なのでこれからはなるべく写真撮ってSNS発信しようと思います。

一緒に参加してきたインターン生の書いたレポートもありますのでこちらも参考に[FYI]

xsmiledur8x7.hatenablog.com

フォトグラメトリーやってみました

みなさん、フォトグラメトリーって知ってますか。 恥ずかしながら自分はついこの間知りました。とても恥ずかしかったので、払拭するために実際にやってみることにしました。

フォトグラメトリーとは

フォトグラメトリとは、3次元の物体を複数の観測点から撮影して得た2次元画像から、視差情報を解析して寸法・形状を求める写真測量のこと。 航空写真から地図の等高線を作成するために発達した手法で、最近ではデジタルカメラを用いた3次元測定機(3D CMM)に応用されている。(weblio辞書より)

らしいっす。はい、見せた方が早いっすね。こちらがフォトグラメトリーという技術を使って駅を3次元化したものらしいです。(お借りします)

使ったソフト・環境

  • AutodeskのRECAPとRECAP Photo
  • MeshLab
  • WindowsPC

を使って作成しました。また、こちらの記事を参考に進めました。ところどころ仕様?が変わってることころがあり、その差分を含めて説明したいと思います。

shiropen.com

製作フロー

  1. RECAPをダウンロード(自分はStudentの権限を使ってPro版を手に入れることができました)。また、テストデータセットとして97枚の井戸の写真がここに入ってます。

  2. このnew projectからphoto to 3Dを選択 f:id:zawazawahtn:20180818182004p:plain

  3. Create 3DObjectを選択 f:id:zawazawahtn:20180818182008p:plain

  4. 作成したオブジェクトの写真群を選択し、project titleを設定してcreate f:id:zawazawahtn:20180818182016p:plain

  5. するとMyCloudDriveに作ったprojectが作成されてダウンロードができるようになります f:id:zawazawahtn:20180818182024p:plain

  6. またweb上では3Dviewができるようになっています f:id:zawazawahtn:20180818182020p:plain

  7. .obj形式でダウンロードすることもでき、MeshLabなど3D編集ソフトへのimportなども可能です

研究室のデスク周りを3次元化してみた

とりあえず身の回りのものを3次元化してみようと思ったので、研究室の自デスク周りを撮ります。

  1. 動画をとってそこから画像を切り出します
    • やり方は色々あると思うのですが、自分は最終的にffmpegを使いました。フリーソフト色々試してみたけどどれもクソ。ffmpeg使いやすい。
  2. だいたい2分の動画をとって700フレームに切り出しました
  3. ちょっとここで不満点が。どうやらrecap photoは100枚の画像までしか扱えないようです。せっかく700枚も用意したのに...
  4. 仕方がないので100枚単位で3次元化させてみました。次やるときはこれに気をつけよう。。。

とここまでやってきたのですが、結果はどれもエラーが吐かれてしまいました。

なんでだろう。後から動画から手でスクショ撮ってたやつと混ぜて作ったら手動でスクショしたやつのみで3次元化されたから、なにやらffmpegが悪さしてる...? これは15枚入れて9枚が使用された結果です。

もうちょっと精度あげたい

せっかくなので、いい感じになるように動画ではなく手動でたくさんの写真を撮ります。どこまで精度が上がるのか知りたい。

  1. 手動で根気よく100枚写真を撮ります
  2. あとは同じフローで3次元化してやります
  3. 結構時間かかります(30分ぐらいかな)
  4. できた

前よりはたくさんの正しいメッシュが生成されてる感じ!だいたい100枚中50枚くらいがつかわれた感じだ。ちゃんと認識してくれる撮り方とかアングルが分かったので次やるときはもうちょいうまくできるかな。

写真から3次元空間を構築する技術は他にも方法が色々あって、今回はそのうちの1種類を試してみました。

おしまい

はじめてのさくひんてんじ

某大学の制作展という授業で作品展示をする機会があったので、そこでの色々な話をつらつら書きます。

www.iiiexhibition.com

そもそも

「制作展」とは、某大学の一年かけて行う授業で、メディアアート作品を中心に、何かしらを表現したい人たちが集まって互いに意見を出し合ってグループや個人で形にする、という授業です。

今回は本番である11月の展示に向けたpreのものとして7月に行われた展示について書いていきます。

ちなみにこの制作展は毎年名前が変わっており、今回は「Dest-logy」というタイトルです。

あとちなみにかつて落合陽一さんも参加していたようです。

つくったさくひん

今回自分らが作った作品がこちらです。本来は色々派手に音が鳴ります。

f:id:zawazawahtn:20180712002450j:plain

youtu.be

youtu.be

かるーく説明すると、 テクノロジーの力によって様々な力吸収した人間は、繁栄した明るい世界を実現するのか、それとも適合できずに崩壊してしまうのか。どっちに転ぶのだろうか。というストーリーを表現しています。

一応Gitに上げていますが、UnityでのGitを用いたチーム開発はあまりオススメしません笑

えられたこと・わかったこと

  1. Unity公式のpost processing behaviour はできる子ということ。一気に見栄えがよくなります。

    f:id:zawazawahtn:20180706195529p:plain
    Before

    f:id:zawazawahtn:20180706195552p:plain
    After

  2. プロトタイプはなる早で作るべし。

  3. 作品をどこまで説明してどこから体験者に想像させるかの設計が難しい。アート作品なのかゲーム作品なのかによって変わりそう。

  4. アート作品に振るかゲーム作品に振るかにした方が良い。(個人的に、ゲーム作品として土台を作成してそれにアート性を加える方が得意だと感じた)

  5. 作品作ると、「面白い」「ありがとう」と言われる回数がめちゃくちゃ多いからこっちも楽しい。

  6. 宣伝大事

    1. TwitterとかのSNS
    2. 口コミ
    3. 名刺や作品のビジュアルをかっこよく写したカード的なもの(持って帰れる用)
  7. デバッグキー大事

  8. 本番用にBuild大事

  9. 作品展示にアクシデントはつきもの。自分らの作品は全日程を通して非常に安定した挙動をしてくれて特にメンテナンスなどは必要なかったが、ハードウェアに凝りだすと闇を見ることになる。(ハード使った方が作品の規模も体験の質も随分変わるのでそこはトレードオフだと思う)

  10. 展示が終わった後の打ち上げが超が5個つくくらい楽しい。終わった後にあーだこーだ言い合ったり、ぶっちゃけ話とかしたり、一緒に苦労して展示を作り上げた人たちと笑い会えるのは気持ちいい。

これらのことを活かして今後のモノづくりに活かそうと思います!

11がつのもみにきてね

今回の展示に見に来てくださった方々、ありがとうございました。途中でトラブルもあり()、4日目の終わりの方はバタバタしてしまいましたが、頑張って11月も展示できるようにしたいので、もし11月の展示が開催されれば是非またいらしてください!