イベント立ち上げ&LT登壇してきました!

こんにちは。

株式会社Synamonでエンジニアリングマネージャーをしてます、渡辺匡城(@mochi_neko_7)です。

またしばらく記事投稿が空いてしましましたが、気を取り直してまた定期的に記事を書いていきたいと思います!

先日Synamonと、同じスタートアップのビビッドガーデンさん、カミナシさんと共同でイベントグループの立ち上げをしました。

今回はそのイベントグループ Startup Issue Gym の簡単な紹介と、第一回イベントで私が登壇したLTの内容についてお話します。

f:id:mochinekos:20210524202803p:plain

Startup Issue Gym

Startup Issue Gymは、ビビッドガーデン、カミナシ、そしてSynamonのスタートアップ3社で立ち上げをしたイベントグループです。

このグループでは急成長しているスタートアップが集まって Issue(課題) を共有し、一緒に解決方法を考える場をつくっていきます。 苦労した Issue を共有して学びを深めるもよし、ちょっと先のフェーズのスタートアップの Issue を参考にするもよし、スタートアップでは働いていないけどどんな Issue があるのかリアルな話を聞きに来るもよしです。

スタートアップがどんなやり方で開発をしているのか知りたい方や今スタートアップで Issue を抱えて困っている方、Issue は乗り越えたので発信することで自分たちの学びを深めたいという方にも集まっていただけるといいなと思っております。 ちょっと覗いてみるとスタートアップの現場のリアルな声が聞けるはずです。

startup-issue-gym.connpass.com

イベントは単発ではなく今後も定期開催する予定なので、気になる方はぜひ「メンバーになる」を押してください!

記念すべき初回イベントのテーマは「開発プロセスの Issue」ということで、立ち上げた3社が自己紹介も兼ねてLTとQ&Aを行いました。 おかげさまで予定していた定員も埋まり、増枠させていただきました。

startup-issue-gym.connpass.com

Youtube Live のアーカイブもあるのでよければご覧ください。

www.youtube.com

実は当初はただ Issue を共有するだけではなく、参加者の方と一緒にその Issue にどう立ち向かうかディスカッションをするイベントにしようとしていたのですが、ディスカッションとなるとなかなか参加のハードルも高いため初回はQ&Aの形式になりました。 ここは次回以降のイベントで挑戦してみたいですね。

ここからは私が実際にLTでお話した内容の要約になります。

開発プロセスの Issue

初回イベント「開発プロセスの Issue」のSynamonのLTとしては私がお話をさせていただきました。

www.slideshare.net

大きなテーマとしては2つの Issue を紹介しました。

  • ここ一年で一番大きかった Issue
    • スクラム導入
  • 現在の開発プロセスの Issue
    • プロダクト開発と案件開発の両立

これらの Issue に関して簡単に説明します。

ここ一年で一番大きかった Issue ~ スクラム導入 ~

Synamonでは2020年10月頃からスクラムを導入しています。

スクラム導入の動機・目的としては主に以下のようなものでした。

f:id:mochinekos:20210524200958j:plain
スクラム導入の動機

プロダクトの開発初期の頃は比較的少人数で、新しい機能などをどんどん開発する必要があるため個々の開発力が光ります。 しかしプロダクトが大きくなるにつれ、ソースコードは複雑になり組織としても大きくなるためチームとして機能する必要が出てきました。 そうなってくるとこれまでの開発プロセスでは難しい場面も出てきます。

また、VRという技術自体の市場がそもそもなかったこともあり、顧客目線が持ちづらいという課題も長くありました。 これはビジネス的にも大きな Issue の一つであり、それに対してはビジネスメンバーだけでなく開発メンバーも向き合うべきと考えています。

スクラム導入の経緯に関しては別の記事でしっかりお話したいと思います。

こういった経緯も踏まえつつ、導入して約半年後の2021年4月頃での実感としては主に以下のようなものが挙げられます。

f:id:mochinekos:20210524201130j:plain
スクラム導入の効果

スクラムとしてはおそらくまだまだ向上の余地はありますし、現在でも課題はたくさんあります。 それでも導入前よりは明らかに良くなったというメンバーの声ももらっています。 開発におけるプロセスのあり方、顧客にとっての価値とは何か、スクラムをもっとうまくやるためにはどうすればいいのかなど、開発メンバーが自発的に考えるシーンを多く見るようになってきました。

現在の開発プロセスの Issue ~ プロダクト開発と案件開発の両立 ~

現在の Issue ももちろんいくつもあるのですが、ここではプロダクト開発と案件開発の両立を中心にお話しました。

弊社プロダクトの「NEUTRANS」は、ビジネスでのコラボレーションに必要な基本的な機能を備えたプロダクトの側面(ベース)と、 個々の企業様の実現したい体験に合わせたカスタマイズをする案件の側面(ユースケース)を持っています。

f:id:mochinekos:20210524201227j:plain
NEUTRANSの構成

これらは独立はしておらず、ベースの拡張によってユースケースの表現が広がり、ユースケースの要望からベースが進化する関係にあります。 このサイクルが循環することによって、各ユースケースのナレッジが蓄積し、ユースケースを横断した機能や新しいユースケースの創出なども行われます。

こういった狙いもありますが、一方で Issue も様々あります。

f:id:mochinekos:20210524201327j:plain
NEUTRANSのIssue

そもそも性質の異なるプロダクトと案件が混ざるため、開発要件がかなりカオスになってしまっています。 かといって簡単に分けてしまうのも、現在の規模の組織のマネジメントとしてはあまり取りたくない手段です。

また、スクラム導入以前からの組織的な課題も残っています。

こういった状況の中でも、常によりよい形を模索するため小さく実験を繰り返し、やってみる→ふりかえるを繰り返して組織として成長している最中になります。

f:id:mochinekos:20210524201540j:plain
スタートアップの面白さ

こういったところに面白味を感じていただけるのであれば、成長期のスタートアップはあなたの成長の場としては良いのではないでしょうか。

おわりに

今回のイベントでは運営者としても登壇者としても関わらせてもらいました。

自分たちの Issue を言語化することで学びも深まりますし、他のスタートアップの Issue の話も共感できる話ばかりでした。

こういった場を通して、スタートアップ同士の交流が活発になったり、スタートアップに興味を持ってもらえる人が少しでも増えたらなと思います。

積極採用中です

Synamonではエンジニア各ポジション積極採用中です。

実は私は最近はエンジニア採用に注力していまして、スカウトからカジュアル面談などもやっております。

ちょっと話を聞いてみたいという方も歓迎していますので、ぜひお気軽にお声かけください!

www.wantedly.com

open.talentio.com

開発チームの自発的な課題解決のためにオープンスペースをやってみた

こんにちは。

株式会社 Synamon でエンジニアをしております、渡辺匡城(@mochi_neko_7)と申します。

今回は、社内の開発チームで自発的な課題の解決や改善ができないかという試みとしてオープンスペースをやってみた話を紹介します。

振り返りも兼ねて、実施の経緯からお話ししていきます。

オープンスペースとは

オープンスペース、あるいは OST(Open Space Technology)とは、参加者が自発的に対話するためのワークショップの1つです。

www.ogis-ri.co.jp

特徴としては以下が挙げられます。

  • 参加者がテーマを出す
  • 参加者はセッションを自由に移動してよい
  • 最後にまとめとその共有をする

アジャイル開発界隈では割とメジャーで、Scrum Masters Night! や Engineering Manager Meetup などのイベントでも行われています。

smn.connpass.com

engineering-manager-meetup.connpass.com

背景

少し前から開発チームにおいて、週一で自由に相談や課題解決をする場を作ってみていました。

しかし開発チーム全体では16人程度、有志で集まっても10人以上集まり、やや人数が多いです。

そうなるとどうしても話を聞いている時間が多く、せっかく集まってもらったのに有意義に時間を使ってもらえていない、という課題感がありました。

やり方やそもそもの定例の意義を考え直していたのですが、その時たまたま読んでいた LeSS(Large Scale Scrum)の書籍でオープンスペースが紹介されていました。

www.amazon.co.jp

そこでちょうど使えそうかなということで、試しにやってみることになりました。

もう1つ背景として、コロナの影響で弊社が完全リモートワークになっていた頃に、コミュニケーション活性化の目的で雑談オープンスペースを何度かやっていました。

ですのでやってみる分には抵抗が少ないかなという期待がありました。

仮説

実施するにあたって立てた仮説は以下になります。

  • 課題解決や改善が自発的に生まれるのでは
  • セッションが小規模で平行して走ることで、コミュニケーションの密度が上がるのでは
  • 定例開催することで、不安や悩みを早めに解消できるのでは

流れと準備

基本的な流れは一般的なものを踏襲しました。

時間は1時間で、以下のようなタイムスケジュールを想定していました。

  1. オープニング(10分)
  2. 参加者からテーマを募る(3分)
  3. セッションの時間と場所を決める(2分)
  4. セッションを行う(30分)
  5. まとめと共有(15分)

事前告知をして、テーマは事前に2つ挙げてもらい、もう2つはその場で出してもらいました。

セッション中の会話は Discord、メモや議事録は Miro を用いました。

discord.com

miro.com

Miro ではこんな感じのセットアップをして、後からセッションの内容がどうだったのか見返せるように工夫してみました。

f:id:mochinekos:20200821160817p:plain
MiroOSTTemplate

付箋の色で使い分けをしています。

  • オレンジ:テーマ
  • 緑:まとめとネクストアクション
  • 濃い黄色:Discord のルーム
  • 薄い黄色:メモ

キャンバス全体を直線で4等分にして中心にテーマなどを置くことで、それ以外のスペースを自由に使えるようにしています。

実際にやってみたらどうなったか

出たテーマ

ざっくり以下のような内容でセッションが盛り上がりました。

  • 読書会をどうやってやるか
  • プロダクトの開発体制の話
  • とある機能の実装方法の相談
  • 最近の注力開発の状況

内容は意外と広く挙がってきました。

まとめやネクストアクションを考えるのはやはりポイントですね。

セッション

テーマを挙げてもらったあとに、セッションの配置をしました。

しかしその際複数のテーマで、テーマを話したいメンバーとテーマに関して相談したいメンバーが被ってしまいました。

そこでセッションを同時に4つ行うのではなく、2つを2回に分けて行うことに急遽変更しました。

そうしてみるとタイムボックスの意識が強くなるので、より会話の密度が上がった印象を受けました。

これは想定していない良い効果でした。

タイムマネジメント

まず Discord に人が集まるまで少し時間がかかります。

それは想定していたのですが、テーマ集めと割り振りに時間がかかりました。

さらにセッションを2回に分けることとなり、時間設定を組みなおした結果、全体の時間が少し超過してしまいました。

タイムマネジメントが甘かったのは反省点でした。

仮説の検証

実施前の仮説の検証結果は以下になります。

  • 課題解決や改善が自発的に生まれるのでは
    • 〇:自発的にテーマが上がってきた
    • △:様々なメンバーからテーマがたくさん挙がってくるともっと良い
    • ✕:実際に解決や改善の効果が出るかトラッキングしたい
  • セッションが小規模で平行して走ることで、コミュニケーションの密度が上がるのでは
    • 〇:タイムボックスの意識が生まれた
    • 〇:全体で1セッションより会話が増え、集中力も上がった
  • 定例開催することで、不安や悩みを早めに解消できるのでは
    • ✕:まだ1回目、もう何度か実施してみて検証したい

おわりに

実際にやってみて、チームのコミュニケーションの1つとしては有効だと実感しました。

ですのでもう何度か実施してみて検証を続けていくことにしました。

結果と反省を踏まえて、進め方自体も改善していきます。

  • タイムテーブルを組みなおすか、パターンを作っておく
  • 開始時に前回実施分の振り返りを簡単に行う

オープンスペースはソフトウェア開発以外にも十分有用な手法ですし、実施するのにはそこまで手間はかかりませんので、チームの自発的な課題解決や改善のきっかけとして試しにやってみてはいかがでしょうか。

おまけ

弊社では「XRが当たり前の世界をつくる」というミッションを一緒に実現していきたいエンジニア、エンジニアリング・マネージャーの各職種の募集を強化しています。

XR 技術への強い関心のある方、スタートアップの環境で成長していきたい方、自己組織的な開発チームづくりに興味のある方などいらっしゃいましたら、ぜひエントリーしてください。

www.wantedly.com

www.wantedly.com

www.wantedly.com

Unityで対象オブジェクトに(ほぼ)手を入れずに使えるアウトラインエフェクトを作った

f:id:Sokuhatiku:20200720225722p:plain
空中ペンで書いた文字に表示されるアウトライン

はじめに

NEUTRANS BIZのベース機能に、Grabというものがあります。挙動は名前の通りで、レーザーポインターを当てた、もしくは直接触っているアイテムを掴んで、移動させることが出来ます。

ある時、アイテムを掴める状態を分かりやすくしてほしいというオーダーがあった為、それを実現するために、掴めるアイテムに対してアウトラインを表示する仕組みを作成しました。

この機能はすでに最新版のNEUTRANS BIZに搭載されています。

手法の検討

アウトラインの実現方法としては、メッシュを法線方向に膨らませて反転させるものが一般的です。これはお手軽ですが、いくつかの欠点があります。

  • ハードエッジの表現が苦手
  • シェーダーに手を入れる、もしくはモデルにマテリアルを追加する必要がある。

f:id:Sokuhatiku:20200720210109p:plain
メッシュ押し出し反転によるアウトライン

上画像をよくみるとアウトラインが途切れてしまっています。丸みを帯びた物体であれば問題にはなりにくいのですが、このような金属質の物体はエッジを利かせているものが多く、その場合単純に頂点を押し出しただけのアウトラインは破綻してしまいます。

以上の欠点を解消する為に、ComputeShaderとImageEffectを利用して、対象オブジェクトのレイヤー変更のみでアウトラインのON/OFFを切替できる仕組みを開発しました。

f:id:Sokuhatiku:20200720211303g:plain
レーザーポインターを当てるとレイヤーが切り替わる

この方式の利点は以下の通りです

  • オブジェクトのメッシュ特性やマテリアルに表示が左右されない
  • 遠くのオブジェクトであっても太さが変わらない為視認性が高い
  • ハードエッジに強い

逆に欠点は以下の通りです

  • レンダリング用にレイヤーを使うため、物理コンポーネントとは別オブジェクトに分ける必要がある
  • イメージエフェクトと追加カメラを利用している為、それなりに重い

仕組み

動作のイメージは以下のようになります。

  1. アウトラインを表示させたいオブジェクトをアウトラインレイヤーに移動する。
  2. アウトラインレイヤーのみ映すカメラ(シルエットカメラ)でリファレンス画像をレンダリングする。
  3. ComputeShaderでリファレンス画像からエッジ検出してアウトラインを生成する。
  4. 通常のレンダリング結果とアウトラインを合成する。

f:id:Sokuhatiku:20200720223840p:plain

工夫してみた点

Depthの考慮

前述の仕組みによりアウトラインの表示は可能になりました。ただしこの状態では、アウトラインを出すオブジェクトが他のオブジェクトの背後にあってもアウトラインが出てしまいます。

f:id:Sokuhatiku:20200720191931p:plain
キューブを貫通してアウトラインが見えてしまう

この違和感はVR中の酔いの原因になりかねない為、対策を行います。

SetReplacementShaderを利用してシルエットカメラのレンダリングに利用するシェーダーを変更し、深度情報をカラーで出力してもらうようにしました。*1

// シルエットカメラにDepth出力用シェーダーをセットする
silhouetteCamera.SetReplacementShader(settings.DepthShader, "RenderType");
// 通常カメラの深度情報は以下のコードで取得可能
var eyeDepth = Shader.GetGlobalTexture("_CameraDepthTexture");

そしてComputeShader内で、通常カメラのレンダリング結果の深度情報と比較を行い、アウトラインがオブジェクトに隠れているかどうかの判断を行うようにしました。

    float sumDepth = 0;
    float avaiableCount = 0;

    for (int i = -outlineSize; i <= outlineSize; i++)
    {
        for (int j = -outlineSize; j <= outlineSize; j++)
        {
            int pos = selfpos + i + (j * threadGroupSize_x);
            float depth = silhouetteDepth[pos];
            float avariable = depth > 0;

            sumDepth += depth * avariable;
            avaiableCount += avariable;
        }
    }

    float ztest = ((sumDepth / avaiableCount) - SourceDepth[did]) > 0;

f:id:Sokuhatiku:20200720191822p:plain

これで上手く遮蔽出来ます。 ※デバッグ用テクスチャの色は強調しています。

負荷削減

ピクセル情報の参照はGPUの中で(比較的)重い処理です。 単純に周囲のピクセルを参照すると、アウトラインの厚みによってピクセル当たりの参照ピクセル数が(2n+1)^ 2で増加します。単純計算すると3ピクセルの厚みのアウトラインを作る為には\{(2 * 3) + 1\}^ 2=49ピクセル参照する必要があります。*2

f:id:Sokuhatiku:20200721125835p:plain
3pxのアウトラインを出すためには各ピクセルが7x7の範囲を認識する必要がある

コンピュートシェーダーには、同じスレッドグループ内のスレッド同士で使える共有メモリが存在します。 これを利用する事で、隣のスレッドが取得したピクセル情報を使いまわせるため、結果としてピクセル当たりの参照回数を抑えることが出来ます。

ただし、シェアードメモリのサイズ及びスレッドグループの大きさには制限があり、一般的なFullHDの画像すべてのピクセルをシェアードメモリに載せることは出来ない為、多少工夫して何とかします。

// 例えばこのようなシェアードメモリを定義する
groupshared float silhouettePixelBuffer[ThreadGroupSize_X * ThreadGroupSize_Y* 4];
void DoOutline(uint2 gtid : SV_GroupThreadID, uint2 gid : SV_GroupID)
{
    // 担当アドレスを計算
    int2 sharedID = gtid * 2;
    int2 bufferID = int2(gtid.x * ThreadGroupSize_X - ThreadGroupSize_X * 0.5 + sharedID.x,
                        gid.y * ThreadGroupSize_Y - ThreadGroupSize_Y * 0.5 + sharedID.y);

    // 担当データを書き込む
    silhouettePixelBuffer[ThreadGroupSize_X * 2 * sharedID.y + sharedID.x] = Silhouette[bufferID];
    silhouettePixelBuffer[ThreadGroupSize_X * 2 * (sharedID.y + 1) + sharedID.x] = Silhouette[bufferID + int2(0, 1)];
    silhouettePixelBuffer[ThreadGroupSize_X * 2 * sharedID.y + (sharedID.x + 1)] = Silhouette[bufferID + int2(1, 0)];
    silhouettePixelBuffer[ThreadGroupSize_X * 2 * (sharedID.y + 1) + (sharedID.x + 1)] = Silhouette[bufferID + int2(1, 1)];

    // グループ内全てのスレッドで上の処理が終わるのを待つ
    GroupMemoryBarrierWithGroupSync();

    // この後はsilhouettePixelBufferを参照する処理を組む

結果はこちらです。 f:id:Sokuhatiku:20200720203503p:plain

思いっきり負荷をかけて改善3msという程度だったので、やらなくても良かったかもしれません……。

最後に

f:id:Sokuhatiku:20200721140442g:plain
VRかつ複雑な形状でも綺麗にアウトラインが出るところがお気に入り

以上の仕組みは、実は2017年頃に作成したものです。この度テックブログの記事としてちょうどいい題材ではないかと持ち掛けられたため、引っ張り出してきて記事にしました。

当時はほぼ新入社員だったのですが、自由にコードを書かせてもらって今に至ります。

Synamonでは現在仲間を絶賛採用中です。ご興味のある方は是非一度お話ししましょう!

herp.careers

*1:このシェーダー差し替え処理のトレードオフとして、GeometryShader等シェーダー内で頂点を弄る処理があった場合、ケアしなければ破綻するようになってしまいますが……。

*2:実際は円形に描画する為、角部分の参照は減らせます。

開発チームの生産性・健全性を可視化できるgilotを触ってみた

こんにちは。

株式会社 Synamon でエンジニアをしております、渡辺匡城(@mochi_neko_7)と申します。

今回はソフトウェアの開発チームの生産性・健全性を可視化できる gilot というツールを触ってみたのでレポートします。

ツールの作者の広木大地さん(@hiroki_daichi)は エンジニアリング組織論への招待 の著者であり、EM.FM などでも開発組織の話を発信されています。

そんな広木さんがツールを作成したと目にしたので、実際に触ってみて、弊社のプロダクトに適用してみました。

日本語での使い方やグラフ、指標の解説は Qiita にもまとめられていますので、こちらも参照ください。

qiita.com

上記の内容の補足として、環境のセットアップや Windows 環境ではまったところ、弊社のプロダクトの簡単な解析結果の紹介をします。

gilot

gilot(ジロー)は Git のログをもとに開発チームの生産性や健全性を可視化できるツールです。

GitHub のリポジトリはこちらになります。

github.com

環境セットアップ

簡単にですが、gilot の利用に必要な環境のセットアップを補足します。

なお、今回の検証に使用した環境は以下になります。

  • OS:Windows10
  • gilot:0.2.3

Python

gilot は Python のプログラムのため、実行には Python の環境が必要です。 環境自体はいくつかあり何でも構いませんが、公式はこちらです。

www.Python.org

環境変数のパスを通すのを忘れないでください。

Git

Git のログ解析をするので、Git Client の環境も必要になります。

Git を使っているリポジトリが解析対象になるので、基本的には既にセットアップされているはずです。

GUI 系の Git ツールで内部に Git Client をインストールしている場合にはその環境変数のパスを通すか、新しく公式からインストールしてしまっても構いません。

Git-scm.com

gilot

gilot のインストールは、コンソールで以下のコマンドを入力して行います。

$ pip install gilot

解析方法

GitHubQiita にも紹介がありますが、ここでも簡単に紹介します。

log

まず log コマンドを使って Git のログを解析します。

$ gilot log [repository] -o [log].csv
  • [repository] には解析対象のリポジトリのディレクトリを指定してください。

  • [log] には解析結果の出力先を指定してください。

直接グラフなどを出力するコマンドもありますが、解析にはやや時間がかかりますので、一度ファイルに書き出しておくことをお勧めします。

デフォルトでは master ブランチを対象に解析します。 これを変更したい場合には、--branch [branch_name] のオプションを追加してください。

後で紹介する hotspothotgraph の解析をしたい場合には、--full のオプションを指定して解析する必要があります。

$ gilot log [repository] --full -o [log-full].csv

こちらも少々時間がかかりますので、エラーが出ていない場合にはしばらく待ちましょう。

plot

plot コマンドを使うことで、4つの指標のグラフを作成できます。

$ gilot plot -i [log].csv -o [plot].png
  • [log] には log コマンドで作成した解析結果を指定してください。

  • [plot] にはグラフの画像の出力先を指定してください。

グラフの見方は Qiita の記事を参照してください。

hotspot

hotspot コマンドを使うことで、変更されやすいファイルを解析できます。

$ gilot hotspot -i [log-full].csv
  • [log-full] には --full オプションを追加して解析したログファイルを指定してください。

変更されやすいファイルのランキングがコンソールに出力されます。

変更されやすいということは、バグの温床になりやすいコードであり、リファクタの良い対象になりやすいと考えられます。

hotgraph

hotgraph コマンドを使うことで、同時に変更されやすいファイルのネットワークグラフを作成できます。

$ gilot hotgraph -i [log-full].csv -o [hotgraph].png
  • [log-full] には、-full オプションを追加して解析したログファイルを指定してください。

  • [hotgraph] には、グラフの画像の出力先を指定してください。

--allow-files--disallow-files のオプションで解析対象のファイルのフィルタができますので、プロジェクトによって適宜使用してください。

Windows を使っている方は注意が必要です。

内部で使用している signal.py のライブラリが Windows では使用できずエラーを吐いてしまいます。 (参考)

これは --stop-retry のオプションを使うことで回避ができます。

$ gilot hotgraph -i [log-full].csv -o [hotgraph].png --stop-retry

同時に変更されやすいファイルには何かしらの関連があると考えられます。

もし一見関係の薄いファイルが関連付けられている場合には、それらの責務が適切になっているか確認やリファクタをしたほうがよいと考えられます。

author

最近追加された author というコマンドを使うことで、コミットしている人のコミット量や全体での割合を時系列に解析できます。

$ gilot author -i [log].csv -o [author].png
  • [log] には log コマンドで作成した解析結果を指定してください。

  • [author] にはグラフの画像の出力先を指定してください。

結果

弊社のプロダクトである NEUTRANS BIZ のリポジトリの plot の結果だけ少しお見せします。

f:id:mochinekos:20200711162725p:plain

簡単な考察

上記の結果の考察を簡単にですが行ってみました。

グラフの詳細な説明は Qiita を参照してください。

Gini Coefficient

50%を下回っているので、それほど格差が大きいわけではなさそうです。

これも時系列で追って変化を見てみたいですね。

Hisgram of Code Output

ややピークが大きいでしょうか。

このグラフの使い方はまだピンと来ていないです。

Code Output and Productivity

insertions と deletions が交互に出ていて、定期的にメンテナンスしているのが分かりやすい印象です。

リリースサイクルとの連動がありそうですね。

最近追加された Productivity がまだどのような指標なのか分かっていないです。

Numer of Actual Authors

数値と実体はおおよそ一致している印象です。

数値が落ち込んでいる部分は、おそらくプロダクトの方向性を決めていた時期で手が止まっていたのかなと推測できます。

開発の安定性の参考になりそうです。

おわりに

今回は手でコンソールにコマンドを打って検証しましたが、CI に組み込んで自動で定期的にグラフを出力するのもできそうですね。

ソフトウェアの生産性や健全性は目に見えづらいものですが、ソフトウェアのコードそのものではなく、活動(Git のログ)を用いると数値で解析することできます。

と作者の方が EM.FM でおっしゃっていました。

このような指標を自分で見出したり解析するツールを作るのはなかなか大変ですよね。

その点 gilot はお手軽に可視化までできてとても便利です。

開発チームの生産性や健全性を可視化するツールの1つとして、開発チームのデリバリーパフォーマンスを測る指標 などと併用しながらうまく利用していきたいです。

UnityでのオープンワールドにはZ-Fightingという壁が立ちはだかっていた

はじめに

エンジニアの小池(DBK)です。

VRでオープンワールドに入りたいと思った人はたくさんいると思います。最近はSwitchなどでオープンワールドのゲームが出ているので特に多いのではないでしょうか。
弊社にもそんな人たちがたくさんいて、でっかいシーンを作りVRで入って色々なことがしたい!となりまして、いわゆるオープンワールドのような非常に広大なシーンの作成に取り掛かりました。

成果物

結局、弊社提供中のサービスであるNEUTRANS BIZ上では3km四方のLargeFieldという名前のシーンになりました。

建物や橋を実物大で見ることができるので、なかなか好評です。

訪れた悲しみ

シーン上のオブジェクトが原点から遠ざかっていくほど、Z-Fightingが激しくなっていきます。弊社サービスではuGUIを利用して様々なUIを構成しているので、この現象が頻発してしまい、シーンの大きさを小さくせざるを得ませんでした。

ちなみにZ-Fightingとは、メッシュがジラジラするアレです。ちゃんとWikipediaにも項目があります。
簡単に言うと、同じ位置に面が2つ以上ある場合、描画したいピクセルが複数存在するため、このような現象が発生します。特に、UnityではTransformがfloatなので、浮動小数点の計算精度がZ-Fightingに大きく影響しています。

Z-fighting - Wikipedia

開発環境

一応検証環境を記載しておきますが、Unityのバージョンは関係ないかと思います。

  • CPU:i7 8700
  • GPU:GTX1080
  • メモリ:16GB
  • OS:Windows 10 pro
  • Unity:2018.4.6f

検証

  • 準備

Z-Fightingを故意に発生させるために、uGUIのImageを利用してメッシュの重なりを作成しました。0.0001のオフセットがされていて、緑のImageが手前に配置されています。

右上に表示されているのは原点からのx方向の距離です。

また、メッシュの法線方向のオフセットを0.0001単位で広げることができるボタンも設置しました。

f:id:hdkkikdbk:20200627235817j:plain
Test UI

検証に利用したUnityのシーンはNEUTRANS BIZのLargeFieldで行いました。簡単な部屋のモデルと、グラウンドとしてのPlaneがオブジェクトとして配置されています。ちなみにこのシーンの容量は以下です。

  • LargeField:44KB
  • 空のシーン:16KB

部屋の写真
Room

  • やり方

作成したUIをx方向に原点から移動していき、どの位置でZ-Fightingが発生するか検証しました。

  • 結果

f:id:hdkkikdbk:20200630162655g:plain

原点から離れるほどにZ-Fightingが激しくなりました。こちらのシーンでは約9,000mからZ-Fightingが確認されました。オフセットを+0.1000すると約10,000mで再度Z-Fightingが発生しました。
また、Editorで実行した方が発生しやすいこともわかりました。Editorの処理によるオーバーヘッドが入ってくるためだと思われます。
そのほか、シーン内に配置されているオブジェクトが多いほど、原点からの距離が短くても発生しやすくなりました。

結論と対策

シーンに配置されているオブジェクト数、原点からの距離、表示するメッシュサイズなど、さまざまなパラメータが関係していることが容易に想像できます。定量的に検証するためにはこのようなパラメータで比較する必要がありますが、すくなくともZ-Fightingが発生しないように、メッシュの法線方向の重なりに注意する必要があることがわかりました。

今回の検証では、3Dオブジェクトの検証は行っていませんが、メッシュが重なっている部分では同じ現象が確認されました。

対策としては以下があげられます。

  1. Transformをいじって、Z-Fightingが発生しているメッシュの法線方向に差をつける
  2. シェーダーでオフセットを指定してずらす
  3. 原点からの距離ができるだけ短くなるように、原点を中心として円状にオブジェクトを配置する
  4. Playerが原点から離れないように背景オブジェクトを回転させて移動する

今回の対策としてはTransformで様々なUIにオフセットを持たせることで解決しました。もともと、uGUIのImageが重なっていた部分もあり、すでに多少のオフセットがあったのそれを広げた形になります。

また、初めはシーンに存在する部屋のモデルを原点に置いてシーンを作成していたのですが、端に行くほど原点からの距離が長くなってしまいます。そこで、中央を原点として端に部屋のモデルを配置することで、原点からの距離がシーンサイズの1辺の長さの半分になりました。

Transformを変更する方法だと、Staticなオブジェクトは問題ないですが、オブジェクトが動く場合は原点からの距離に合わせてメッシュの差を制御する必要がありそうです。

また、面のメッシュにだけ対応するだけであれば問題ないですが、立体的なオブジェクトはシェーダーで対策を行う必要があります。シェーダーについての詳しい方法はこちらを参考にしてください。

Unity でのZファイティング(Z-Fighting)の対処法 - 強火で進め

一番確実な方法としては、4つ目にあげたようにPlayerを中心として世界を回すように移動させるのがよいのでしょうが、オブジェクトを動かすときの負荷やVRなので3次元移動での方法を考える必要があるなど、なかなか考えることが多いです。本当にオープンワールドが必要になった時には再度検証してみようと思います。

最後に

Synamonでは、XRで市場を切り開いていきたい、スタートアップで挑戦していきたいエンジニアを募集しています。

気になった方は下記のWantedlyや、自分の(Twitter)でも何でもいいので、気軽にご連絡ください!

ポモドーロ・テクニックで複数人で開発してみた話

はじめに

こんにちは。

株式会社Synamonでエンジニアをしております、渡辺匡城(@mochi_neko_7)と申します。

最後の記事投稿から少し時間が空いてしまいましたが、これから再開していきたいと思っていますので、よろしくお願いいたします。

今回はモブプログラミングにポモドーロ・テクニック(ポモドーロ)を導入した開発を社内で実施してみたので、そこで実際にやってみた結果を簡単に紹介します。

状況設定

まずは簡単にですが開発の状況を紹介します。

  • 4人の固定メンバーの新しいチーム
  • 複数のテーマの開発を中長期間かけて行う
  • リアルで集まることが多い
  • 初めてのモブプログラミング
  • 1日に2~4時間固定で時間を確保
  • メンバーのスキル、経験はバラバラ
  • 設計作業の割合が多め

モブプログラミング(モブプロ)は、ペアプログラミングの複数人バージョンのような形のチーム開発の手法になります。 qiita.com モブプロの紹介はまた別の機会で記事にしますので、ここでは割愛させていただきます。

ポモドーロ自体は個人でも使えるのですが、今回はチームでの開発で適用してみました。

課題

開発を始めて数か月経って、いくつか課題が見えてきました。

  • 議論が白熱すると休憩なしに何時間も話し込んでしまう
  • かなり疲れる
  • 時間がかかる割に話がまとまらない

ポモドーロの導入

そこで、その頃どこかで耳にしたポモドーロ・テクニックを導入してみました。 next.rikunabi.com

ルールは以下になります。

  • 作業25分+休憩5分=1ポモドーロ(1ポモ)
  • 4ポモ毎に30分の長めの休憩を入れる
  • 作業の途中で割り込みが入った場合、そのポモは完了とする

もともとはクリエイティブな仕事での生産性向上のための手法として開発されたようです。

ポモドーロはトマトのイタリア語で、トマト型のキッチンタイマーが由来のようですね。

タイマー1つあれば実施できる手軽なものですが、専用アプリもいくつかあるようです。

個人的にいい感じに使いやすいアプリが見つからず、Unityを使って自分でえいやって作ったものをチームで使っていました。 github.com (最低限の機能重視でUIとかかなり適当ですが...)

というわけで、開発作業を「4ポモ=2時間」のセットで定期的に実施するスタイルをとってみました。

結果

実際にこれを半年近くやってみて実感したことは以下になります。

  • 集中力が上がった
  • 疲れにくくなった
  • 開発のリズム感が出るようになった
  • ポモ単位で作業時間が見積もれるようになった

実際、ポモドーロ導入のタイミングで作業時間は半分になりましたが、アウトプットの差は体感としてはあまり感じませんでした。

その日の作業を「3ポモ作業+1ポモ週次振り返り」のように切る使い方もでき、タイムマネジメントの手法としても優秀です。

個人でもポモドーロを使って仕事をする場合にも有用でした。

ただし、打ち合わせが頻繁に入るような日にはリズム感が崩れてしまい、あまり機能しなかった印象があります。

まとめ

  • 集中して作業したい場合に有用
  • 一人でも複数人でも使える
  • 手軽にできる
  • チーム内での評判はとてもよかった
  • 頻繁に割り込みが入るような場合には合わないかも

一見すると休憩が入ることで作業時間が減り、成果が下がるのではと思われます。 しかし実際には、クリエイティブな作業を集中的にする際には適度な休憩を入れることで、集中力が上がってよいというのを実感できました。

これは実際に体感してもらわないとなかなか伝わりづらいところでしょうか。

30分を単位とした短時間スプリントに応用したり、モブプロのドライバーの交代のタイミングにしてしまうなど、応用もできそうです。

タイマーだけあれば簡単に導入できますので、みなさんも試しに使ってみてはいかがでしょうか。

最後に

Synamonではエンジニア採用をさまざまなポジションで強化中です。

ビジネスXRで市場を切り開いていきたい、スタートアップで挑戦していきたいエンジニアを募集しています。

ご興味ある方はぜひ気軽にお話ししてみませんか。

www.wantedly.com

www.wantedly.com

www.wantedly.com

www.wantedly.com

photo credit: gerlos Pomodoro [day 61] via photopin (license)

xR (VR / AR / MR, etc.) の標準仕様OpenXRについて調べてみた

はじめに

株式会社Synamonでエンジニアをしております,久能 (@do_i_know_it) と申します.

 

VRコンテンツを開発していて一番大変なのは,アプリケーションをOculusやSteamVRなど複数のプラットフォームに対応する,新しいデバイスに対応するなどの作業だと思います.

新しいデバイスは独自のプラットフォームに対応したSDKを使わないと動作できないといった状況が多いのが現状です.

Unityによる開発では,独自プラットフォームのSDKがUnity標準のAPIに十分に対応しておらず苦しめられることも多々あったりします (心当たりがある方も多いのでは?).

 

そんな中,VRにおける仕様を標準化することでアプリケーションの開発コストを削減するためにOpenXRなるプロジェクトが立ち上がりました.

本記事では,「OpenXRとは何ぞや?」という方に向けてOpenXRとその周辺の概要を簡単に紹介したいと思います.

www.khronos.org

OpenXRとは

OpenXRとは,VR (人工現実感) / AR (拡張現実感) / MR (複合現実感) などのxRランタイムプラットフォームにおけるアプリケーションとデバイスとの間の仕様を標準化する取り組みです.

glTF,OpenGL,Vulkanなどを策定したKhronos Groupによって2016年から提唱,推進されています. 

OpenXRは次のような特徴を持つAPIとして策定されます.

  • Open
  • Royalty Free
  • Cross Platform

OpenXR 0.90が2019年3月に公開され,一部の仕様が仮策定されました.

www.khronos.org

OpenXR 1.0は2019年秋に公開予定で,残りの仕様が仮策定されます.

(2019/08/14 追記・修正)

2019年7月にSIGGRAPH 2019にてOpenXR 1.0が公開されました.

www.khronos.org

OpenXR 0.90で仮策定されていた一部の仕様 (後述のApplication Interface) がOpenXR 1.0で整備されました.

残りの仕様 (後述のDevice Plugin Interface) は1.0以降で策定・整備されていくようです.

OpenXRによる恩恵

プラットフォームのアプリケーションとデバイスとの間の仕様が標準化されることでデバイス開発者,プラットフォーム開発者,アプリケーション開発者のそれぞれにメリットがあります.

  • デバイス開発者
    • プラットフォームごとのデバイスドライバの対応が容易になる
  • プラットフォーム開発者
    • デバイスドライバごとのランタイムシステムの対応が容易になる
  • アプリケーション開発者
    • 各プラットフォームや各デバイスへの移植が容易になる

f:id:do_i_know_it:20190618125145j:plain

(OpenXR Overview - The Khronos Group Incより引用)

 

現状では,アプリケーション開発者はデバイスやプラットフォームごとにそれぞれ対応が必要であり,デバイス開発者はプラットフォームのランタイムシステムごとにデバイスドライバを提供する必要があります.

そのため,以下のコストが高くなります.

  • デバイスの各プラットフォームへの対応
  • アプリケーションの各プラットフォームや各デバイスへの対応

これにより,アプリケーションの移植性が課題となっています.

 

例えば,UnityでSteamVR対応のPCVRコンテンツを開発するとしましょう.その場合,以下のような事態が考えられます.

  • SteamVR PluginによりOculus RiftやHTC VIVE,Windows MRに対応したコンテンツを開発
  • Oculus Storeへの移植,Oculus GoやOculus Questへ対応するためにはSteamVR PluginをOculus Integrationに置き換える必要

最近はスタンドアロンなHMDもいろいろ出てきましたよね.VIVE Wave SDKやDaydream用のGoogle VR SDKなど,スタンドアロンHMDはPCVRとは別のSDKを必要とする場合が多い印象です.これらに対応しようとするとまたまたSDKを使用した処理の置き換えが発生します.

今後さらに多様なプラットフォームが台頭してくると,コンテンツを各プラットフォームに対応する度にそれぞれのプラットフォーム用のSDKに処理を置き換えていくことになり,マルチプラットフォームに対応したコンテンツを気軽に開発しにくくなっていきます.

 

OpenXRによって仕様が標準化されることで,アプリケーションの移植性が向上し,多様なプラットフォーム,多様なデバイスに対応したコンテンツを提供できるようになります.

APIのアーキテクチャ

これらの恩恵を実現するためのアーキテクチャとして,OpenXRでは2層のAPIを提供することでデバイス,プラットフォーム,アプリケーションを分離します.

  • Application Interface
    • プラットフォームのランタイムが提供するAPI
    • アプリケーションはこのAPIを通じてランタイムへアクセス
  • Device Plugin Interface
    • デバイスドライバが提供するAPI
    • ランタイムシステムはこのAPIを通じてデバイスドライバへアクセス

f:id:do_i_know_it:20190618125632p:plain

 

Unity, Oculus,SteamVR,Oculus Rift,HTC VIVEがそれぞれOpenXRに対応した未来を考えてみましょう.その場合,以下のような恩恵が考えられます.

  • Oculus RiftやHTC VIVEがDevice Plugin Interfaceを公開するデバイスドライバに対応することで,デバイスの動作環境がOculusでもStreamVRでもよい
  • OculusやStreamVRのランタイムがApplication Interfaceを公開し,Device Plugin Interfaceに対応した実装になることで,ランタイムは制御しているデバイスがOculus RiftでもHTC VIVEでもよい
  • Unityの標準APIがApplication Interfaceに対応した実装になった場合,アプリケーションは実行環境がOculusでもSteamVRでもよい

 

また,OpenXRは公式APIレイヤの他に独自のレイヤを設けられるため拡張性の高い設計になっています.追加したレイヤによって独自の機能を追加してAPIを拡張したり,既存APIの挙動を変更することができます. 

f:id:do_i_know_it:20190618125550p:plain

対応するデバイス

OpenXR 0.90は下記の形態のデバイスをサポートします.

  • Hand
    • ハンドコントローラ
      • ex) Oculus Touch
    • トラッキングした手の姿勢
      • ex) Leap Motion
  • Head
    • ヘッドマウンテッドディスプレイ (HMD)
      • ex) HTC VIVE
    • トラッキングした頭の姿勢
      • ex) RealSense
  • Gamepad
    • 従来の両手持ちゲームパッド
  • Treadmill
    • 歩行による移動を計測する装置

提供する機能

OpenXR 0.90は下記の機能を提供します.

  • Spaces
    • アプリケーション内の空間の管理
  • View Configuration
    • アプリケーション画面構成の管理
  • Session
    • アプリケーションの実行ループの管理
  • Rendering
    • アプリケーションの描画処理の管理
  • Input and Haptics
    • ユーザのアクションとフィードバックの管理

Renderingはあくまで描画処理の実行タイミングなどの管理だけを行い,実際の描画命令がどのような実装かは問われません.そのため,描画の手段としてOpenGLを利用するかVulkanを利用するかなどはプラットフォームのランタイムの実装次第となります.

詳しくは公式の仕様を眺めてみてください.

www.khronos.org

メンバーシップ

Khronos Groupのメンバーシップに参加することで,OpenXRの仕様の普及や策定などに関わることができます.

www.khronos.org

メンバーシップは大まかに分けて以下の2種類に大別されます.

  • 仕様の策定に参加可能,普及活動に参加可能

f:id:do_i_know_it:20190618130518p:plain

  • 仕様の策定は参加不可,普及活動は参加可能

f:id:do_i_know_it:20190618130514p:plain

(https://www.khronos.org/members/より引用)

2019年7月現在,GoogleやMicrosoftの他,Unity,Epic Games,Sonyなどが参画しています.

OpenXRへの対応状況

APIへの対応状況は2019年7月現在下記の通りです.

  • 対応済み
  • 年内対応予定 
    • Oculus (Facebook)
    • Unreal Engine (Epic Games)

 

Unityの対応状況はというと,現時点では公表されていません.しかしメンバーシップには参加しているので,近く対応することを期待しています.

 

(2019/08/14 追記)

Oculus Rift,Oculus  QuestのOpenXR対応が発表されました.

 

www.khronos.org

 

その他の標準化プロジェクト

今回紹介フォーカスしているOpenXRの他にも,xRにおける仕様を策定しようとする活動がいくつかありました.

OpenVR

Valve Softwareが2015年から提供しているVRデバイス向けのAPIであり,特定のハードウェアベンダのSDKなどに依存せずにアプリケーションを開発できることを目的としています.

github.com

BSD 3-Clause Licenseで公開されています.

OpenXR同様,アプリケーション側とドライバ側の2層にAPIが分かれています.

www.youtube.com

2019年7月現在,主にSteamVR Pluginの公開APIのような立ち位置になっています.

またSteamVR PluginはInput System 2.0でOpenXRへの対応を見据えた機構に変わりました.

Open Source Virtual Reality (OSVR)

Razerなどが2015年1月から推進していたオープンソースなVRデバイスの仕様標準化プロジェクトです.

ハードウェア要求が低くOSに依存しないため,GNU/LinuxのPCでVRを体験できるのが特徴です.

osvr.github.io

Apache 2.0 Licenseで公開されています.

2019年7月現在,残念ながらコミュニティでの活動が見られません.

また,RazerはSensicsと提携して同名のPC向けHMDを開発・販売していましたが,現在は生産が終了しているようです.

General Specifications for Virtual Reality Head-Mounted Displays

中国電子標準化研究所が2017年4月から提唱,推進している仕様書です.

北京工科大学やHTCなど,中国国内の研究機関や企業が標準化に参加しています.

2017年7月から仕様書の英文版(原題:虚拟现实头戴式显示设备通用规范)が公開されています.

skarredghost.com

 

おまけ

公式HPにてTシャツが販売されています.OpenXRを広めたい,OpenXRに貢献している気分になりたい方におすすめです.

Powered by teespring

teespring.com

 

これまでに紹介した通り,OpenXRはデバイスドライバ,ランタイム,アプリケーションの間におけるAPIを標準化する取り組みです.

これに対して,デバイスとPCとの物理的な接続方法に関する標準規格がVirtualLinkです.USB Type-CのDisplayPort Alternate Modeを用いて,HMDの接続規格を標準化します.

sites.google.com

まとめ

本記事では,OpenXRとその周辺の概要を紹介しました.

  • OpenXRとはxR (VR/AR/MR) の仕様を標準化する取り組み
  • アプリケーション,プラットフォームのランタイム,デバイスドライバの間に標準APIを策定
    → プラットフォーム,デバイス別の対応が簡易化
    → アプリケーションの移植性が向上
  • OpenXRの他にも標準仕様を策定する取り組みが存在する
  • メンバーシップに参加するとOpenXRの普及や策定に関われる

今回紹介したOpenXRなどの標準仕様の策定が推進されている現状を見ると,弊社の目指すVRが当たり前の世界へ近づいている実感がありますね.

仕様が標準化されることでVRの普及が進むことを期待しているので,今後も動向を追っていきたいと思っています.