TECH PLAY

電通総研

電通総研 の技術ブログ

836

こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回は ZBrush で作成した3Dモデルを、UE5のタイムラインという機能を活用して、簡単なアニメーションを作成する手順をご紹介します。 はじめに UE5でオブジェクトにアニメーションをつける方法としてBlueprintのタイムラインを使用する方法があります。 タイムラインで設定した時間(タイミング)に、あらかじめ定義した値を出力する仕組みで、簡単なアニメーションが実装できます。 タイムラインを使用せずに、複雑なアニメーションを作成する手順も今後配信予定です。 今回はDCCツールの ZBrush を使用して、大砲の3Dオブジェクトを作成し、UE5内でその大砲を動かしたり弾を発射させるなどのアニメーションをつけていきます。 検証環境/ツール Unreal Engine5.1.1 ZBrush 2022.0.6 実装手順 ZBrush で大砲を作成 ZBrush で作成したオブジェクトをエクスポート UE5でFBXファイルをインポート UE5でタイムラインを使用したアニメーションの作成 1. ZBrush で大砲を作成 まず初めに ZBrush を使用して大砲の3Dオブジェクトを作成します。 今回詳しい作成方法は割愛しますが、 ZBrush の操作方法やオブジェクト作成手順につきましては、今後記事を配信予定です。 まずはバレル(銃身)部分を作成します。 今回は下記画像のようなバレルの形状で作成しています。 次にバレルを装着するベースの部分の作成を行います。 今回は本題ではないため割愛しますが、 ZBrush のローポリ編集を使用することで、下記画像のような無機質な形状も作成できます。 今回の実装のポイントとしては、バレルとベースの部分を2つの部品として、別々のオブジェクトで作成することです。 これにより、後述するタイムラインを利用したアニメーションに使用できます。 2. ZBrush で作成したオブジェクトをエクスポート ZBrush で作成したオブジェクトをUEで使用できるようにFBXに変換してエクスポートする必要があります。 ZBrush のZ プラグイン という機能を使用して、FBXエクスポートの手順を紹介します。 主にエクスポートで変更するのは下記部分になります。 出力する情報を選択 FBXのバージョンを選択 ファイルの形式を選択 メッシュを三角メッシュにするかどうか ポリペイントの出力をするかどうか エクスポート ① 出力する情報を選択 出力する情報を下記から選びます。 選択のみ : 選択したサブツール 表示のみ : 表示してあるサブツール すべて : 全てのサブツール 今回は、バレル部分とベースの部分で2種類のFBXを出力したかったので、 それぞれ個別に選択を行い「Select」を選びました。 ② FBXのバージョンを選択 「FBX2020」の部分をクリックすることで、バージョンが選択できます。 今回は「FBX2020」を選択しました。 ③ ファイルの形式を選択 ファイルの形式を下記から選びます。 bin ascii binの方がファイルサイズが小さく一般的なので、今回はこちらを選択しました。 ④ メッシュを三角メッシュにするかどうか メッシュを三角ポリゴンとしてエクスポートしたい場合はオンにします。 三角ポリゴンにすると、ポリゴン数が減りファイルが軽くなる代わりに、メッシュの再編集がしにくくなります。 今回は小さなファイルだったので、設定はオフのまま進めました。 ⑤ ポリペイントの出力をするかどうか ZBrush 上でもポリペイントという機能を使用することでオブジェクトに色をつけることができます。 サブツール内の筆のマークをオンにすることで、ポリペイントもFBXに含めることができます。 今回は、マテリアルや色の設定はUEで行うので、オフのまま進めます。 ⑥ エクスポート エクスポートボタンを押下し、モデルのエクスポートを行います。 3. UE5でFBXファイルをインポート 前工程で、バレルとベースの部分で2種類のFBXファイルを作成したので、 今回はそれらをUE5にインポートを行います。 今回は2種類のFBXファイル名を以下のように作成しています。 cannon.fbx cannon_base.fbx Content Drawerを開き、右クリックから「Import to Game」を押下し、前工程で作成した2つのFBXファイルをインポートします。 マテリアルに関してはUEで作成していくので、「Create New Materials」を選択します。   インポートすると下記キャプチャのに表示されます。 インポートしてきたcannon.fbxをダブルクリックしてアセットの編集画面を開きます。 想定していたものより小さくインポートされていたので、右側の詳細画面から「Transform」の値を変更します。 今回は「Import Uniform Scale」の値を16に変更します。またデフォルトでの向きを変更するために「Import Rotation」のY軸を90に変更します。 この設定値はインポートする際の設定値になるので、画面上部にある「Reimport Base Mesh」を押下し、再度インポートします。 インポートが完了するとオブジェクトの大きさや向きが変わります。 次にマテリアルを変更します。 UEでプロジェクトを作成時、Starter Contentsを含める設定をしていると様々なマテリアルがデフォルトでインストールされているので、今回はそこからマテリアルを選んでいきます。 右側の詳細画面からMaterial Slotsを開きます。 セレクトボックスから「M_Metal_ Chrome 」を選択します。最後にこのアセット編集画面を保存することで、FBXファイルのデフォルト値を変更できます。 cannon_base.fbxも同様に編集します。大きさや向きはcannon.fbxと同じように変更しました。 マテリアルに関しては、「M_Metal_Burnished_Steel」を選択しました。 同様に保存を行うことで、Content Drawerの表示もマテリアルが適応された形に変化します。 Content Drawerで2種類のFBXファイルを選択し、View Portに ドラッグ&ドロップ することで、オブジェクトの大きさやマテリアルの見え方を確認できます。 以上で、FBXのインポートの説明を終わります。次は実際にインポートしたファイルにBlueprintを利用してアニメーションをつけていきます。 4. UE5でタイムラインを使用したアニメーションの作成 大砲の球を作成 まずは大砲のアニメーションを作成する前に、大砲から発射される球を作っていきます。 Content Drawerを開き、大砲の球用のActorのBlueprintを作成します。 今回は「BP_projectile」という名前で生成しました。 Blueprintを作成したら、まずは コンポーネント を追加します。「 Sphere Collision」という衝突判定を行う コンポーネント を作成します。 「DefaultSceneRoot」に「 Sphere Collision」を ドラッグ&ドロップ を行います。 これでこの コンポーネント が親 コンポーネント として設定されます。 次に「DefaultSceneRoot」に設定した「 Sphere Collision」の子 コンポーネント として「 Sphere 」を追加します。 大きさやマテリアルを右側の詳細画面で変更します。 Transformから大きさを変更します。 今回はMaterialで「M_Metal_Gold」を選択しました。 指定が終わると、下記キャプチャのように大きさとマテリアルが変更されます。 次に「Projectile Movement」という コンポーネント を追加します。これはこのBlueprint内のオブジェクトを発射物として一定方向に移動させ続けることができます。 最後にContent Drawerに戻り、作成したBlueprintをView Portに ドラッグ&ドロップ して配置してみます。 下記動画のように移動している鉄球ができれば大砲の球は完成です。 次にインポートしてきた大砲にアニメーションをつけていきます。 大砲から球を発射させる 大砲の球を作った時と同じように新規のBlueprintを作成します。 今回は「BP_cannon」という名前で生成しました。 大砲の球の時と同様に「 Sphere 」の コンポーネント を追加し、「DefaultSceneRoot」に ドラッグ&ドロップ を行い親 コンポーネント とします。 ここでは名前を「cannon_base」と変更しました。 次に右側の「Static Mesh」から、FBXでインポートした「cannon_base」を選択します。 次に、「cannon_base」の子 コンポーネント として「cannon_barrel」という名前で「 Sphere 」の コンポーネント を追加します。 同様に「Static Mesh」から、FBXでインポートした「cannon」を選択します。 ここで詳細画面の「Collision Presets」を「No Collision」に変更しておきます。 次に、このActorをSpawnさせる際の位置や向きを取得するために「Arrow」 コンポーネント を追加します。 名前を「Projectile Spawn Point」に変更し、「cannon_barrel」の子 コンポーネント として設定します。 View Port上に矢印が追加されるので、大砲の球を生成したい位置に矢印を移動します。 次に、大砲から球を出すBlueprintを作成します。 「BP_cannon」のEvent Graphを開きます。 「Event BeginPlay」ノードから「Delay」ノードを作成し、「Duration」を1秒に設定します。次に「SpawnActor Actor from Class」ノードを繋ぎ、Classの属性を「BP_Projectile」を選択します。 左側のComponentsから「Projectile Spawn Point」を ドラッグ&ドロップ してView Portに配置します。 さらにそこから「Get World Location / Rotation」の2つのノードを作成し、「SpawnActor Actor from Class」のノードに繋ぎます。 繰り返し球が出るように、「SpawnActor Actor from Class」から「Delay」につなげることで、球の発射されるBlueprintは完了です。 ここで一旦、作成したBlueprintをView Portに配置してみます。 この段階ではまだバレルに動きはありませんが、バレルの先端から球が発射されるようになりました。 大砲の発射時にアニメーションをつける(バレルのアニメーション) 次にBlueprintのタイムラインという機能を使って大砲の発射時にアニメーションをつけていきます。 「BP_cannon」のEvent Graph上で右クリックを行い「Timeline」を検索しノードを作成します。 名前を「Cannon fire Timeline」と変更しました。ダブルクリックをすることでタイムラインの編集に入れます。 次に左上の「+Track」を押下し「Add Float Track」を選択し、「Cannon Barrel location」というトラックを作成します。 出てきたトラック上で右クリックで「Add key」を選択し、表の中にkeyを3つ作りました。 keyの値は下記の通りにしています。 Time:0.0 / Value :0 Time:0.2 / Value :70 Time:0.6 / Value :0 Event Graphに戻ると「Cannon fire Timeline」のノードに「Cannon Barrel Location」というアウトプットピンが追加されているのがわかります。 ここの返り値として、秒数ごとに上で設定した Value の値が排出されます。 今回の例で言うと、このタイムラインが発火したタイミングでValue0が返却され、0.2秒後にValue70が返却される。 さらに発火から0.6秒後にはValue0が返却されるという式になります。 次に設定した Value の分だけ大砲のバレル部分を動かして、球が発射される時の挙動を作っていきます。 左下からCannon Barrel コンポーネント を配置し、「Set Relative Location」と繋ぎます。 タイムラインで排出される Value の値を、バレルのX軸に対して適応することで、秒数ごとにバレルが伸び縮みする仕組みが作成できます。 次に、タイムラインが発火したことを知らせる値を作成します。 再びタイムライン編集画面に戻り、「+Track」を押下し、「Add Event Track」を選択し「Cannon fired」と名前を変更します。 発火したことを伝えるだけでいいので、値は気にせず「Time:0.0 / Value :0」のkeyを作成します。 「Cannon Fired」というピンが作成されたのを確認します。 「Event BeginPlay」から続く流れに、今回作成したタイムラインのノードを含めるために「SpawnActor Actor from Class」の実行ピンを「Cannon fire timeline」のPlay from Startピンに接続します。次に「Cannon Fired」ピンをDelayノードに接続し直します。 これにより球を発射するたびにバレルが動くようになります。 View Portに配置するとこのように見えます。ついにバレルが動くようになりました。 大砲の発射時にアニメーションをつける(爆発のエフェクト) 最後に、大砲が球を発射するときに、爆発のエフェクトを追加します。 「Spawn Emitter at Location」というノードを使うことで、任意のEmitter(今回は爆発エフェクト)を任意の場所に出すことができます。 Starter Contentsに含まれている「P_Explosion」をセレクトボックスから選びます。 次に「Get Actor Location」を作成し、現在の大砲の位置をBlueprint上に引用し、「Spawn Emitter at Location」のLocationピンに繋ぎます。 爆発が出る位置を、バレルの先端に変更したいので、「LocationX」だけの値を90に変更しました。 最後に、作成した爆発エフェクトのノードを大砲の球が生成される直前のノードに追加することで、爆発エフェクトを付加できます。 View Portで確認すると以下の動画のように見えます。 以上が、 ZBrush で作成した3Dモデルから、UE5のタイムラインという機能を活用して、簡単なアニメーションを作成する手順のご紹介でした。 所感 今回は ZBrush で作成したシンプルなモデルを、UEのタイムラインを用いてアニメーションさせました。 タイムラインで出力する値を利用する方法は、簡単なアニメーションを作るにはとても便利な手段だと感じました。 例えばユーザーに気づいてもらいたいアイテムを定期的に光らせたりするアニメーションは ノンゲーム の領域でも利用価値がとてもありそうです。 次回以降は、より複雑なアニメーションを作成する手順にも挑戦してみようと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://www.udemy.com/course/unrealblueprint/learn/lecture/13833864#overview https://mononoco.com/creative/zbrush/fbx-exportimport 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回は ZBrush で作成した3Dモデルを、UE5のタイムラインという機能を活用して、簡単なアニメーションを作成する手順をご紹介します。 はじめに UE5でオブジェクトにアニメーションをつける方法としてBlueprintのタイムラインを使用する方法があります。 タイムラインで設定した時間(タイミング)に、あらかじめ定義した値を出力する仕組みで、簡単なアニメーションが実装できます。 タイムラインを使用せずに、複雑なアニメーションを作成する手順も今後配信予定です。 今回はDCCツールの ZBrush を使用して、大砲の3Dオブジェクトを作成し、UE5内でその大砲を動かしたり弾を発射させるなどのアニメーションをつけていきます。 検証環境/ツール Unreal Engine5.1.1 ZBrush 2022.0.6 実装手順 ZBrush で大砲を作成 ZBrush で作成したオブジェクトをエクスポート UE5でFBXファイルをインポート UE5でタイムラインを使用したアニメーションの作成 1. ZBrush で大砲を作成 まず初めに ZBrush を使用して大砲の3Dオブジェクトを作成します。 今回詳しい作成方法は割愛しますが、 ZBrush の操作方法やオブジェクト作成手順につきましては、今後記事を配信予定です。 まずはバレル(銃身)部分を作成します。 今回は下記画像のようなバレルの形状で作成しています。 次にバレルを装着するベースの部分の作成を行います。 今回は本題ではないため割愛しますが、 ZBrush のローポリ編集を使用することで、下記画像のような無機質な形状も作成できます。 今回の実装のポイントとしては、バレルとベースの部分を2つの部品として、別々のオブジェクトで作成することです。 これにより、後述するタイムラインを利用したアニメーションに使用できます。 2. ZBrush で作成したオブジェクトをエクスポート ZBrush で作成したオブジェクトをUEで使用できるようにFBXに変換してエクスポートする必要があります。 ZBrush のZ プラグイン という機能を使用して、FBXエクスポートの手順を紹介します。 主にエクスポートで変更するのは下記部分になります。 出力する情報を選択 FBXのバージョンを選択 ファイルの形式を選択 メッシュを三角メッシュにするかどうか ポリペイントの出力をするかどうか エクスポート ① 出力する情報を選択 出力する情報を下記から選びます。 選択のみ : 選択したサブツール 表示のみ : 表示してあるサブツール すべて : 全てのサブツール 今回は、バレル部分とベースの部分で2種類のFBXを出力したかったので、 それぞれ個別に選択を行い「Select」を選びました。 ② FBXのバージョンを選択 「FBX2020」の部分をクリックすることで、バージョンが選択できます。 今回は「FBX2020」を選択しました。 ③ ファイルの形式を選択 ファイルの形式を下記から選びます。 bin ascii binの方がファイルサイズが小さく一般的なので、今回はこちらを選択しました。 ④ メッシュを三角メッシュにするかどうか メッシュを三角ポリゴンとしてエクスポートしたい場合はオンにします。 三角ポリゴンにすると、ポリゴン数が減りファイルが軽くなる代わりに、メッシュの再編集がしにくくなります。 今回は小さなファイルだったので、設定はオフのまま進めました。 ⑤ ポリペイントの出力をするかどうか ZBrush 上でもポリペイントという機能を使用することでオブジェクトに色をつけることができます。 サブツール内の筆のマークをオンにすることで、ポリペイントもFBXに含めることができます。 今回は、マテリアルや色の設定はUEで行うので、オフのまま進めます。 ⑥ エクスポート エクスポートボタンを押下し、モデルのエクスポートを行います。 3. UE5でFBXファイルをインポート 前工程で、バレルとベースの部分で2種類のFBXファイルを作成したので、 今回はそれらをUE5にインポートを行います。 今回は2種類のFBXファイル名を以下のように作成しています。 cannon.fbx cannon_base.fbx Content Drawerを開き、右クリックから「Import to Game」を押下し、前工程で作成した2つのFBXファイルをインポートします。 マテリアルに関してはUEで作成していくので、「Create New Materials」を選択します。   インポートすると下記キャプチャのに表示されます。 インポートしてきたcannon.fbxをダブルクリックしてアセットの編集画面を開きます。 想定していたものより小さくインポートされていたので、右側の詳細画面から「Transform」の値を変更します。 今回は「Import Uniform Scale」の値を16に変更します。またデフォルトでの向きを変更するために「Import Rotation」のY軸を90に変更します。 この設定値はインポートする際の設定値になるので、画面上部にある「Reimport Base Mesh」を押下し、再度インポートします。 インポートが完了するとオブジェクトの大きさや向きが変わります。 次にマテリアルを変更します。 UEでプロジェクトを作成時、Starter Contentsを含める設定をしていると様々なマテリアルがデフォルトでインストールされているので、今回はそこからマテリアルを選んでいきます。 右側の詳細画面からMaterial Slotsを開きます。 セレクトボックスから「M_Metal_ Chrome 」を選択します。最後にこのアセット編集画面を保存することで、FBXファイルのデフォルト値を変更できます。 cannon_base.fbxも同様に編集します。大きさや向きはcannon.fbxと同じように変更しました。 マテリアルに関しては、「M_Metal_Burnished_Steel」を選択しました。 同様に保存を行うことで、Content Drawerの表示もマテリアルが適応された形に変化します。 Content Drawerで2種類のFBXファイルを選択し、View Portに ドラッグ&ドロップ することで、オブジェクトの大きさやマテリアルの見え方を確認できます。 以上で、FBXのインポートの説明を終わります。次は実際にインポートしたファイルにBlueprintを利用してアニメーションをつけていきます。 4. UE5でタイムラインを使用したアニメーションの作成 大砲の球を作成 まずは大砲のアニメーションを作成する前に、大砲から発射される球を作っていきます。 Content Drawerを開き、大砲の球用のActorのBlueprintを作成します。 今回は「BP_projectile」という名前で生成しました。 Blueprintを作成したら、まずは コンポーネント を追加します。「 Sphere Collision」という衝突判定を行う コンポーネント を作成します。 「DefaultSceneRoot」に「 Sphere Collision」を ドラッグ&ドロップ を行います。 これでこの コンポーネント が親 コンポーネント として設定されます。 次に「DefaultSceneRoot」に設定した「 Sphere Collision」の子 コンポーネント として「 Sphere 」を追加します。 大きさやマテリアルを右側の詳細画面で変更します。 Transformから大きさを変更します。 今回はMaterialで「M_Metal_Gold」を選択しました。 指定が終わると、下記キャプチャのように大きさとマテリアルが変更されます。 次に「Projectile Movement」という コンポーネント を追加します。これはこのBlueprint内のオブジェクトを発射物として一定方向に移動させ続けることができます。 最後にContent Drawerに戻り、作成したBlueprintをView Portに ドラッグ&ドロップ して配置してみます。 下記動画のように移動している鉄球ができれば大砲の球は完成です。 次にインポートしてきた大砲にアニメーションをつけていきます。 大砲から球を発射させる 大砲の球を作った時と同じように新規のBlueprintを作成します。 今回は「BP_cannon」という名前で生成しました。 大砲の球の時と同様に「 Sphere 」の コンポーネント を追加し、「DefaultSceneRoot」に ドラッグ&ドロップ を行い親 コンポーネント とします。 ここでは名前を「cannon_base」と変更しました。 次に右側の「Static Mesh」から、FBXでインポートした「cannon_base」を選択します。 次に、「cannon_base」の子 コンポーネント として「cannon_barrel」という名前で「 Sphere 」の コンポーネント を追加します。 同様に「Static Mesh」から、FBXでインポートした「cannon」を選択します。 ここで詳細画面の「Collision Presets」を「No Collision」に変更しておきます。 次に、このActorをSpawnさせる際の位置や向きを取得するために「Arrow」 コンポーネント を追加します。 名前を「Projectile Spawn Point」に変更し、「cannon_barrel」の子 コンポーネント として設定します。 View Port上に矢印が追加されるので、大砲の球を生成したい位置に矢印を移動します。 次に、大砲から球を出すBlueprintを作成します。 「BP_cannon」のEvent Graphを開きます。 「Event BeginPlay」ノードから「Delay」ノードを作成し、「Duration」を1秒に設定します。次に「SpawnActor Actor from Class」ノードを繋ぎ、Classの属性を「BP_Projectile」を選択します。 左側のComponentsから「Projectile Spawn Point」を ドラッグ&ドロップ してView Portに配置します。 さらにそこから「Get World Location / Rotation」の2つのノードを作成し、「SpawnActor Actor from Class」のノードに繋ぎます。 繰り返し球が出るように、「SpawnActor Actor from Class」から「Delay」につなげることで、球の発射されるBlueprintは完了です。 ここで一旦、作成したBlueprintをView Portに配置してみます。 この段階ではまだバレルに動きはありませんが、バレルの先端から球が発射されるようになりました。 大砲の発射時にアニメーションをつける(バレルのアニメーション) 次にBlueprintのタイムラインという機能を使って大砲の発射時にアニメーションをつけていきます。 「BP_cannon」のEvent Graph上で右クリックを行い「Timeline」を検索しノードを作成します。 名前を「Cannon fire Timeline」と変更しました。ダブルクリックをすることでタイムラインの編集に入れます。 次に左上の「+Track」を押下し「Add Float Track」を選択し、「Cannon Barrel location」というトラックを作成します。 出てきたトラック上で右クリックで「Add key」を選択し、表の中にkeyを3つ作りました。 keyの値は下記の通りにしています。 Time:0.0 / Value :0 Time:0.2 / Value :70 Time:0.6 / Value :0 Event Graphに戻ると「Cannon fire Timeline」のノードに「Cannon Barrel Location」というアウトプットピンが追加されているのがわかります。 ここの返り値として、秒数ごとに上で設定した Value の値が排出されます。 今回の例で言うと、このタイムラインが発火したタイミングでValue0が返却され、0.2秒後にValue70が返却される。 さらに発火から0.6秒後にはValue0が返却されるという式になります。 次に設定した Value の分だけ大砲のバレル部分を動かして、球が発射される時の挙動を作っていきます。 左下からCannon Barrel コンポーネント を配置し、「Set Relative Location」と繋ぎます。 タイムラインで排出される Value の値を、バレルのX軸に対して適応することで、秒数ごとにバレルが伸び縮みする仕組みが作成できます。 次に、タイムラインが発火したことを知らせる値を作成します。 再びタイムライン編集画面に戻り、「+Track」を押下し、「Add Event Track」を選択し「Cannon fired」と名前を変更します。 発火したことを伝えるだけでいいので、値は気にせず「Time:0.0 / Value :0」のkeyを作成します。 「Cannon Fired」というピンが作成されたのを確認します。 「Event BeginPlay」から続く流れに、今回作成したタイムラインのノードを含めるために「SpawnActor Actor from Class」の実行ピンを「Cannon fire timeline」のPlay from Startピンに接続します。次に「Cannon Fired」ピンをDelayノードに接続し直します。 これにより球を発射するたびにバレルが動くようになります。 View Portに配置するとこのように見えます。ついにバレルが動くようになりました。 大砲の発射時にアニメーションをつける(爆発のエフェクト) 最後に、大砲が球を発射するときに、爆発のエフェクトを追加します。 「Spawn Emitter at Location」というノードを使うことで、任意のEmitter(今回は爆発エフェクト)を任意の場所に出すことができます。 Starter Contentsに含まれている「P_Explosion」をセレクトボックスから選びます。 次に「Get Actor Location」を作成し、現在の大砲の位置をBlueprint上に引用し、「Spawn Emitter at Location」のLocationピンに繋ぎます。 爆発が出る位置を、バレルの先端に変更したいので、「LocationX」だけの値を90に変更しました。 最後に、作成した爆発エフェクトのノードを大砲の球が生成される直前のノードに追加することで、爆発エフェクトを付加できます。 View Portで確認すると以下の動画のように見えます。 以上が、 ZBrush で作成した3Dモデルから、UE5のタイムラインという機能を活用して、簡単なアニメーションを作成する手順のご紹介でした。 所感 今回は ZBrush で作成したシンプルなモデルを、UEのタイムラインを用いてアニメーションさせました。 タイムラインで出力する値を利用する方法は、簡単なアニメーションを作るにはとても便利な手段だと感じました。 例えばユーザーに気づいてもらいたいアイテムを定期的に光らせたりするアニメーションは ノンゲーム の領域でも利用価値がとてもありそうです。 次回以降は、より複雑なアニメーションを作成する手順にも挑戦してみようと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://www.udemy.com/course/unrealblueprint/learn/lecture/13833864#overview https://mononoco.com/creative/zbrush/fbx-exportimport 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
こんにちは、X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 好きな AWS サービスはSecurity HubとGuardDutyです。 はじめに 2023年4月10日にGuardDutyの新しい検出タイプが公表されましたので紹介します。 https://aws.amazon.com/jp/about-aws/whats-new/2023/04/amazon-guardduty-threat-detections-dns-traffic/ 追加された3つの検出タイプは、すべてDefense Evasionに関連しています。 Defense Evasionとは「防衛回避」のことで、セキュリティソフトに検知されないために攻撃者が攻撃を隠蔽することです。 今回、外部 DNS プロバイダーを使用するか、 HTTPS (DoH) または TLS (DoT) 経由で DNS トラフィック を送信するなどの手法を使用した防衛回避について検出できるようになりました。 各検出タイプについて、以下で説明します。 新しく追加された検出タイプ DefenseEvasion:EC2/UnusualDNSResolver 重要度:Medium(中) 使用可能なリージョン:GuardDutyがサポートされている全リージョン 検出ロジック:通常、EC2 インスタンス は、正当な DNS サーバーからの応答を受信することが期待されます。 この検出は、EC2 インスタンス が通常の DNS トラフィック パターンを学習し、長期間利用していないパブリック DNS リ ゾル バに対する DNS 通信を警告します。 補足:本機能が追加される前のGuardDutyには、デフォルトの AWS DNS リ ゾル バを使用して問題を見つけるといった制限がありました。 なので、例えばデフォルトの DNS 設定を Google DNS (8.8.8.8または8.8.4.4)とすると、攻撃は検出されずに任意の ドメイン にクエリを実行できてしまいます。 前提として、安易にデフォルトの AWS DNS 設定を外部 DNS に変えることは避けるべきですが、今回の機能追加によって検出できるようになりました。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unusualdnsresolver DefenseEvasion:EC2/UnusualDoHActivity 重要度:Medium(中) 使用可能なリージョン:一部リージョン ※ を除くGuardDutyがサポートされている全リージョン 検出ロジック:この検出は、EC2 インスタンス の通常の DNS トラフィック パターンを学習し、長期間利用していないパブリックDoHサーバへのDoH通信を警告します。 補足:DoH( DNS over HTTPS )とは、 HTTPS を用いて DNS 通信を行う技術のことです。 従来の DNS は UDP による平文でしたが、これを HTTPS の技術を使用して暗号化します。 攻撃者は、DoHを使用して通常の DNS トラフィック を脅威検知から回避することがあります。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unsualdohactivity DefenseEvasion:EC2/UnusualDoTActivity 重要度:Medium(中) 使用可能なリージョン:一部リージョン ※ を除くGuardDutyがサポートされている全リージョン 検出ロジック:この検出は、EC2 インスタンス の通常の DNS トラフィック パターンを学習し、長期間利用していないパブリックDoTサーバへのDoT通信を警告します。 補足:DoT( DNS over TLS )とは、 DNS 通信を TLS レベルで暗号化する技術のことです。 攻撃者は、DoTを使用して、通常の DNS トラフィック を脅威検知から回避することがあります。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unusualdotactivity ※ 一部リージョン: AWS アジアパシフィック(大阪), AWS アジアパシフィック( ジャカルタ ), AWS アジアパシフィック(ソウル), 中国(北京、Sinnetが運営), 中国( 寧夏 、NWCDが運営) 所感 上記3タイプはデータソースとして VPC フローログを利用しているということで、今まで検出できなかったパターンを補完するアップデートとなりました。 DoHとDoTの利用はまだ普及していないため、「DefenseEvasion:EC2/UnusualDoHActivity」が検出される機会が増えそうです。 なお、直近で通信履歴がないものに対して検知されるため、誤検知も少なからず発生する可能性はあります。 検出されたらターゲットのIPを確認し、想定された正常な動きかどうか慎重に見極めた方が良さそうです。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア(セキュリティ設計) 執筆: @fuku.dancho 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
こんにちは、X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 好きな AWS サービスはSecurity HubとGuardDutyです。 はじめに 2023年4月10日にGuardDutyの新しい検出タイプが公表されましたので紹介します。 https://aws.amazon.com/jp/about-aws/whats-new/2023/04/amazon-guardduty-threat-detections-dns-traffic/ 追加された3つの検出タイプは、すべてDefense Evasionに関連しています。 Defense Evasionとは「防衛回避」のことで、セキュリティソフトに検知されないために攻撃者が攻撃を隠蔽することです。 今回、外部 DNS プロバイダーを使用するか、 HTTPS (DoH) または TLS (DoT) 経由で DNS トラフィック を送信するなどの手法を使用した防衛回避について検出できるようになりました。 各検出タイプについて、以下で説明します。 新しく追加された検出タイプ DefenseEvasion:EC2/UnusualDNSResolver 重要度:Medium(中) 使用可能なリージョン:GuardDutyがサポートされている全リージョン 検出ロジック:通常、EC2 インスタンス は、正当な DNS サーバーからの応答を受信することが期待されます。 この検出は、EC2 インスタンス が通常の DNS トラフィック パターンを学習し、長期間利用していないパブリック DNS リ ゾル バに対する DNS 通信を警告します。 補足:本機能が追加される前のGuardDutyには、デフォルトの AWS DNS リ ゾル バを使用して問題を見つけるといった制限がありました。 なので、例えばデフォルトの DNS 設定を Google DNS (8.8.8.8または8.8.4.4)とすると、攻撃は検出されずに任意の ドメイン にクエリを実行できてしまいます。 前提として、安易にデフォルトの AWS DNS 設定を外部 DNS に変えることは避けるべきですが、今回の機能追加によって検出できるようになりました。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unusualdnsresolver DefenseEvasion:EC2/UnusualDoHActivity 重要度:Medium(中) 使用可能なリージョン:一部リージョン ※ を除くGuardDutyがサポートされている全リージョン 検出ロジック:この検出は、EC2 インスタンス の通常の DNS トラフィック パターンを学習し、長期間利用していないパブリックDoHサーバへのDoH通信を警告します。 補足:DoH( DNS over HTTPS )とは、 HTTPS を用いて DNS 通信を行う技術のことです。 従来の DNS は UDP による平文でしたが、これを HTTPS の技術を使用して暗号化します。 攻撃者は、DoHを使用して通常の DNS トラフィック を脅威検知から回避することがあります。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unsualdohactivity DefenseEvasion:EC2/UnusualDoTActivity 重要度:Medium(中) 使用可能なリージョン:一部リージョン ※ を除くGuardDutyがサポートされている全リージョン 検出ロジック:この検出は、EC2 インスタンス の通常の DNS トラフィック パターンを学習し、長期間利用していないパブリックDoTサーバへのDoT通信を警告します。 補足:DoT( DNS over TLS )とは、 DNS 通信を TLS レベルで暗号化する技術のことです。 攻撃者は、DoTを使用して、通常の DNS トラフィック を脅威検知から回避することがあります。 参考: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#defenseevasion-ec2-unusualdotactivity ※ 一部リージョン: AWS アジアパシフィック(大阪), AWS アジアパシフィック( ジャカルタ ), AWS アジアパシフィック(ソウル), 中国(北京、Sinnetが運営), 中国( 寧夏 、NWCDが運営) 所感 上記3タイプはデータソースとして VPC フローログを利用しているということで、今まで検出できなかったパターンを補完するアップデートとなりました。 DoHとDoTの利用はまだ普及していないため、「DefenseEvasion:EC2/UnusualDoHActivity」が検出される機会が増えそうです。 なお、直近で通信履歴がないものに対して検知されるため、誤検知も少なからず発生する可能性はあります。 検出されたらターゲットのIPを確認し、想定された正常な動きかどうか慎重に見極めた方が良さそうです。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア(セキュリティ設計) 執筆: @fuku.dancho 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
ISID X(クロス) イノベーション 本部 の飯田です。 ブラックボックス 最適化を使って、なかなか 言語化 しにくい自分の思考パターン(好みの色)を表現する取り組みをしてみました。 ブラックボックス 最適化とOptuna ブラックボックス 最適化とは「ある関数の出力を最大化 (または最小化) するような入力を勾配情報などを使わずに探索する問題」と言われます。 参考 ある入力に対して、その出力結果だけしか取得することが出来ず、それ以外の情報が与えられないような状況で、結果を最適化(最小化・最大化)することを目的としています。 Optuna は株式会社Preferred Networksが開発しているハイパーパラメータの最適化を自動化するためのソフトウェア フレームワーク です。 optuna.org TPE (Tree-structured Parzen Estimator) 等の最適化 アルゴリズム が実装されています。 ライブラリの使い方も非常に簡単で、使いやすいと思っています。 つくったもの FastAPIで簡単な画面を作って、Optunaと組み合わせて、自分の好みの色を探してくれるWebアプリを作ってみました。 「色の好み」を ブラックボックス 関数と見立て、好みの値が最大になるような最適化をしていくイメージです。 内的な感覚(例:色の好み)の関数と見立てるという意味では、心理物理学という学問領域があります。 心理物理学は、外的な刺激と内的な感覚の対応関係を測定し、また 定量 的な計測をしようとする学問です。 「色の好み」を ブラックボックス 最適化で探る取り組みは、心理物理学に近しいものがあるかも知れません Web画面は下記のようなイメージです(今回、デザイン性は一切考慮しておりません笑) 結果 134試行を行った結果のベストパラメータは{'r': 59, 'g': 112, 'b': 160}でした。 実際に描画すると、こちらの色です。 自分の気持ちとしては、まぁまぁ合っている感じがしています。 最適化が進む様子はこんな様子でした。 コード 流れとしては、ざっくり下記のような流れです study.ask() で、過去の結果に基づいて、効率的に探索できる色を決定 FastAPI経由でHTML上で、その色を画面表示 提示された色の好みに対して点数を入力し、 API を呼びだす regist_trial(r,g,b,v)で、RGBと評価点を登録 メイン部分のコードは下記のような形です。 sampler = optuna.samplers.TPESampler(multivariate=True, n_startup_trials=10) study = optuna.create_study(direction='maximize', sampler=sampler) def regist_trial(r,g,b,v): trial = optuna.trial.create_trial( params={"r": int(r),"g": int(g),"b": int(b)}, distributions=study_search_space, value=int(v) ) study.add_trial(trial) def sugest_next_color(r,g,b,v): regist_trial(r,g,b,v) trial = study.ask() next_r = trial.suggest_int("r", 0, 255) next_g = trial.suggest_int("g",0, 255) next_b = trial.suggest_int("b",0, 255) return (next_r,next_g,next_b) 最後に Optunaは 機械学習 のハイパーパラメータ調整がまず浮かんで来ると思いますが、 ブラックボックス 最適化はいろいろな場面で有効活用できそうです。 料理や化学実験のレシピ・材料配合の最適化 システムのパラメータ調整 官能評価 などにも使えるんじゃないかと思います。 最適化が進む様子のアニメーションは見ていて気持ちいいですね。 最後に、私たちは一緒に働いてくれる仲間を募集しています! デジタル技術を社会課題解決につなげるようなプロジェクトを推進していきたいプロジェクトマネージャーやエンジニアを募集しています。 ぜひご応募ください! ソリューションアーキテクト スマートシティ導入コンサルタント/スマートシティ戦略コンサルタント 執筆: @iida.michitaka ( Shodo で執筆されました )
ISID X(クロス) イノベーション 本部 の三浦です。 筆者の関わっている案件では、コンテナ利用、 AWS Fargate利用を進めております。 AWS Fargateのお手軽さは非常に重宝しております。 しかし、そこで問題になってくるのが、管理作業(例: SQL 実行、EFSへのファイル配置)をどうするかです。 アプリケーション本体をせっかく AWS Fargateでやっているので、管理作業もできるだけサーバーレスでやりたいですよね? で、以前の記事では、『業務用の端末⇒ AWS _Fargate(ポート フォワ ード)⇒RDS』といった内容を書きました。 AWS FargateからSSMでRDSに接続 しかし、これには問題点がありまして、業務端末からのDBへの直接接続はセキュリ ティー ポリシー、データ持ち出しの観点で推奨されない場合があります。 そこで他のパターンとしては、『業務用の端末⇒ECS Exec(コンテナにログイン)⇒RDS』といった手段があるのですが、これには下記のような課題があります。 コンテナ内に本来不要なDB接続用のライブラリのインストールが必要 巨大な結果セットを返すような不適切な SQL 実行時にECSタスクのリソース(例:メモリ)を使用してしまいサービスによくない影響が出る コンテナ内に入ってオペレーションするのは、セキュリ ティー 的に望ましくない場合がある コンテナに本来不要なオペレーション用の権限をつけなければならない場合がある(例:データ授受用のs3へのアクセス権) ということで、業務用端末からDBへ直接接続せず、下記のようにセキュアな AWS CloudShellから下記のような経路で接続できないか試します。 『業務用の端末⇒ AWS CloudShell⇒ AWS Fargate(ポート フォワ ード)⇒RDS』 目次 目次 接続失敗編 接続成功編 接続失敗編 下記のように普通にフロントでstart-sessionするとstart-sessionのプロセスがフロントに残ることでそのままでは使えません。 ローカルならば他のターミナルを開いてそちらでDB接続のコマンドを実行すればいいのですが、 AWS CloudShellではそれができません。 aws ssm start-session \ --target ecs:${clusterID}_${taskid}_${CONTAINER_ID} \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters "{\"host\":[\"XXXXXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" 接続成功編 しかし、下記のようにstart-sessionをバックグランド実行することにより AWS CloudShellからポート フォワ ードして、RDSに接続可能です。 (aws ssm start-session \ --target ecs:${clusterID}_${taskid}_${CONTAINER_ID} \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters "{\"host\":[\"xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" \ \ )& \ export PGPASSWORD=xxxxxxxxx psql -U userName -p 5432 -h localhost 終了処理は下記の「ps + kill」で可能です。 ということで、ちょっとした工夫で AWS CloudShellからRDSにポート フォワ ードで接続できるという内容でした。 執筆: @miura.toshihiko 、レビュー: 寺山 輝 (@terayama.akira) ( Shodo で執筆されました )
ISID X(クロス) イノベーション 本部 の三浦です。 筆者の関わっている案件では、コンテナ利用、 AWS Fargate利用を進めております。 AWS Fargateのお手軽さは非常に重宝しております。 しかし、そこで問題になってくるのが、管理作業(例: SQL 実行、EFSへのファイル配置)をどうするかです。 アプリケーション本体をせっかく AWS Fargateでやっているので、管理作業もできるだけサーバーレスでやりたいですよね? で、以前の記事では、『業務用の端末⇒ AWS _Fargate(ポート フォワ ード)⇒RDS』といった内容を書きました。 AWS FargateからSSMでRDSに接続 しかし、これには問題点がありまして、業務端末からのDBへの直接接続はセキュリ ティー ポリシー、データ持ち出しの観点で推奨されない場合があります。 そこで他のパターンとしては、『業務用の端末⇒ECS Exec(コンテナにログイン)⇒RDS』といった手段があるのですが、これには下記のような課題があります。 コンテナ内に本来不要なDB接続用のライブラリのインストールが必要 巨大な結果セットを返すような不適切な SQL 実行時にECSタスクのリソース(例:メモリ)を使用してしまいサービスによくない影響が出る コンテナ内に入ってオペレーションするのは、セキュリ ティー 的に望ましくない場合がある コンテナに本来不要なオペレーション用の権限をつけなければならない場合がある(例:データ授受用のs3へのアクセス権) ということで、業務用端末からDBへ直接接続せず、下記のようにセキュアな AWS CloudShellから下記のような経路で接続できないか試します。 『業務用の端末⇒ AWS CloudShell⇒ AWS Fargate(ポート フォワ ード)⇒RDS』 目次 目次 接続失敗編 接続成功編 接続失敗編 下記のように普通にフロントでstart-sessionするとstart-sessionのプロセスがフロントに残ることでそのままでは使えません。 ローカルならば他のターミナルを開いてそちらでDB接続のコマンドを実行すればいいのですが、 AWS CloudShellではそれができません。 aws ssm start-session \ --target ecs:${clusterID}_${taskid}_${CONTAINER_ID} \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters "{\"host\":[\"XXXXXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" 接続成功編 しかし、下記のようにstart-sessionをバックグランド実行することにより AWS CloudShellからポート フォワ ードして、RDSに接続可能です。 (aws ssm start-session \ --target ecs:${clusterID}_${taskid}_${CONTAINER_ID} \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters "{\"host\":[\"xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" \ \ )& \ export PGPASSWORD=xxxxxxxxx psql -U userName -p 5432 -h localhost 終了処理は下記の「ps + kill」で可能です。 ということで、ちょっとした工夫で AWS CloudShellからRDSにポート フォワ ードで接続できるという内容でした。 執筆: @miura.toshihiko 、レビュー: 寺山 輝 (@terayama.akira) ( Shodo で執筆されました )
ISID X(クロス) イノベーション 本部 の飯田です。 ブラックボックス 最適化を使って、なかなか 言語化 しにくい自分の思考パターン(好みの色)を表現する取り組みをしてみました。 ブラックボックス 最適化とOptuna ブラックボックス 最適化とは「ある関数の出力を最大化 (または最小化) するような入力を勾配情報などを使わずに探索する問題」と言われます。 参考 ある入力に対して、その出力結果だけしか取得することが出来ず、それ以外の情報が与えられないような状況で、結果を最適化(最小化・最大化)することを目的としています。 Optuna は株式会社Preferred Networksが開発しているハイパーパラメータの最適化を自動化するためのソフトウェア フレームワーク です。 optuna.org TPE (Tree-structured Parzen Estimator) 等の最適化 アルゴリズム が実装されています。 ライブラリの使い方も非常に簡単で、使いやすいと思っています。 つくったもの FastAPIで簡単な画面を作って、Optunaと組み合わせて、自分の好みの色を探してくれるWebアプリを作ってみました。 「色の好み」を ブラックボックス 関数と見立て、好みの値が最大になるような最適化をしていくイメージです。 内的な感覚(例:色の好み)の関数と見立てるという意味では、心理物理学という学問領域があります。 心理物理学は、外的な刺激と内的な感覚の対応関係を測定し、また 定量 的な計測をしようとする学問です。 「色の好み」を ブラックボックス 最適化で探る取り組みは、心理物理学に近しいものがあるかも知れません Web画面は下記のようなイメージです(今回、デザイン性は一切考慮しておりません笑) 結果 134試行を行った結果のベストパラメータは{'r': 59, 'g': 112, 'b': 160}でした。 実際に描画すると、こちらの色です。 自分の気持ちとしては、まぁまぁ合っている感じがしています。 最適化が進む様子はこんな様子でした。 コード 流れとしては、ざっくり下記のような流れです study.ask() で、過去の結果に基づいて、効率的に探索できる色を決定 FastAPI経由でHTML上で、その色を画面表示 提示された色の好みに対して点数を入力し、 API を呼びだす regist_trial(r,g,b,v)で、RGBと評価点を登録 メイン部分のコードは下記のような形です。 sampler = optuna.samplers.TPESampler(multivariate=True, n_startup_trials=10) study = optuna.create_study(direction='maximize', sampler=sampler) def regist_trial(r,g,b,v): trial = optuna.trial.create_trial( params={"r": int(r),"g": int(g),"b": int(b)}, distributions=study_search_space, value=int(v) ) study.add_trial(trial) def sugest_next_color(r,g,b,v): regist_trial(r,g,b,v) trial = study.ask() next_r = trial.suggest_int("r", 0, 255) next_g = trial.suggest_int("g",0, 255) next_b = trial.suggest_int("b",0, 255) return (next_r,next_g,next_b) 最後に Optunaは 機械学習 のハイパーパラメータ調整がまず浮かんで来ると思いますが、 ブラックボックス 最適化はいろいろな場面で有効活用できそうです。 料理や化学実験のレシピ・材料配合の最適化 システムのパラメータ調整 官能評価 などにも使えるんじゃないかと思います。 最適化が進む様子のアニメーションは見ていて気持ちいいですね。 最後に、私たちは一緒に働いてくれる仲間を募集しています! デジタル技術を社会課題解決につなげるようなプロジェクトを推進していきたいプロジェクトマネージャーやエンジニアを募集しています。 ぜひご応募ください! ソリューションアーキテクト スマートシティ導入コンサルタント/スマートシティ戦略コンサルタント 執筆: @iida.michitaka ( Shodo で執筆されました )
こんにちは。ISID 金融ソリューション事業部の若本です。 生成系の画像/ 自然言語処理 AIが盛り上がりを見せる中、既存ソフトウェアへの組み込みや連携も活発に行われるようになってきました。 3DCG制作アプリケーションである Blender でも、アドオンを通じて Blender 内でAIが使いやすくなりつつあります。先日、diffusionが使用できるアドオンである「Stability for Blender 」がリリースされたのもその一例です。 今回はStability for Blender を用いてできることと、その手順をまとめます。 Stability for Blender について Stable Diffusionの開発を行っているStability AI社が提供する、 Blender 用のアドオン※です。 筆者は実施時点で最新であったv0.0.15をインストールして実施しました。v0.0.15時点の機能としては下記の3つがあります。 文章から画像生成 文章からテクスチャを生成する 画像から画像生成 Renderingから画像を生成する テクスチャからテクスチャを生成する 画像からアニメーション生成 Renderingからアニメーションを生成 DreamStudio (β版)に登録し、 API keyを発行する必要があります。 DreamStudioでは登録時に100creditほど使用可能になりますが、画像を生成するたびにcreditを消費していきますのでご注意ください。なお、 API keyとcreditともにDreamStudioのMy Accountから確認可能です。 ※Blender3.0以降がサポートされています。 Stability for blender を使ってみる stability for blender で出力するまでの一連の流れを説明します( Blender そのもののインストールは割愛します)。 公式サイト を参考に実施しました。 事前準備 リリースページ からアドオンのzipファイルをダウンロードします。前述の通り、筆者はv0.0.15をインストールしています。 blender を開き、メニューの「Edit>preferences>add-ons」を開きます。 右上部の「Install...」ボタンを押すとフォルダ エクスプローラ ーが開くので、先ほどダウンロードしたzipファイルを選択します。選択後、以下のような画面になっていればOKです。 画面に「Stability」のタブが表示されていればインストール完了となります。 DreamStudio (β版)に登録し、 API keyを取得します。 「Stability」のタブに API keyを入力すると以下のような画面になります。これで実施する準備が整いました。 文章からテクスチャを生成する Blender 上で与えた文章から画像を生成してみます。 まず、「init Type」の「Text Prompt Only」を選択します。 次に、promptの入力ボックスに欲しい画像を英語で指示します。今回は最初からデフォルトで設定されている下記promptをそのまま使用しました。 A dream of a distant galaxy 後は「Dream」を押下するだけで実行されます。 消費creditも併せて表示されるのは親切ですね。 10秒足らずで画像が生成されました。非常にお手軽です。 もちろん、生成した画像はテクスチャとしてそのまま使用できます。 Renderingから画像を生成する 画像から画像を生成する例として、Renderingの結果から画像を生成してみます。 まずは「init Type」の「Texture」を選択します。 メニューから「Render>Render image」を押下すると、新規ウィンドウでRenderingが実行されます。 カメラを設定している以前の記事のプロジェクトを使用しました。 Rendering画面からStabilityを実行します。 promptは以下としました。 An empty park with snow, concept art, matte painting, HQ, 4k 前述の通り、「Dream」を押下することで画像が生成されます。 Blender 上で見える景色をベースに画像を生成することができました。 ここで、「Stability」タブの「input Options」から各種パラメータを設定できます。 パラメータ名 概要 default Init Strength 入力画像にどれだけ準拠するかを設定します。 0.5 Prompt Strength プロンプトにどれだけ準拠するかを設定します。 7.5 Set seed Stable Diffusionのseedを設定します。seedを変えると異なる画像が出力されます。 555555 Steps Stable DiffusionのStep数を設定します。 50 Engine 使用するStable Diffusionモデルを設定します。(あくまで推測ですが、GENERATE_512_2_1は解像度512pixelで Stable diffusion ver2.1 を表していると思われます) GENERATE_512_2_1 Sampler Stable DiffusionのSampler(ノイズ除去 アルゴリズム )を設定します。 K_DPMPP_2S_ANCESTRAL 主に出力の品質や、入力のバランス(文章と画像の情報どちらを優先するか)に関するパラメータが設定できます。ここでは、「Init strength」を変更してみます。 「Init strength」を変化させると以下のようになります。 「Init strength」を大きくするほど、Renderingされた情報に準拠するような画像の生成がされました。 一方で、小さくするほどpromptの「An empty park with snow」が重視され、元々置いていたオブジェクトは別のものに解釈される/消えることが確認できました。 ※今回、Renderingからアニメーション生成の手順も実施しましたが、数時間経過しても処理が進まず断念しました。 おわりに 今回はStability for Blender の利用手順とできることを調査しました。 執筆時点でv0.0.16も公開されており、「高解像度化」が新たに機能として追加されるなど、活発に開発が続けられています。今後より使いやすく、かつ機能を拡充していくことでクリエイター支援ツールとして活用されることが期待されます。 AIモデルの3DCGソフトウェアへの組み込みは今後も様々な形で発展していくと思いますので、今後もキャッチアップしていきたいと思います。 ここまでお読みいただきありがとうございました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ 執筆: @wakamoto.ryosuke 、レビュー: @yamada.y ( Shodo で執筆されました )
こんにちは。ISID 金融ソリューション事業部の若本です。 生成系の画像/ 自然言語処理 AIが盛り上がりを見せる中、既存ソフトウェアへの組み込みや連携も活発に行われるようになってきました。 3DCG制作アプリケーションである Blender でも、アドオンを通じて Blender 内でAIが使いやすくなりつつあります。先日、diffusionが使用できるアドオンである「Stability for Blender 」がリリースされたのもその一例です。 今回はStability for Blender を用いてできることと、その手順をまとめます。 Stability for Blender について Stable Diffusionの開発を行っているStability AI社が提供する、 Blender 用のアドオン※です。 筆者は実施時点で最新であったv0.0.15をインストールして実施しました。v0.0.15時点の機能としては下記の3つがあります。 文章から画像生成 文章からテクスチャを生成する 画像から画像生成 Renderingから画像を生成する テクスチャからテクスチャを生成する 画像からアニメーション生成 Renderingからアニメーションを生成 DreamStudio (β版)に登録し、 API keyを発行する必要があります。 DreamStudioでは登録時に100creditほど使用可能になりますが、画像を生成するたびにcreditを消費していきますのでご注意ください。なお、 API keyとcreditともにDreamStudioのMy Accountから確認可能です。 ※Blender3.0以降がサポートされています。 Stability for blender を使ってみる stability for blender で出力するまでの一連の流れを説明します( Blender そのもののインストールは割愛します)。 公式サイト を参考に実施しました。 事前準備 リリースページ からアドオンのzipファイルをダウンロードします。前述の通り、筆者はv0.0.15をインストールしています。 blender を開き、メニューの「Edit>preferences>add-ons」を開きます。 右上部の「Install...」ボタンを押すとフォルダ エクスプローラ ーが開くので、先ほどダウンロードしたzipファイルを選択します。選択後、以下のような画面になっていればOKです。 画面に「Stability」のタブが表示されていればインストール完了となります。 DreamStudio (β版)に登録し、 API keyを取得します。 「Stability」のタブに API keyを入力すると以下のような画面になります。これで実施する準備が整いました。 文章からテクスチャを生成する Blender 上で与えた文章から画像を生成してみます。 まず、「init Type」の「Text Prompt Only」を選択します。 次に、promptの入力ボックスに欲しい画像を英語で指示します。今回は最初からデフォルトで設定されている下記promptをそのまま使用しました。 A dream of a distant galaxy 後は「Dream」を押下するだけで実行されます。 消費creditも併せて表示されるのは親切ですね。 10秒足らずで画像が生成されました。非常にお手軽です。 もちろん、生成した画像はテクスチャとしてそのまま使用できます。 Renderingから画像を生成する 画像から画像を生成する例として、Renderingの結果から画像を生成してみます。 まずは「init Type」の「Texture」を選択します。 メニューから「Render>Render image」を押下すると、新規ウィンドウでRenderingが実行されます。 カメラを設定している以前の記事のプロジェクトを使用しました。 Rendering画面からStabilityを実行します。 promptは以下としました。 An empty park with snow, concept art, matte painting, HQ, 4k 前述の通り、「Dream」を押下することで画像が生成されます。 Blender 上で見える景色をベースに画像を生成することができました。 ここで、「Stability」タブの「input Options」から各種パラメータを設定できます。 パラメータ名 概要 default Init Strength 入力画像にどれだけ準拠するかを設定します。 0.5 Prompt Strength プロンプトにどれだけ準拠するかを設定します。 7.5 Set seed Stable Diffusionのseedを設定します。seedを変えると異なる画像が出力されます。 555555 Steps Stable DiffusionのStep数を設定します。 50 Engine 使用するStable Diffusionモデルを設定します。(あくまで推測ですが、GENERATE_512_2_1は解像度512pixelで Stable diffusion ver2.1 を表していると思われます) GENERATE_512_2_1 Sampler Stable DiffusionのSampler(ノイズ除去 アルゴリズム )を設定します。 K_DPMPP_2S_ANCESTRAL 主に出力の品質や、入力のバランス(文章と画像の情報どちらを優先するか)に関するパラメータが設定できます。ここでは、「Init strength」を変更してみます。 「Init strength」を変化させると以下のようになります。 「Init strength」を大きくするほど、Renderingされた情報に準拠するような画像の生成がされました。 一方で、小さくするほどpromptの「An empty park with snow」が重視され、元々置いていたオブジェクトは別のものに解釈される/消えることが確認できました。 ※今回、Renderingからアニメーション生成の手順も実施しましたが、数時間経過しても処理が進まず断念しました。 おわりに 今回はStability for Blender の利用手順とできることを調査しました。 執筆時点でv0.0.16も公開されており、「高解像度化」が新たに機能として追加されるなど、活発に開発が続けられています。今後より使いやすく、かつ機能を拡充していくことでクリエイター支援ツールとして活用されることが期待されます。 AIモデルの3DCGソフトウェアへの組み込みは今後も様々な形で発展していくと思いますので、今後もキャッチアップしていきたいと思います。 ここまでお読みいただきありがとうございました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ 執筆: @wakamoto.ryosuke 、レビュー: @yamada.y ( Shodo で執筆されました )
(画像: Basic Theory of Physically-Based Rendering ) こんにちは!金融ソリューション事業部の山下です。 今回は、近年進化が目覚ましい3DCGグラフィックスのクオリティを支えるPBR(Physical Based Rendering)について紹介します。 本記事では、入門編としてPBRの基礎理論やワークフローを紹介します。 また応用編として、 Substance 3Dや Unreal Engine を用いた制作フローを紹介する記事も別途執筆予定です。 PBRマテリアルの生成事例については、 Substance Samplerを用いたこちらの記事 でも紹介しているので、ぜひご覧ください。 1. PBRとは? 2. PBRの基礎理論 2-1. エネルギー保存の法則:拡散(Diffuse)と鏡面(Specular)反射 2-2. 金属(Metal)と非金属(Non-Metal) 2-3. 吸収(Absorption)と散乱(Scattering) 2-4. フレネル効果(Fresnel Effect) 2-5. マイクロファセット理論 3. PBRにおける主要ワークフロー 3-1. Metal - Roughness 3-2. Specular - Glossiness 4. 各テクスチャマップの概要(Metallic/Roughnessワークフロー) 4-1. BaseColor(Albedo)Map 4-2. Metallic(金属度)Map 4-3. Roughness(粗さ)Map 4-4. Normal(法線)Map 4-5. Ambient Occlusion(環境遮蔽)Map 4-6. Height(高さ)Map 4-7. Specluar Level(鏡面反射レベル)Map まとめ 参考 1. PBRとは? PBR(Physical Based Rendering)とは、現実世界の光の振る舞いを近似させる3DCG レンダリング 手法です。 従来の レンダリング 手法では、物理原則に基づかない比較的シンプルな近似を行う「 Lambert反射モデル 」や「 Blinn–Phong反射モデル 」が採用されていました。 PBRの原理に沿ったマテリアルを使用することにより、リアルな質感や照明をシミュレートしてより正確かつ自然な見た目を実現できます。 PBRの活用は、2000年~2010年代にゲームや映画業界から始まりました。 GPU ハードウェアやGraphic API 、リアルタイム レンダリング 技術の進化に伴い普及が進んだ結果、現在では主要な3Dファイル形式( glTF 、 FBX など)においてもPBRパラメータが採用されています。 一点誤解されやすい点を補足しますと、PBRはトゥーン レンダリング やNPR(非フォトリアル レンダリング )などアニメ調の作品においても有効に機能する技術です。そのため、PBRは Pixar やDisneyの映画でも採用されています。 (画像: SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice ) 2. PBRの基礎理論 現実世界における光の挙動を再現するための主要な原理/法則について、以下、概要のみ紹介します。 2-1. エネルギー保存の法則 :拡散(Diffuse)と鏡面(Specular)反射 エネルギー保存の法則 は、物理学においてエネルギーが変換される過程でその総量が一定であることを示す基本原則です。 PBRにおいては、光の反射や散乱に関する計算手法( BRDF:Bidirectional Reflectance Distribution Function など)においてこの法則が適用されています。 具体的には、入射光が物体の表面に当たる際、光のエネルギーは以下2つに分散します。 拡散(Diffuse)反射光:物体の内部で散乱され、再び表面から放出される光。物体によって吸収/放出される光の波長が異なる。その結果、物体の色が異なって見える。 鏡面(Specular)反射光:物体の表面から反射される光。完全な平面では入射角と反射角が等しくなる。物体表面が滑らかなほどハイライトは小さく明るくなり、粗いほど大きく暗くなる。 (画像: Basic Theory of Physically-Based Rendering ) この法則に基づき、PBRでは「反射光の総エネルギーは、入射光のエネルギーと等しい」という現実世界の光の挙動を再現しています。 2-2. 金属(Metal)と非金属(Non-Metal) PBRマテリアルにおいて、「金属か非金属か」という観点は非常に重要になります。 表面が金属の場合、鏡面反射が強調されて拡散反射はほとんど存在しません。これにより、金属表面は光沢感が強く、反射が明確に現れます。一方、非金属の場合、鏡面反射は比較的弱くなり、逆に拡散反射の影響が強まります。 また、鏡面反射の色は、金属の場合は金属自体の色で染まります。一方、非金属の場合、鏡面反射はほとんど白に近い色になります。 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) 2-3. 吸収(Absorption)と散乱(Scattering) 吸収は、物体が光を吸収する現象です。吸収された光は一般的には物体内部で熱エネルギーに変換されます。 散乱は、光が物体内部や表面で乱反射される現象です。 半透明な物体では、光が物体の内部で散乱した後に表面から出てくる現象(SSS:Subsurface Scattering)が発生します。特にこの現象は、人肌や大理石、ろうそくや乳製品などで顕著に現れます。 (画像: Wikipedia: Subsurface scattering) ) 2-4. フレネル効果(Fresnel Effect) (画像: Fresnel Reflection and Fresnel Reflection Modes Explained ) フレネル効果は、光が物体の表面と交差する角度によって、その反射率が変化する現象です。 例えば、上記画像のように水面を上から見下ろした際、近い部分(視線と物体表面の角度が大きい)では水面の底が透けて見えます。一方で遠い部分(視線と物体表面の角度が小さい)では、完全に反射光しか見えません。 つまり、視線と物体の表面となす角度が小さいほど(鋭い角度で見るほど)、反射率が高くなります。 このフレネル効果は、水だけでなく布や木などの物体にも全て発生します。 PBRではフレネル効果を考慮することで、物体表面の光沢感や金属質感を表現します。 (参考: THE PBR GUIDE BY ALLEGORITHMIC ) DCCツールにおいては、上記の通り正面から垂直に物体を捉えた点の反射率を「F0」として扱います。このF0は、物体のIOR(屈折率)によって一意に導き出すことができます。 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) また、F0は一般的な非金属で2~5%程度、金属では60~70%程度となっており、いずれも側面における反射率はほぼ100%となります。 2-5. マイクロファセット理論 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) マイクロファセット理論は、物体の表面を無数の微小な平面(マイクロファセット)の集合として扱う理論です。 マイクロファセットはそれぞれ異なる向きを持っているため、光はそれぞれ異なる方向に反射されます。物体表面全体における反射は、各マイクロファセットによる反射の合成として計算されます。 PBRでは、物体表面の粗さ(Roughness)や凹凸(Normal)といったテクスチャマップを用いることで、メッシュよりも細かい単位の光の散乱や反射を計算します。 3. PBRにおける主要ワークフロー PBRマテリアルを作成/利用する場合、Metallic/RoughnessとSpecular/Glossinessという2つのワークフローが主流です。 3-1. Metal - Roughness テクスチャマップによって「金属度」と「粗さ」を制御するワークフローです。 メリット 調整が直感的であり、シンプル。鏡面反射のマップを持たずF0値のデフォルトが設定される為、非金属における反射率の設定破綻がしにくい(物理的にありえない値にはなりにくい) 比較的、テクスチャのメモリ使用量が少ない(1 RGB:Albedo) ほとんどのDCCツールで採用されている デメリット F0値のコン トロール ができない。(※ UEではSpecular Inputが用意されている為デフォルト値からの調整が可能) 金属度マップは原則バイナリ値で表す為、低解像度の場合にテクスチャ補完によってEdge Artifactが発生しやすい 3-2. Specular - Glossiness テクスチャマップで「鏡面反射」と「光沢度」を制御するワークフローです。 メリット Specular MapにてF0値のコン トロール がしやすい 比較的、Edge artifactが発生しにくい デメリット 調整が難しい(F0値が物理法則的に破綻する可能性がある) 比較的、テクスチャのメモリ使用量が多い(2 RGB:Albedo, Specular) どちらのワークフローもそれぞれの利点があり用途や好みに応じて選択されますが、本記事では Unreal Engine でも採用されているMetallic/Roughnessワークフローに沿って説明します。 4. 各テクスチャマップの概要(Metallic/Roughnessワークフロー) PBRワークフローでは、複数の画像素材(テクスチャマップ)を用いてマテリアルを表現します。 各テクスチャ素材をDCCツールや ゲームエンジン において適切に組み合わせることで、PBRの表現が可能になります。 各マップにおけるテクスチャのサンプル画像は、 こちらの記事 にて、 Substance Samplerを用いて生成したこちらのマテリアルを使用します。 マテリアルの完成系は、こちらです。 4-1. BaseColor(Albedo)Map 物体の基本色を表すマップです。RGB( Vector 3)で、0~1の値として表します。 従来のカラーマップとは異なり光の影響や陰影、反射などは含まれていないため、Albedoマップは明るい色調になることが特徴です。 実際のテクスチャ制作ではDCCツールを用いる手法のほか、カメラと偏光フィルターを用いた撮影による制作手法などがあります。 4-2. Metallic(金属度)Map 表面の金属性を表すマップです。 グレースケールで、通常は黒か白かの2値のみで表現します(0が非金属、1が金属)。 今回のサンプル画像は非金属のため、黒一色となります。 白(値が高い)が金属、黒(値が低い)が非金属を示します。 金属マップは、物体の反射特性を制御し、金属質感や非金属質感を区別する役割があります。 4-3. Roughness(粗さ)Map 物体の表面の粗さを表すマップです。0~1のグレースケール値で表します(0がつるつる、1がざらざら)。 粗いほど表面がざらつき、光の散乱が大きくなります。 3Dモデルの表面の粗さを表現します。白(値が高い)は粗い表面、黒(値が低い)は滑らかな表面を示します。 粗さマップは、光の反射や散乱の度合いを制御し、質感や光沢感を調整する役割があります。 4-4. Normal(法線)Map 物体の表面の微細な凹凸を表すマップです。RGB( Vector 3)で表し、RGBがXYZ座標に対応するベクトルとして扱います。 RGB値によって、各 ピクセル の表面法線の向きが定義されています。 法線マップは、モデルのポリゴン数を増やさずにディテールを追加することができ、リアルな質感や陰影を表現する役割があります。これにより、高解像度のジオメトリを持たないモデルでも、細かいディテールを表現できます。 4-5. Ambient Occlusion(環境遮蔽)Map 表面の自然な陰影を表現するマップです。0~1のグレースケール値(0が遮蔽された黒、1が露出していて白)で表します。 表面の凹凸によって遮られる環境光を表現します。これにより、物体同士が接近している部分や凹んでいる部分に影ができ、リアルな陰影が表現されます。 4-6. Height(高さ)Map 物体表面の高低差を表すマップです。0~1のグレイスケール値(0が低く、1が高い)で高さを表します。 レンダリング を行う際に、高さの単位(ユニット)を設定する必要があります。 4-7. Specluar Level(鏡面反射レベル)Map 非金属物体に対する鏡面反射の係数を表すマップです。 UEではデフォルト値が0.5(F0が4%)として設定されていますが、この係数を調整できます。 Specular - GlossinessワークフローにおけるSpecular Mapとは異なる点についてご注意ください。 まとめ いかがでしたでしょうか。 近年では、人肌や大理石など物体表面内部に浸透する光の振る舞いを表現する SSS(サブサーフェススキャタリング) や、幅広いレンジの明るさ情報を用いる HDRI(ハイダイナミックレンジイメージ) など、様々な新しい技術が開発されています。 さらに、Unreal Engine5など ゲームエンジン の進化も伴うことで「現実と見紛う」レベルの3DCGがリアルタイム レンダリング 可能になっており、今後も3DCG技術の進化と ユースケース に目が離せません。 次回からは応用編として、 Substance Designerを用いたPBRマテリアルの制作や、 Unreal Engine における レンダリング 方法について紹介してきたいと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Basic Theory of Physically-Based Rendering SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice THE PBR GUIDE BY ALLEGORITHMIC 執筆: @yamashita.yuki 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
(画像: Basic Theory of Physically-Based Rendering ) こんにちは!金融ソリューション事業部の山下です。 今回は、近年進化が目覚ましい3DCGグラフィックスのクオリティを支えるPBR(Physical Based Rendering)について紹介します。 本記事では、入門編としてPBRの基礎理論やワークフローを紹介します。 また応用編として、 Substance 3Dや Unreal Engine を用いた制作フローを紹介する記事も別途執筆予定です。 PBRマテリアルの生成事例については、 Substance Samplerを用いたこちらの記事 でも紹介しているので、ぜひご覧ください。 1. PBRとは? 2. PBRの基礎理論 2-1. エネルギー保存の法則:拡散(Diffuse)と鏡面(Specular)反射 2-2. 金属(Metal)と非金属(Non-Metal) 2-3. 吸収(Absorption)と散乱(Scattering) 2-4. フレネル効果(Fresnel Effect) 2-5. マイクロファセット理論 3. PBRにおける主要ワークフロー 3-1. Metal - Roughness 3-2. Specular - Glossiness 4. 各テクスチャマップの概要(Metallic/Roughnessワークフロー) 4-1. BaseColor(Albedo)Map 4-2. Metallic(金属度)Map 4-3. Roughness(粗さ)Map 4-4. Normal(法線)Map 4-5. Ambient Occlusion(環境遮蔽)Map 4-6. Height(高さ)Map 4-7. Specluar Level(鏡面反射レベル)Map まとめ 参考 1. PBRとは? PBR(Physical Based Rendering)とは、現実世界の光の振る舞いを近似させる3DCG レンダリング 手法です。 従来の レンダリング 手法では、物理原則に基づかない比較的シンプルな近似を行う「 Lambert反射モデル 」や「 Blinn–Phong反射モデル 」が採用されていました。 PBRの原理に沿ったマテリアルを使用することにより、リアルな質感や照明をシミュレートしてより正確かつ自然な見た目を実現できます。 PBRの活用は、2000年~2010年代にゲームや映画業界から始まりました。 GPU ハードウェアやGraphic API 、リアルタイム レンダリング 技術の進化に伴い普及が進んだ結果、現在では主要な3Dファイル形式( glTF 、 FBX など)においてもPBRパラメータが採用されています。 一点誤解されやすい点を補足しますと、PBRはトゥーン レンダリング やNPR(非フォトリアル レンダリング )などアニメ調の作品においても有効に機能する技術です。そのため、PBRは Pixar やDisneyの映画でも採用されています。 (画像: SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice ) 2. PBRの基礎理論 現実世界における光の挙動を再現するための主要な原理/法則について、以下、概要のみ紹介します。 2-1. エネルギー保存の法則 :拡散(Diffuse)と鏡面(Specular)反射 エネルギー保存の法則 は、物理学においてエネルギーが変換される過程でその総量が一定であることを示す基本原則です。 PBRにおいては、光の反射や散乱に関する計算手法( BRDF:Bidirectional Reflectance Distribution Function など)においてこの法則が適用されています。 具体的には、入射光が物体の表面に当たる際、光のエネルギーは以下2つに分散します。 拡散(Diffuse)反射光:物体の内部で散乱され、再び表面から放出される光。物体によって吸収/放出される光の波長が異なる。その結果、物体の色が異なって見える。 鏡面(Specular)反射光:物体の表面から反射される光。完全な平面では入射角と反射角が等しくなる。物体表面が滑らかなほどハイライトは小さく明るくなり、粗いほど大きく暗くなる。 (画像: Basic Theory of Physically-Based Rendering ) この法則に基づき、PBRでは「反射光の総エネルギーは、入射光のエネルギーと等しい」という現実世界の光の挙動を再現しています。 2-2. 金属(Metal)と非金属(Non-Metal) PBRマテリアルにおいて、「金属か非金属か」という観点は非常に重要になります。 表面が金属の場合、鏡面反射が強調されて拡散反射はほとんど存在しません。これにより、金属表面は光沢感が強く、反射が明確に現れます。一方、非金属の場合、鏡面反射は比較的弱くなり、逆に拡散反射の影響が強まります。 また、鏡面反射の色は、金属の場合は金属自体の色で染まります。一方、非金属の場合、鏡面反射はほとんど白に近い色になります。 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) 2-3. 吸収(Absorption)と散乱(Scattering) 吸収は、物体が光を吸収する現象です。吸収された光は一般的には物体内部で熱エネルギーに変換されます。 散乱は、光が物体内部や表面で乱反射される現象です。 半透明な物体では、光が物体の内部で散乱した後に表面から出てくる現象(SSS:Subsurface Scattering)が発生します。特にこの現象は、人肌や大理石、ろうそくや乳製品などで顕著に現れます。 (画像: Wikipedia: Subsurface scattering) ) 2-4. フレネル効果(Fresnel Effect) (画像: Fresnel Reflection and Fresnel Reflection Modes Explained ) フレネル効果は、光が物体の表面と交差する角度によって、その反射率が変化する現象です。 例えば、上記画像のように水面を上から見下ろした際、近い部分(視線と物体表面の角度が大きい)では水面の底が透けて見えます。一方で遠い部分(視線と物体表面の角度が小さい)では、完全に反射光しか見えません。 つまり、視線と物体の表面となす角度が小さいほど(鋭い角度で見るほど)、反射率が高くなります。 このフレネル効果は、水だけでなく布や木などの物体にも全て発生します。 PBRではフレネル効果を考慮することで、物体表面の光沢感や金属質感を表現します。 (参考: THE PBR GUIDE BY ALLEGORITHMIC ) DCCツールにおいては、上記の通り正面から垂直に物体を捉えた点の反射率を「F0」として扱います。このF0は、物体のIOR(屈折率)によって一意に導き出すことができます。 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) また、F0は一般的な非金属で2~5%程度、金属では60~70%程度となっており、いずれも側面における反射率はほぼ100%となります。 2-5. マイクロファセット理論 (画像: THE PBR GUIDE BY ALLEGORITHMIC ) マイクロファセット理論は、物体の表面を無数の微小な平面(マイクロファセット)の集合として扱う理論です。 マイクロファセットはそれぞれ異なる向きを持っているため、光はそれぞれ異なる方向に反射されます。物体表面全体における反射は、各マイクロファセットによる反射の合成として計算されます。 PBRでは、物体表面の粗さ(Roughness)や凹凸(Normal)といったテクスチャマップを用いることで、メッシュよりも細かい単位の光の散乱や反射を計算します。 3. PBRにおける主要ワークフロー PBRマテリアルを作成/利用する場合、Metallic/RoughnessとSpecular/Glossinessという2つのワークフローが主流です。 3-1. Metal - Roughness テクスチャマップによって「金属度」と「粗さ」を制御するワークフローです。 メリット 調整が直感的であり、シンプル。鏡面反射のマップを持たずF0値のデフォルトが設定される為、非金属における反射率の設定破綻がしにくい(物理的にありえない値にはなりにくい) 比較的、テクスチャのメモリ使用量が少ない(1 RGB:Albedo) ほとんどのDCCツールで採用されている デメリット F0値のコン トロール ができない。(※ UEではSpecular Inputが用意されている為デフォルト値からの調整が可能) 金属度マップは原則バイナリ値で表す為、低解像度の場合にテクスチャ補完によってEdge Artifactが発生しやすい 3-2. Specular - Glossiness テクスチャマップで「鏡面反射」と「光沢度」を制御するワークフローです。 メリット Specular MapにてF0値のコン トロール がしやすい 比較的、Edge artifactが発生しにくい デメリット 調整が難しい(F0値が物理法則的に破綻する可能性がある) 比較的、テクスチャのメモリ使用量が多い(2 RGB:Albedo, Specular) どちらのワークフローもそれぞれの利点があり用途や好みに応じて選択されますが、本記事では Unreal Engine でも採用されているMetallic/Roughnessワークフローに沿って説明します。 4. 各テクスチャマップの概要(Metallic/Roughnessワークフロー) PBRワークフローでは、複数の画像素材(テクスチャマップ)を用いてマテリアルを表現します。 各テクスチャ素材をDCCツールや ゲームエンジン において適切に組み合わせることで、PBRの表現が可能になります。 各マップにおけるテクスチャのサンプル画像は、 こちらの記事 にて、 Substance Samplerを用いて生成したこちらのマテリアルを使用します。 マテリアルの完成系は、こちらです。 4-1. BaseColor(Albedo)Map 物体の基本色を表すマップです。RGB( Vector 3)で、0~1の値として表します。 従来のカラーマップとは異なり光の影響や陰影、反射などは含まれていないため、Albedoマップは明るい色調になることが特徴です。 実際のテクスチャ制作ではDCCツールを用いる手法のほか、カメラと偏光フィルターを用いた撮影による制作手法などがあります。 4-2. Metallic(金属度)Map 表面の金属性を表すマップです。 グレースケールで、通常は黒か白かの2値のみで表現します(0が非金属、1が金属)。 今回のサンプル画像は非金属のため、黒一色となります。 白(値が高い)が金属、黒(値が低い)が非金属を示します。 金属マップは、物体の反射特性を制御し、金属質感や非金属質感を区別する役割があります。 4-3. Roughness(粗さ)Map 物体の表面の粗さを表すマップです。0~1のグレースケール値で表します(0がつるつる、1がざらざら)。 粗いほど表面がざらつき、光の散乱が大きくなります。 3Dモデルの表面の粗さを表現します。白(値が高い)は粗い表面、黒(値が低い)は滑らかな表面を示します。 粗さマップは、光の反射や散乱の度合いを制御し、質感や光沢感を調整する役割があります。 4-4. Normal(法線)Map 物体の表面の微細な凹凸を表すマップです。RGB( Vector 3)で表し、RGBがXYZ座標に対応するベクトルとして扱います。 RGB値によって、各 ピクセル の表面法線の向きが定義されています。 法線マップは、モデルのポリゴン数を増やさずにディテールを追加することができ、リアルな質感や陰影を表現する役割があります。これにより、高解像度のジオメトリを持たないモデルでも、細かいディテールを表現できます。 4-5. Ambient Occlusion(環境遮蔽)Map 表面の自然な陰影を表現するマップです。0~1のグレースケール値(0が遮蔽された黒、1が露出していて白)で表します。 表面の凹凸によって遮られる環境光を表現します。これにより、物体同士が接近している部分や凹んでいる部分に影ができ、リアルな陰影が表現されます。 4-6. Height(高さ)Map 物体表面の高低差を表すマップです。0~1のグレイスケール値(0が低く、1が高い)で高さを表します。 レンダリング を行う際に、高さの単位(ユニット)を設定する必要があります。 4-7. Specluar Level(鏡面反射レベル)Map 非金属物体に対する鏡面反射の係数を表すマップです。 UEではデフォルト値が0.5(F0が4%)として設定されていますが、この係数を調整できます。 Specular - GlossinessワークフローにおけるSpecular Mapとは異なる点についてご注意ください。 まとめ いかがでしたでしょうか。 近年では、人肌や大理石など物体表面内部に浸透する光の振る舞いを表現する SSS(サブサーフェススキャタリング) や、幅広いレンジの明るさ情報を用いる HDRI(ハイダイナミックレンジイメージ) など、様々な新しい技術が開発されています。 さらに、Unreal Engine5など ゲームエンジン の進化も伴うことで「現実と見紛う」レベルの3DCGがリアルタイム レンダリング 可能になっており、今後も3DCG技術の進化と ユースケース に目が離せません。 次回からは応用編として、 Substance Designerを用いたPBRマテリアルの制作や、 Unreal Engine における レンダリング 方法について紹介してきたいと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Basic Theory of Physically-Based Rendering SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice THE PBR GUIDE BY ALLEGORITHMIC 執筆: @yamashita.yuki 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
はいどーもー! 早いもので新卒入社から丸3年、コミュニケーションIT事業部の宮澤響です! 本記事では、 Backlog API を利用した Backlog への課題の登録方法について、私が実際にハマったポイントを交えながらご紹介します。 背景・前提 Backlogとは どうしてAPIで課題登録を? サンプルコードについて 下準備 APIキーの発行 プロジェクトIDの確認 スペースのURLの確認 やってみる 必要なモジュールのインポートと変数の定義 課題の登録〜基本編〜 課題の登録〜カスタム属性編〜 課題の登録〜複数選択編〜 おまけで検証してみた まとめ 背景・前提 Backlogとは Backlogとは、株式会社 ヌーラボ が提供している課題管理・プロジェクト管理のサービスです。 シンプルで直感的に使えるデザインが特長であり、Git リポジトリ や Wiki としての機能も有しています。 どうして API で課題登録を? 弊社では同種のサービスとして Jira が全社展開されています。 そのため、私自身もこれまではJiraの利用経験しかありませんでした。 しかしこの度、チームの都合によりBacklogを利用することになり、利用方法を調査していたところ、BacklogにはJiraのように標準機能で自動化できる項目はあまりないことが分かりました。 そこで、Backlog API を利用することで一部の処理を自動化できないかと考え、手始めに基本となるであろう課題の登録をやってみることにしました。 サンプルコードについて 本記事のサンプルコードには TypeScript と axios を利用しています。 それぞれのインストール方法などについては本記事内では解説していませんので、適宜リンク先をご参照ください。 下準備 まずはBacklog API を利用するための下準備です。 API キーの発行 個人設定 > API から、 API キーを発行します。 必要に応じて メモ 欄に文字列を入力し、 登録 ボタンを押下します。 なお、Backlog API ではOAuth 2.0を利用した認証・認可方式も提供されていますが、Nulabアカウントを作成した上で開発するアプリケーションの登録を行う必要があるため、本記事では事前準備が不要な API キーを利用した方式を採用します。( 参考 ) プロジェクトIDの確認 課題の登録先となるプロジェクトのプロジェクトIDを確認します。 プロジェクトIDは、当該プロジェクトの 課題 ページや、 プロジェクト設定 ページのURLから確認できます。 プロジェクト情報の取得 の API を利用して確認することもできますが、今回は少し楽をしています。 スペースのURLの確認 課題の登録先となるプロジェクトが所属しているスペースのURLを確認します。 スペースやプロジェクトのあらゆる画面のURLの先頭にある https://xx.backlog.jp または https://xx.backlog.com の部分です。 xx の部分にはそれぞれのスペースのスペースIDが入ります。 やってみる 実際に API リク エス トのための ソースコード を記述していきます。 必要なモジュールのインポートと変数の定義 まずは必要なモジュールをインポートするとともに、ここまでに確認してきた内容から以下の変数を定義します。 // 必要なモジュールをインポートします import axios , { AxiosResponse } from "axios" ; // 右辺の""の中に先ほど発行したAPIキーの値を入力します const apiKey = "abcdefghijklmn" ; // 右辺の""の中に先ほど確認したプロジェクトIDの値を入力します const projectId = "123456" ; // 右辺の""の中に先ほど確認したスペースのURLの値の末尾に「/api/v2」を追加したものを入力します const baseUrl = "https://xx.backlog.jp/api/v2" ; なお、本記事では簡素化のために API キーを ソースコード 内に直接記載していますが、実際に運用をする際、特に GitHub などを利用して ソースコード を共有、公開する際は、 API キーのような認証情報は ソースコード 内に直接記載しない ことを強く推奨します。 (対応例: .gitignore で指定した .env ファイルに記載した値を dotenv を利用して読み込む、など) 課題の登録〜基本編〜 課題の追加 の API を利用します。 手始めに、必須とされている以下のパラメータのみを指定して、POSTリク エス トを送信してみます。 パラメータ名 型 内容 projectId 数値 課題を登録するプロジェクトのID summary 文字列 課題の件名 issueTypeId 数値 課題の種別のID priorityId 数値 課題の優先度のID なお、 issueTypeId や priorityId は、登録先のプロジェクトの 課題 ページの 高度な検索 タブや、 プロジェクト設定 の当該種別の編集ページのURLから確認するのが最も簡単です。 もちろん、 課題情報の取得 、 種別一覧の取得 、 優先度一覧の取得 、などの API を利用して確認することも可能です。 注意点として、Backlog API を利用する際は Content-Type が application/x-www-form-urlencoded である必要がある ため、 URLSearchParams を利用します。( 参考 ) const createIssue1 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト1" , issueTypeId: "123456" , priorityId: "2" , } ); return await axios.post ( url + params ); } ; createIssue1 (); 無事に登録されました。 課題の登録〜カスタム属性編〜 続いて、以下のカスタム属性の値を指定してみます。 カスタム属性名 選択形式 選択肢 単一選択カスタム属性 単一選択(リスト形式) 選択肢1、選択肢2、選択肢3 複数選択カスタム属性 複数選択(リスト形式) 選択肢1、選択肢2、選択肢3 カスタム属性のパラメータ名は customField_xxxxx ( xxxxx はカスタム属性ID)です。 カスタム属性IDの確認方法は、これまでのものと同様、登録先のプロジェクトの 課題 ページの 高度な検索 タブのURL、 プロジェクト設定 の当該カスタム属性の編集ページのURL、 カスタム属性一覧の取得 の API などです。 注意点として、カスタム属性の値は、 選択肢名ではなく選択肢IDで指定 します。 課題の追加 の API リファレンスにはこのことが書かれていないので、若干のハマりポイントです。 const createIssue2 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト2" , issueTypeId: "123456" , priorityId: "2" , // 「customField_12345: "選択肢1"」とすると400エラーになります customField_12345: "1" , // 同上 customField_67890: "1" , } ); return await axios.post ( url + params ); } ; createIssue2 (); 無事にカスタム属性の値が設定されました。 課題の登録〜複数選択編〜 続いて、複数選択が可能なカスタム属性に複数の値を指定してみます。 イメージとしては以下のような ソースコード なのですが、このままでは customField_67890 に複数の値を指定する部分で コンパイル エラー( Type 'string[]' is not assignable to type 'string'. )が発生してしまいます。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , // これはコンパイルエラーになります customField_67890: [ "1" , "2" ] , } ); return await axios.post ( url + params ); } ; createIssue3 (); そのため、標準機能で対応する場合には、少し不格好ではありますが、 append() メソッドを利用して、1つ目の選択肢と2つ目の選択肢を分けて指定 します。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: "1" , } ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); 或いは、コンスト ラク タでは値を指定せず、 append() メソッドのみで全ての値を指定することも可能です。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams (); params.append ( "apiKey" , apiKey ); params.append ( "projectId" , projectId ); params.append ( "summary" , "テスト3" ); params.append ( "issueTypeId" , "123456" ); params.append ( "priorityId" , "2" ); params.append ( "customField_12345" , "1" ); params.append ( "customField_67890" , "1" ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); なお、上述のサンプルコードはいずれも標準機能のみを用いてクエリパラメータを生成していましたが、外部ライブラリを利用すると、カスタム属性に複数の値を指定する部分を一行ですっきり記述できます。 例えば、 qs を利用すると、以下のようになります。 import qs from "qs" ; const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = qs.stringify ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } , { indices: false } ); return await axios.post ( url + params ); } ; createIssue3 (); 無事に複数の値が設定されました。 これでひとまず課題登録に関する一連の試みは完了です。 おまけで検証してみた ちょっとしたおまけです。 上述のとおり、Backlog API では application/x-www-form-urlencoded でリク エス トを送信しますが、 application/json でのリク エス トに変更したらどうなるのでしょうか。 課題の登録には不要な検証ですが、気になったので試してみました。 const createIssue4 = async () : Promise < AxiosResponse > => { // apiKeyをdataに含めると401エラーになります const url = ` ${ baseUrl } /issues?apiKey= ${ apiKey } ` ; const data = { projectId , summary: "テスト4" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } ; return await axios.post ( url , data ); } ; createIssue4 (); 結果としては、課題の登録自体はできるものの、カスタム属性の値が反映されませんでした。 (中途半端に成功する理由については不明です…もしご存知の方がいらっしゃれば、ぜひ本記事を引用して記事を執筆してみてください…!笑) まとめ 本記事では、Backlog API を利用したBacklogへの課題の登録方法について、サンプルコードとともにご紹介しました。 その際の主な注意点は以下です。 API キーのような認証情報は ソースコード 内に直接記載しない(Backlog API に限らず) Content-Type は application/x-www-form-urlencoded カスタム属性の値は選択肢名ではなく選択肢IDで指定 標準機能でパラメータに複数の値を指定するには、 append() メソッドで1つ目の選択肢と2つ目の選択肢を分けて指定 少しでもBacklog API の利用を検討している方々の参考になれば幸いです。 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! 私自身は対顧客のセキュリティに関する業務に従事していますので、そのような業務にご興味がありましたら、応募の際にお問い合わせください! みなさまのご応募、お待ちしています! クラウドアーキテクト アプリケーションアーキテクト 電通グループ向け基幹システムプロジェクトマネージャ 戦略的IT プロジェクトマネージャ/ITコンサルタント 執筆: @miyazawa.hibiki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
はいどーもー! 早いもので新卒入社から丸3年、コミュニケーションIT事業部の宮澤響です! 本記事では、 Backlog API を利用した Backlog への課題の登録方法について、私が実際にハマったポイントを交えながらご紹介します。 背景・前提 Backlogとは どうしてAPIで課題登録を? サンプルコードについて 下準備 APIキーの発行 プロジェクトIDの確認 スペースのURLの確認 やってみる 必要なモジュールのインポートと変数の定義 課題の登録〜基本編〜 課題の登録〜カスタム属性編〜 課題の登録〜複数選択編〜 おまけで検証してみた おわりに 背景・前提 Backlogとは Backlogとは、株式会社 ヌーラボ が提供している課題管理・プロジェクト管理のサービスです。 シンプルで直感的に使えるデザインが特長であり、Git リポジトリ や Wiki としての機能も有しています。 どうして API で課題登録を? 弊社では同種のサービスとして Jira が全社展開されています。 そのため、私自身もこれまではJiraの利用経験しかありませんでした。 しかしこの度、チームの都合によりBacklogを利用することになり、利用方法を調査していたところ、BacklogにはJiraのように標準機能で自動化できる項目はあまりないことが分かりました。 そこで、Backlog API を利用することで一部の処理を自動化できないかと考え、手始めに基本となるであろう課題の登録をやってみることにしました。 サンプルコードについて 本記事のサンプルコードには TypeScript と axios を利用しています。 それぞれのインストール方法などについては本記事内では解説していませんので、適宜リンク先をご参照ください。 下準備 まずはBacklog API を利用するための下準備です。 API キーの発行 個人設定 > API から、 API キーを発行します。 必要に応じて メモ 欄に文字列を入力し、 登録 ボタンを押下します。 なお、Backlog API ではOAuth 2.0を利用した認証・認可方式も提供されていますが、Nulabアカウントを作成した上で開発するアプリケーションの登録を行う必要があるため、本記事では事前準備が不要な API キーを利用した方式を採用します。( 参考 ) プロジェクトIDの確認 課題の登録先となるプロジェクトのプロジェクトIDを確認します。 プロジェクトIDは、当該プロジェクトの 課題 ページや、 プロジェクト設定 ページのURLから確認できます。 プロジェクト情報の取得 の API を利用して確認することもできますが、今回は少し楽をしています。 スペースのURLの確認 課題の登録先となるプロジェクトが所属しているスペースのURLを確認します。 スペースやプロジェクトのあらゆる画面のURLの先頭にある https://xx.backlog.jp または https://xx.backlog.com の部分です。 xx の部分にはそれぞれのスペースのスペースIDが入ります。 やってみる 実際に API リク エス トのための ソースコード を記述していきます。 必要なモジュールのインポートと変数の定義 まずは必要なモジュールをインポートするとともに、ここまでに確認してきた内容から以下の変数を定義します。 // 必要なモジュールをインポートします import axios , { AxiosResponse } from "axios" ; // 右辺の""の中に先ほど発行したAPIキーの値を入力します const apiKey = "abcdefghijklmn" ; // 右辺の""の中に先ほど確認したプロジェクトIDの値を入力します const projectId = "123456" ; // 右辺の""の中に先ほど確認したスペースのURLの値の末尾に「/api/v2」を追加したものを入力します const baseUrl = "https://xx.backlog.jp/api/v2" ; なお、本記事では簡素化のために API キーを ソースコード 内に直接記載していますが、実際に運用をする際、特に GitHub などを利用して ソースコード を共有、公開する際は、 API キーのような認証情報は ソースコード 内に直接記載しない ことを強く推奨します。 (対応例: .gitignore で指定した .env ファイルに記載した値を dotenv を利用して読み込む、など) 課題の登録〜基本編〜 課題の追加 の API を利用します。 手始めに、必須とされている以下のパラメータのみを指定して、POSTリク エス トを送信してみます。 パラメータ名 型 内容 projectId 数値 課題を登録するプロジェクトのID summary 文字列 課題の件名 issueTypeId 数値 課題の種別のID priorityId 数値 課題の優先度のID なお、 issueTypeId や priorityId は、登録先のプロジェクトの 課題 ページの 高度な検索 タブや、 プロジェクト設定 の当該種別の編集ページのURLから確認するのが最も簡単です。 もちろん、 課題情報の取得 、 種別一覧の取得 、 優先度一覧の取得 、などの API を利用して確認することも可能です。 注意点として、Backlog API を利用する際は Content-Type が application/x-www-form-urlencoded である必要がある ため、 URLSearchParams を利用します。( 参考 ) const createIssue1 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト1" , issueTypeId: "123456" , priorityId: "2" , } ); return await axios.post ( url + params ); } ; createIssue1 (); 無事に登録されました。 課題の登録〜カスタム属性編〜 続いて、以下のカスタム属性の値を指定してみます。 カスタム属性名 選択形式 選択肢 単一選択カスタム属性 単一選択(リスト形式) 選択肢1、選択肢2、選択肢3 複数選択カスタム属性 複数選択(リスト形式) 選択肢1、選択肢2、選択肢3 カスタム属性のパラメータ名は customField_xxxxx ( xxxxx はカスタム属性ID)です。 カスタム属性IDの確認方法は、これまでのものと同様、登録先のプロジェクトの 課題 ページの 高度な検索 タブのURL、 プロジェクト設定 の当該カスタム属性の編集ページのURL、 カスタム属性一覧の取得 の API などです。 注意点として、カスタム属性の値は、 選択肢名ではなく選択肢IDで指定 します。 課題の追加 の API リファレンスにはこのことが書かれていないので、若干のハマりポイントです。 const createIssue2 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト2" , issueTypeId: "123456" , priorityId: "2" , // 「customField_12345: "選択肢1"」とすると400エラーになります customField_12345: "1" , // 同上 customField_67890: "1" , } ); return await axios.post ( url + params ); } ; createIssue2 (); 無事にカスタム属性の値が設定されました。 課題の登録〜複数選択編〜 続いて、複数選択が可能なカスタム属性に複数の値を指定してみます。 イメージとしては以下のような ソースコード なのですが、このままでは customField_67890 に複数の値を指定する部分で コンパイル エラー( Type 'string[]' is not assignable to type 'string'. )が発生してしまいます。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , // これはコンパイルエラーになります customField_67890: [ "1" , "2" ] , } ); return await axios.post ( url + params ); } ; createIssue3 (); そのため、標準機能で対応する場合には、少し不格好ではありますが、 append() メソッドを利用して、1つ目の選択肢と2つ目の選択肢を分けて指定 します。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: "1" , } ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); 或いは、コンスト ラク タでは値を指定せず、 append() メソッドのみで全ての値を指定することも可能です。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams (); params.append ( "apiKey" , apiKey ); params.append ( "projectId" , projectId ); params.append ( "summary" , "テスト3" ); params.append ( "issueTypeId" , "123456" ); params.append ( "priorityId" , "2" ); params.append ( "customField_12345" , "1" ); params.append ( "customField_67890" , "1" ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); なお、上述のサンプルコードはいずれも標準機能のみを用いてクエリパラメータを生成していましたが、外部ライブラリを利用すると、カスタム属性に複数の値を指定する部分を一行ですっきり記述できます。 例えば、 qs を利用すると、以下のようになります。 import qs from "qs" ; const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = qs.stringify ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } , { indices: false } ); return await axios.post ( url + params ); } ; createIssue3 (); 無事に複数の値が設定されました。 これでひとまず課題登録に関する一連の試みは完了です。 おまけで検証してみた ちょっとしたおまけです。 上述のとおり、Backlog API では application/x-www-form-urlencoded でリク エス トを送信しますが、 application/json でのリク エス トに変更したらどうなるのでしょうか。 課題の登録には不要な検証ですが、気になったので試してみました。 const createIssue4 = async () : Promise < AxiosResponse > => { // apiKeyをdataに含めると401エラーになります const url = ` ${ baseUrl } /issues?apiKey= ${ apiKey } ` ; const data = { projectId , summary: "テスト4" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } ; return await axios.post ( url , data ); } ; createIssue4 (); 結果としては、課題の登録自体はできるものの、カスタム属性の値が反映されませんでした。 (中途半端に成功する理由については不明です…もしご存知の方がいらっしゃれば、ぜひ本記事を引用して記事を執筆してみてください…!笑) おわりに 本記事では、Backlog API を利用したBacklogへの課題の登録方法について、サンプルコードとともにご紹介しました。 その際の主な注意点は以下です。 API キーのような認証情報は ソースコード 内に直接記載しない(Backlog API に限らず) Content-Type は application/x-www-form-urlencoded カスタム属性の値は選択肢名ではなく選択肢IDで指定 標準機能でパラメータに複数の値を指定するには、 append() メソッドで1つ目の選択肢と2つ目の選択肢を分けて指定 少しでもBacklog API の利用を検討している方々の参考になれば幸いです。 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! <電通×IT>電通グループ基幹システムプロジェクトマネージャー エンタープライズ向けDX推進リーダー/エンジニア <電通×IT>クラウドアーキテクト <電通×IT>アプリケーションアーキテクト 製品・プラットフォーム開発エンジニア 執筆: @miyazawa.hibiki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の孫です。 皆さんはGitで ソースコード の構成管理を行う中で、バイナリファイルのサイズが大きすぎて GitHub などの ホスティング サービスからブロックされたりした経験はないでしょうか。 実は、最近UnrealEngineを使ってゲームを開発しているところで、そうした大容量ファイルの管理問題に直面しました。 こういう問題を解決するために、 Git LFS というアップローチがあります。 今回の記事では、 Amazon S3 (以下 S3)を用いて独自のGit LFS サーバを建てる方法を紹介します。 ※構成イメージは以下の図をご参照ください。 Git LFS とは GitHub でのサイズ制限 によって GitHub では100MBを超えるファイルをブロックします。 サイズ制限を解消するため、大容量ファイルを効率的に扱う「Git LFS 」が利用されます。 Git LFS を利用することで、レポジトリではハッシュのみを管理し、データ自体は別のストレージ(上記図の Amazon S3 )で管理することなどが可能になります。 GitHub でGit LFS を使う場合の選択肢 GitHub では、公式サービスとして GitHub LFS が提供されています。 しかし、 GitHub が提供している LFS サーバーは無料枠でアカウントごとに2GBまで使用することが可能であるものの、それを超えて使用する場合には「data pack」を購入する必要があります。 コストを削減したい為、 GitHub LFS をS3に切り替えることにしました。 S3ベースのGit LFS サーバーの構築にあたり、いくつかOpenSourceがありますが、今回は構築の利便性および導入後の運用性を考慮した上でRudolfsを選定しました。 以下は当初検討になった各OpenSourceです。 lfs-test-server S3と連携する仕組みがない為却下 LFS2S3Proxy 個人の製品ですからセキュリティおよび今後のアップデートを考慮した上で却下 meltingice/Git LFS S3 Ruby で開発した製品ですが、チーム内に Ruby に詳しいメンバーがいない為却下 Rudolfs ★S3をバックエンドとして利用可能、かつDocker化されており運用もしやすい為採用★ 実施手順 以下の流れで、Rudolfsを用いてGit LFS サーバーを構築します。 事前準備 Rudolfsのセットアップ 検証リソースの準備 動作確認 1.事前準備 Dockerをセットアップします 以下のドキュメントに沿ってDocker Desktopをインストールします Linux OS Mac OS Windows OS Docker Composeのインストールを確認します コマンド docker compose version でバージョンが表示されればOKです 一般的にDocker Desktopのインストールパッケージに含まれるはずですが、もし一部の linux パーケージになければ、 こちら に沿ってDocker Compose プラグイン をインストールします その他、Dockerの使い方についての説明は割愛します 「git lfs 」コマンドプライグインをインストールします こちらのページ に沿ってインストールします AWS アカウントがない場合、作成する必要があります 今なら1年間無料で Amazon EC2 やS3を利用できるため、無料枠で大丈夫です AWS コンソールからアクセスキーを作成します AWSドキュメント に沿って作成します AWS コンソールからS3 バケット を作成します AWS S3のバケットの作り方 を参照して作成します S3 バケット 名: 今回は「test- lfs -s3」にしました 2.Rudolfsのセットアップ 基本はRudolfs リポジトリ の Readme を参考にしてセットアップを行います。 Rudolfsの ソースコード をダウンロードします 以下のコマンドで ソースコード をクローンします git clone https://github.com/jasonwhite/rudolfs.git Rudolfsで利用する暗号化キーを生成します openssl rand -hex 32 コマンドで生成します ダウンロードしたRudolfsフォルダに移動して新規に .env ファイルを作成します 事前準備で作成した AWS アクセスキー、暗号化キーとS3 バケット 名を埋め込んで .env ファイルに書きます AWS_ACCESS_KEY_ID=「AWSアクセスキーID」 AWS_SECRET_ACCESS_KEY=「AWSアクセスキー」 AWS_DEFAULT_REGION=「AWSリージョン名」 LFS_ENCRYPTION_KEY=「Rudolfsの暗号化キー」 LFS_S3_BUCKET=「作成したbucket名」 LFS_MAX_CACHE_SIZE=10GB 以下のコマンドを叩いてRudolfsコンテナを起動します docker-compose --env-file .env up -d コンテナの起動ステータスを確認します docker compose ps を叩きます 「STATUS」は running で表示することを確認します 3.検証リソースの準備 GitHub でテスト用 リポジトリ を作成します リポジトリ 名は「test- lfs 」にしました 詳細な手順は リポジトリを作成する を参照して作成してください テス トリポジ トリをクローンします git clone リポジトリのURL test- lfs フォルダに移動し .lfsconfig ファイルを作成します 以下の規則に沿って LFS サーバのURLを定義します git のglobal settingを設定します Readmeでパフォーマンスに関するおすすめ設定です 今回はこの設定によってどの程度の効果が発揮できるまでは検証していません # Increase the number of worker threads git config --global lfs.concurrenttransfers 64 # Use a global LFS cache to make re-cloning faster git config --global lfs.storage ~/.cache/lfs .gitattributes を作成し、該当の LFS ファイルを定義します 今回のテストファイルの拡張子は .test にしました *.test filter=lfs diff=lfs merge=lfs -text テストファイルを作成します GitHub は100MBを超えるファイルをブロックします 大容量ファイルを認識させるため、120MBのテストファイルを作成します # MAC OSコマンド $ mkfile -n 120m bigdata1.test # Linux OSコマンド $ dd if=/dev/zero of=bigdata1.test bs=1M count=120 # Window OSコマンド $ fsutil file createnew "bigdata1.test" 125829120 4.動作確認 Push前にS3 バケット を確認します 何もオブジェクトがないことを確認します Git LFS を使用しない場合のエラーを確認します 先ほど作成した大容量テストファイルをPushします Git LFS を使用しない場合、前述 GitHub でのサイズ制限でエラーになることを確認します # 大容量ファイルをgitに追加してコミットします $ git add -A $ git commit -m "test rudolfs s3 bigdata1" # GitHubへのPushでファイルサイズの超過エラーが発生します $ git push origin main ------エラー情報の抜粋-------- remote: error: Trace: 9256fd02811ab3b1e6f389b62f285e730ea5d39cbff2226baefcd80261028e5b remote: error: See https://gh.io/lfs for more information. ★ remote: error: File bigdata1.test is 120.00 MB; this exceeds GitHub's file size limit of 100.00 MB ★ remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com. --------------------------- Git LFS を初期化します git lfs install 再度大容量テストファイルをPushします Git LFS を使用する場合、Pushが問題なく完了することを確認します $ git push origin main Push後にS3 バケット と GitHub リポジトリ を確認します S3 バケット の中に、オブジェクトが存在することを確認します GitHub リポジトリ の中に、bigdata1.testファイル内容は ハッシュ値 であることを確認します bigdata1.testの中身の ハッシュ値 は、S3 バケット のファイル名と一致していることを確認します ここまで、今回の構成に対する動作確認は完了しました! おわりに というわけで、今回はRudolfs+S3を導入することによって大容量ファイルの構成管理ができて、また リポジトリ のサイズが抑えられました。 またチームで開発する場合は、Rudolfsの暗号キーさえチームメンバー内で一致していれば、各メンバーのS3権限を待たせる運用で進められます。 ただし、暗号キー自体は全てのメンバーに配布する都合で、セキュリティ観点で考慮する必要があります。 本記事ではセキュリティの側面について深掘りしないですが、もう少しセキュアな運用にしたい場合、一つの案として暗号キーの共有ではなくて安全なプライベートネットワーク内にRudolfsコンテナを一つ建て共有するアップローチがあります。 今回の構成は特に AWS プロジェクトにおいてコストを抑えたい方に向いています。 LFS で大容量ファイルを管理した上で、 リポジトリ のCloneやPull、Pushなどの速度が早くなり開発の効率化を図ることができます! 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://github.com/jasonwhite/rudolfs https://git-lfs.com/ https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-git-large-file-storage 執筆: @chen.sun 、 @kase.teruyoshi 、レビュー: @yamashita.yuki ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の孫です。 皆さんはGitで ソースコード の構成管理を行う中で、バイナリファイルのサイズが大きすぎて GitHub などの ホスティング サービスからブロックされたりした経験はないでしょうか。 実は、最近UnrealEngineを使ってゲームを開発しているところで、そうした大容量ファイルの管理問題に直面しました。 こういう問題を解決するために、 Git LFS というアップローチがあります。 今回の記事では、 Amazon S3 (以下 S3)を用いて独自のGit LFS サーバを建てる方法を紹介します。 ※構成イメージは以下の図をご参照ください。 Git LFS とは GitHub でのサイズ制限 によって GitHub では100MBを超えるファイルをブロックします。 サイズ制限を解消するため、大容量ファイルを効率的に扱う「Git LFS 」が利用されます。 Git LFS を利用することで、レポジトリではハッシュのみを管理し、データ自体は別のストレージ(上記図の Amazon S3 )で管理することなどが可能になります。 GitHub でGit LFS を使う場合の選択肢 GitHub では、公式サービスとして GitHub LFS が提供されています。 しかし、 GitHub が提供している LFS サーバーは無料枠でアカウントごとに2GBまで使用することが可能であるものの、それを超えて使用する場合には「data pack」を購入する必要があります。 コストを削減したい為、 GitHub LFS をS3に切り替えることにしました。 S3ベースのGit LFS サーバーの構築にあたり、いくつかOpenSourceがありますが、今回は構築の利便性および導入後の運用性を考慮した上でRudolfsを選定しました。 以下は当初検討になった各OpenSourceです。 lfs-test-server S3と連携する仕組みがない為却下 LFS2S3Proxy 個人の製品ですからセキュリティおよび今後のアップデートを考慮した上で却下 meltingice/Git LFS S3 Ruby で開発した製品ですが、チーム内に Ruby に詳しいメンバーがいない為却下 Rudolfs ★S3をバックエンドとして利用可能、かつDocker化されており運用もしやすい為採用★ 実施手順 以下の流れで、Rudolfsを用いてGit LFS サーバーを構築します。 事前準備 Rudolfsのセットアップ 検証リソースの準備 動作確認 1.事前準備 Dockerをセットアップします 以下のドキュメントに沿ってDocker Desktopをインストールします Linux OS Mac OS Windows OS Docker Composeのインストールを確認します コマンド docker compose version でバージョンが表示されればOKです 一般的にDocker Desktopのインストールパッケージに含まれるはずですが、もし一部の linux パーケージになければ、 こちら に沿ってDocker Compose プラグイン をインストールします その他、Dockerの使い方についての説明は割愛します 「git lfs 」コマンドプライグインをインストールします こちらのページ に沿ってインストールします AWS アカウントがない場合、作成する必要があります 今なら1年間無料で Amazon EC2 やS3を利用できるため、無料枠で大丈夫です AWS コンソールからアクセスキーを作成します AWSドキュメント に沿って作成します AWS コンソールからS3 バケット を作成します AWS S3のバケットの作り方 を参照して作成します S3 バケット 名: 今回は「test- lfs -s3」にしました 2.Rudolfsのセットアップ 基本はRudolfs リポジトリ の Readme を参考にしてセットアップを行います。 Rudolfsの ソースコード をダウンロードします 以下のコマンドで ソースコード をクローンします git clone https://github.com/jasonwhite/rudolfs.git Rudolfsで利用する暗号化キーを生成します openssl rand -hex 32 コマンドで生成します ダウンロードしたRudolfsフォルダに移動して新規に .env ファイルを作成します 事前準備で作成した AWS アクセスキー、暗号化キーとS3 バケット 名を埋め込んで .env ファイルに書きます AWS_ACCESS_KEY_ID=「AWSアクセスキーID」 AWS_SECRET_ACCESS_KEY=「AWSアクセスキー」 AWS_DEFAULT_REGION=「AWSリージョン名」 LFS_ENCRYPTION_KEY=「Rudolfsの暗号化キー」 LFS_S3_BUCKET=「作成したbucket名」 LFS_MAX_CACHE_SIZE=10GB 以下のコマンドを叩いてRudolfsコンテナを起動します docker-compose --env-file .env up -d コンテナの起動ステータスを確認します docker compose ps を叩きます 「STATUS」は running で表示することを確認します 3.検証リソースの準備 GitHub でテスト用 リポジトリ を作成します リポジトリ 名は「test- lfs 」にしました 詳細な手順は リポジトリを作成する を参照して作成してください テス トリポジ トリをクローンします git clone リポジトリのURL test- lfs フォルダに移動し .lfsconfig ファイルを作成します 以下の規則に沿って LFS サーバのURLを定義します git のglobal settingを設定します Readmeでパフォーマンスに関するおすすめ設定です 今回はこの設定によってどの程度の効果が発揮できるまでは検証していません # Increase the number of worker threads git config --global lfs.concurrenttransfers 64 # Use a global LFS cache to make re-cloning faster git config --global lfs.storage ~/.cache/lfs .gitattributes を作成し、該当の LFS ファイルを定義します 今回のテストファイルの拡張子は .test にしました *.test filter=lfs diff=lfs merge=lfs -text テストファイルを作成します GitHub は100MBを超えるファイルをブロックします 大容量ファイルを認識させるため、120MBのテストファイルを作成します # MAC OSコマンド $ mkfile -n 120m bigdata1.test # Linux OSコマンド $ dd if=/dev/zero of=bigdata1.test bs=1M count=120 # Window OSコマンド $ fsutil file createnew "bigdata1.test" 125829120 4.動作確認 Push前にS3 バケット を確認します 何もオブジェクトがないことを確認します Git LFS を使用しない場合のエラーを確認します 先ほど作成した大容量テストファイルをPushします Git LFS を使用しない場合、前述 GitHub でのサイズ制限でエラーになることを確認します # 大容量ファイルをgitに追加してコミットします $ git add -A $ git commit -m "test rudolfs s3 bigdata1" # GitHubへのPushでファイルサイズの超過エラーが発生します $ git push origin main ------エラー情報の抜粋-------- remote: error: Trace: 9256fd02811ab3b1e6f389b62f285e730ea5d39cbff2226baefcd80261028e5b remote: error: See https://gh.io/lfs for more information. ★ remote: error: File bigdata1.test is 120.00 MB; this exceeds GitHub's file size limit of 100.00 MB ★ remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com. --------------------------- Git LFS を初期化します git lfs install 再度大容量テストファイルをPushします Git LFS を使用する場合、Pushが問題なく完了することを確認します $ git push origin main Push後にS3 バケット と GitHub リポジトリ を確認します S3 バケット の中に、オブジェクトが存在することを確認します GitHub リポジトリ の中に、bigdata1.testファイル内容は ハッシュ値 であることを確認します bigdata1.testの中身の ハッシュ値 は、S3 バケット のファイル名と一致していることを確認します ここまで、今回の構成に対する動作確認は完了しました! おわりに というわけで、今回はRudolfs+S3を導入することによって大容量ファイルの構成管理ができて、また リポジトリ のサイズが抑えられました。 またチームで開発する場合は、Rudolfsの暗号キーさえチームメンバー内で一致していれば、各メンバーのS3権限を待たせる運用で進められます。 ただし、暗号キー自体は全てのメンバーに配布する都合で、セキュリティ観点で考慮する必要があります。 本記事ではセキュリティの側面について深掘りしないですが、もう少しセキュアな運用にしたい場合、一つの案として暗号キーの共有ではなくて安全なプライベートネットワーク内にRudolfsコンテナを一つ建て共有するアップローチがあります。 今回の構成は特に AWS プロジェクトにおいてコストを抑えたい方に向いています。 LFS で大容量ファイルを管理した上で、 リポジトリ のCloneやPull、Pushなどの速度が早くなり開発の効率化を図ることができます! 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://github.com/jasonwhite/rudolfs https://git-lfs.com/ https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-git-large-file-storage 執筆: @chen.sun 、 @kase.teruyoshi 、レビュー: @yamashita.yuki ( Shodo で執筆されました )
こんにちは!製造ソリューション事業部6年目の小林です。 製品 開発プロセス で発生する様々な情報を一元管理するPLM(Product Lifecycle Management)システムの導入、セールス支援をしています。 この記事では、私の仕事内容と仕事の楽しいポイントをご紹介します。 簡単な自己紹介 通信系の大学を卒業後入社し、製造ソリューション事業部に配属され、6年目になります。 就職活動では、メーカーに対するITソリューションを軸に活動をしていました。 他の企業説明会などにもたくさん参加をしましたが、最終的には インターン に参加した時の雰囲気から、とても刺激的な毎日が送れるのではないかと直感的に感じるものがあり、入社を決めました。 仕事内容 私の所属する製造ソリューション事業部 東日本技術ユニットでは、製品 開発プロセス で発生する様々な情報を管理するPLMシステム、製品開発設計で扱うCADシステムを軸とした製造ソリューションを扱っています。 そこで私は主に、プロジェクトマネージャー、プロジェクトリーダーといった役割で仕事をしています。 ※PLMシステムに興味がある方は以下リンクをご参照ください。 製造業DXサイト 製品> PLM(Product Lifecycle Management) https://mfg.isid.co.jp/product/plm/ 私の仕事のやりがい PLMシステム導入プロジェクトは最終的な目標(新システムが本番運用している状態)達成まで約1~3年ほどの期間がかかります。 この仕事の一番のやりがいを感じる時は、やはり、プロジェクトを完遂後、 ユーザーよりお礼の言葉をいただいた時 です。 ただ、このピークでやりがいを感じる機会は、数年に1回あるか、ないか、ですので、この記事では、プロジェクト遂行中にやりがいを感じるポイントを2点ご紹介します。 ①見えないものを頭をフル回転させて見ようとする プロジェクト発足時に最初に来るフェーズは”計画フェーズ”です。 製造ソリューション事業部では、基本的には、プリセールスで担当したエンジニアがプロジェクトマネージャーになります。 そのため、導入するシステムに期待することなどを、お客様の想いを理解した上で、目的・目標・計画をすり合わせを行います。 ただ、この時の計画は予測ですので、正解(実績)は、やってみないと誰にも分かりません。 何もモノがない状態で、頭をフル回転させて、 あらゆるリスクを予測しスケジュールを組んだり、精度が荒い部分、不明な部分に対して社内外にアクションを働きかけているとき、仕事を創造しているような楽しさがあります。 また、「お客様のシステム導入にリスクのある計画になっていないか」という顧客視点は、もちろん、「自社の後続フェーズを踏まえて何をいつまでに完了しないといけないか」といった自社内作業の視点を含めた2つの視点で頭を使うところが コンサルタント にはない、プロジェクトマネージャーの役割の醍醐味です。 ②実現したいことを把握した上でロジックを組み立てる 計画フェーズが終了すると、"要件定義・基本設計フェーズ"に移ります。 このフェーズでは、お客様の実現したいことに対して、システム要件として文書化して整理をし、仕様確定します。 製造ソリューション事業部では、ITシステム コンサルタント と システムエンジニア の役目を両方を担当する社員が多いです。 お客様の実現したいことを自身で ヒアリ ングし、仕様・ロジックに落とし込んでいくといった一連の流れをすべて把握しながら要件定義・基本設計をする楽しさがあります。 一日のスケジュール 9:30始業で、週2で客先訪問、週3でテレワーク業務です。 客先訪問の前後は、近くの サテライトオフィス を利用し、社内業務をします。 基本18:30には終業していますが、技術調査の探求心が止まらない場合は、遅い時間まで仕事を進めることもあります 学生の時にやっておいた方がいいこと なんでもよいので、”真剣にやって、楽しむ”という経験を一度するとよいと思います。 今回の記事では仕事の楽しいポイントを書きましたが、「やりたいこと」と同時に、「やらなければいけないこと」も付いてきています。 ただ、私の場合は、「真剣に仕事で楽しいこと」を追求しているので、ほぼ無意識にその「やらなければいけないこと」は知らず知らずクリアしているケースがほとんどです。 最後に ~就活生の方へのメッセージ~ 私も就活生の時は、製造業界に向けて何かで寄与したいという強い想いはありましたが、「本当に自分がやりたいこと」は明確に分からず、悩みを持っていた時期がありました。 そんな悩みを抱えていた時に、ISIDの説明会などに参加するという手段を使い、「やりたいこと」の精度を上げ、悩みを解決することができました。 私たちは今、同じチームで働いてくれる仲間を探しています。 既にITに興味があるという方はもちろんですが、○○業界に寄与したい強い想いがあるという方も是非ISIDの門戸を叩いてみてください。 私たちは一緒に働いてくれる仲間を募集しています! ISID 募集職種一覧 www.isid.co.jp 執筆: @kobayashi.takahiro 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
こんにちは!製造ソリューション事業部6年目の小林です。 製品 開発プロセス で発生する様々な情報を一元管理するPLM(Product Lifecycle Management)システムの導入、セールス支援をしています。 この記事では、私の仕事内容と仕事の楽しいポイントをご紹介します。 簡単な自己紹介 通信系の大学を卒業後入社し、製造ソリューション事業部に配属され、6年目になります。 就職活動では、メーカーに対するITソリューションを軸に活動をしていました。 他の企業説明会などにもたくさん参加をしましたが、最終的には インターン に参加した時の雰囲気から、とても刺激的な毎日が送れるのではないかと直感的に感じるものがあり、入社を決めました。 仕事内容 私の所属する製造ソリューション事業部 東日本技術ユニットでは、製品 開発プロセス で発生する様々な情報を管理するPLMシステム、製品開発設計で扱うCADシステムを軸とした製造ソリューションを扱っています。 そこで私は主に、プロジェクトマネージャー、プロジェクトリーダーといった役割で仕事をしています。 ※PLMシステムに興味がある方は以下リンクをご参照ください。 製造業DXサイト 製品> PLM(Product Lifecycle Management) https://mfg.isid.co.jp/product/plm/ 私の仕事のやりがい PLMシステム導入プロジェクトは最終的な目標(新システムが本番運用している状態)達成まで約1~3年ほどの期間がかかります。 この仕事の一番のやりがいを感じる時は、やはり、プロジェクトを完遂後、 ユーザーよりお礼の言葉をいただいた時 です。 ただ、このピークでやりがいを感じる機会は、数年に1回あるか、ないか、ですので、この記事では、プロジェクト遂行中にやりがいを感じるポイントを2点ご紹介します。 ①見えないものを頭をフル回転させて見ようとする プロジェクト発足時に最初に来るフェーズは”計画フェーズ”です。 製造ソリューション事業部では、基本的には、プリセールスで担当したエンジニアがプロジェクトマネージャーになります。 そのため、導入するシステムに期待することなどを、お客様の想いを理解した上で、目的・目標・計画をすり合わせを行います。 ただ、この時の計画は予測ですので、正解(実績)は、やってみないと誰にも分かりません。 何もモノがない状態で、頭をフル回転させて、 あらゆるリスクを予測しスケジュールを組んだり、精度が荒い部分、不明な部分に対して社内外にアクションを働きかけているとき、仕事を創造しているような楽しさがあります。 また、「お客様のシステム導入にリスクのある計画になっていないか」という顧客視点は、もちろん、「自社の後続フェーズを踏まえて何をいつまでに完了しないといけないか」といった自社内作業の視点を含めた2つの視点で頭を使うところが コンサルタント にはない、プロジェクトマネージャーの役割の醍醐味です。 ②実現したいことを把握した上でロジックを組み立てる 計画フェーズが終了すると、"要件定義・基本設計フェーズ"に移ります。 このフェーズでは、お客様の実現したいことに対して、システム要件として文書化して整理をし、仕様確定します。 製造ソリューション事業部では、ITシステム コンサルタント と システムエンジニア の役目を両方を担当する社員が多いです。 お客様の実現したいことを自身で ヒアリ ングし、仕様・ロジックに落とし込んでいくといった一連の流れをすべて把握しながら要件定義・基本設計をする楽しさがあります。 一日のスケジュール 9:30始業で、週2で客先訪問、週3でテレワーク業務です。 客先訪問の前後は、近くの サテライトオフィス を利用し、社内業務をします。 基本18:30には終業していますが、技術調査の探求心が止まらない場合は、遅い時間まで仕事を進めることもあります 学生の時にやっておいた方がいいこと なんでもよいので、”真剣にやって、楽しむ”という経験を一度するとよいと思います。 今回の記事では仕事の楽しいポイントを書きましたが、「やりたいこと」と同時に、「やらなければいけないこと」も付いてきています。 ただ、私の場合は、「真剣に仕事で楽しいこと」を追求しているので、ほぼ無意識にその「やらなければいけないこと」は知らず知らずクリアしているケースがほとんどです。 最後に ~就活生の方へのメッセージ~ 私も就活生の時は、製造業界に向けて何かで寄与したいという強い想いはありましたが、「本当に自分がやりたいこと」は明確に分からず、悩みを持っていた時期がありました。 そんな悩みを抱えていた時に、ISIDの説明会などに参加するという手段を使い、「やりたいこと」の精度を上げ、悩みを解決することができました。 私たちは今、同じチームで働いてくれる仲間を探しています。 既にITに興味があるという方はもちろんですが、○○業界に寄与したい強い想いがあるという方も是非ISIDの門戸を叩いてみてください。 私たちは一緒に働いてくれる仲間を募集しています! ISID 募集職種一覧 www.isid.co.jp 執筆: @kobayashi.takahiro 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はUE5 PixelStreamingで、マウスカーソルを別の画像に変更してクリックイベントを作成します。 前回までの記事でもPixelStreamingについて調べているので、まだご覧になっていない方はそちらも参考にしていただけると嬉しいです。 UE5 PixelStreamingで、WebUI経由でUE Blueprintを操作する UE5 PixelStreamingで、Blueprint経由でWebブラウザを操作する はじめに PixelStreamingを利用してブラウザからUEを操作する利用場面を考えた際、重要になってくるUXのひとつとしてマウスクリックが考えられます。 例えばUE上にショップのようなものを展開し、ユーザーの気になるオブジェクト(商品サンプルなど)がある場合、マウスクリックを通じて ECサイト へ遷移することなどできます。 今回はそのようなPixelStreaming上でのマウスクリックやマウスカーソルに関する調査を行いました。 検証環境/ツール Unreal Engine5.1.1 AWS EC2 Windows _Server-2022-English-Full-Base-2023.01.19 Chrome ver.110.0.5481.177 実装手順 マウスカーソルの座標を取得 マウスカーソル用の画像を設定する マウスカーソルの動きに画像が連動するようにする 作成した ウィジェット をUEプロジェクトに適用する 作成した ウィジェット をPixelStreamingでも動くようにする 1. マウスカーソルの座標を取得 まず初めにマウスがクリックした際の座標を取得するBlueprintを作成します。 適当なプロジェクトを用意して、LevelBlueprintを開きます。 Blueprintでマウスの座標を取得するための関数は2つ存在します。 Get Mouse Position Get Mouse Position Scaled by DPI 今回は下の「Get Mouse Position Scaled by DPI」を使用します。 DPIとは解像度のことで、「Get Mouse Position Scaled by DPI」を使用すると解像度に合わせてマウスの座標を算出してくれます。 「Get Mouse Position Scaled by DPI」を使用してマウスの座標を取得するために、まずはコントローラーの情報を取得するための「Get Player Controller」のノードを作成します。 作成したノードのReturn Value から上記で説明した「Get Mouse Position Scaled by DPI」のノードを作成します。 このLocation X/Y にマウスの座標が入っているので、それぞれを「Print String」でUEに表示させます。 このままでは、まだマウスの座標を表示させるためのイベントが設定されていないので、今回はマウスを左クリックした際に座標を表示させるようにします。 「Left Mouse Button」のイベントノードを作成し、先ほど作成した「Print String」に繋ぐことで、左クリックをした際にマウスの座標をUEに表示するイベントが発火するようになります。 ※この段階でPixelStreamingでプレイをしても後述する設定がまだ完了していないためうまく作動しません。 2. マウスカーソル用の画像を設定する 次に、マウスカーソルを任意の画像に変えるためのBlueprintを作成します。 ContentDrawerを開き、任意の場所にWidgetBlueprintを作成します。 ( User Interface > Widget Blueprint) 今回は「WBP_MouseCursor」という名前で作成しました。 続いて、マウスカーソルとして使う画像も用意します。今回はグレーの丸い png 画像を用意しました。 同じ階層にインポートを行います。 それではBlueprintの作成に入っていきます。 先ほど作成した「WBP_MouseCursor」を開き、デザイナーエディターで作業を行います。 WidgetBlueprintを開くと最初に表示されている画面がデザイナーエディターなので、そのまま進めます。 まずは左上のpaletteにImageと記述し、検索します。 出てきたImageを左下のWBP_MouseCursorの中に ドラッグ&ドロップ をして配置します。 次に左下に配置したImageを右クリックし、「Wrap With > Canvas Panel」を選択し、 Canvas Panelでラッピングします。 これにより使用する画像のサイズや、位置の調整を行えるようになります。 またImageに「image_数字」という名前が付けられているので、任意の名前に変更します。今回はgray_circleという名前に変更しています。 Imageを追加しただけだと、白い四角い画像が追加されているだけなので、先ほどインポートしたグレーの丸い画像に変更します。 画面右側のBrush配下のImageのセレクトボックスから追加した画像の名前を検索します。 画面右側からサイズも変更します。 菊の花のようになっている部分の中心がカーソルの先端部分になるので、追加したグレーの丸の中心が菊の花の中心になるように画面右のPosition X/Y を変更します。今回は「-32」を記述しました。 下画像のようになっていたら成功です。 続いてグラフエディターに移動します。 3. マウスカーソルの動きに画像が連動するようにする マウスカーソルの動きに先ほど作成した画像を連動させるために、グラフエディターを使用します。 画面右上のGraphを選択し、グラフエディターに移動します。 先ほど作成したグレーの丸い画像をマウスの位置に置くために、一番初めに行ったマウスの座標を取得する処理と同じものを作成します。 「Get Player Controller」のノードを作成し、「Get Mouse Position Scaled by DPI」のノードにつなげます。 次に、先ほどデザイナーで作成したgray_circleを使うために、ノード追加で「Get gray_circle」と検索し追加します。 続いて、追加した「Gray Circle」からピンを伸ばし、「Slot as Canvas Slot」ノードを追加します。 次に、「Slot as Canvas Slot」のReturn Value から「Set Position」ノードを繋ぎ、先ほど作った「Get Mouse Position Scaled by DPI」のLocation X/Y も「Set Position」に繋ぎます。 最後に「Event Tick」と「Set Position」を繋いでグラフエディターでの作業も完了です。 4. 作成した ウィジェット をUEプロジェクトに適用する 今まで作成したWidgetBlueprintを本プロジェクトに追加するために、LevelBlueprintに処理を追加します。 今回は「Event BeginPlay」を使用します。実行ピンを伸ばし「Create Widget 」ノードを作成します。 作成すると属性の中にクラスを選択するセレクトボックスがあるので、先ほど作成した「WBP_MouseCursor」を選択します。 先ほど作成した「Create Widget 」ノードから「Add to Viewport」を繋げます。これでUEをプレイ時にマウスカーソル位置にグレーの丸い画像が表示されるようになります。 実際にプレイ画面を見てみると、マウスカーソルの位置にグレーの画像が表示されていることと、クリックした位置で座標がプリントされていることが確認できます。 5. 作成した ウィジェット をPixelStreamingでも動くようにする 次は、作成したプロジェクトをPixelStreamingでブラウザに反映させていきます。 PixelStreamingの設定方法は こちらの金融ソリューション事業部の山下さんの記事 を参考にしました。 ここまで作成したものをPixelStreaming上で接続すると、マウスクリックを行うたびに ポインター が画面の左上(座標0.0の位置)に移動してしまいます。 これはPixelStreamingを行う際、プレイヤーがUE画面をクリックすると、マウスカーソルをキャプチャしてロックする仕様で起こる事象なので、この設定を変えていきます。 変更するファイルは、 こちらの記事(UE5 PixelStreamingで、WebUI経由でUE Blueprintを操作する) で修正を行ったplayer.htmlになります。 先ほどの記事で「emitUIInteraction」を追加している近くの箇所で下記記述を追加します。 //マウスイベント変更 inputOptions.controlScheme = ControlSchemeType.HoveringMouse; inputOptions.hideBrowserCursor = true; この設定により、カーソルの制御をUE画面上でも行えるようになります。 またカーソルを隠すことにより、UE画面上でのカーソルを設定したグレーの丸い画像に置き換えることができます。 これにより、マウスクリックを行うたびに ポインター が画面の左上(座標0.0の位置)に移動してしまうこともなく、想定通りの挙動をブラウザ上でも行うことができます。 所感 今回はPixelStreamingの プラグイン を用いて、マウスクリックイベント(クリックした座標を表示させる)と、マウスカーソルを任意の画像に変更させてみました。 UEだけでプロジェクトを行う時とPixelStreamingを用いる時で、ユーザーインプットの扱い方があまりよくわかっていませんでしたが、今回の実装でよく理解することができました。 今回の調査を通じて、マウスクリックを使用してキャ ラク ターオブジェクトの移動や、 ECサイト への遷移などができることで、ゲームに慣れていない人もさまざまなシーンでUEを使うことができるのではないかと感じました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://docs.unrealengine.com/4.27/ja/SharingAndReleasing/PixelStreaming/CustomPlayer/ https://papersloth.hatenablog.com/entry/2018/02/06/220632 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はUE5 PixelStreamingで、マウスカーソルを別の画像に変更してクリックイベントを作成します。 前回までの記事でもPixelStreamingについて調べているので、まだご覧になっていない方はそちらも参考にしていただけると嬉しいです。 UE5 PixelStreamingで、WebUI経由でUE Blueprintを操作する UE5 PixelStreamingで、Blueprint経由でWebブラウザを操作する はじめに PixelStreamingを利用してブラウザからUEを操作する利用場面を考えた際、重要になってくるUXのひとつとしてマウスクリックが考えられます。 例えばUE上にショップのようなものを展開し、ユーザーの気になるオブジェクト(商品サンプルなど)がある場合、マウスクリックを通じて ECサイト へ遷移することなどできます。 今回はそのようなPixelStreaming上でのマウスクリックやマウスカーソルに関する調査を行いました。 検証環境/ツール Unreal Engine5.1.1 AWS EC2 Windows _Server-2022-English-Full-Base-2023.01.19 Chrome ver.110.0.5481.177 実装手順 マウスカーソルの座標を取得 マウスカーソル用の画像を設定する マウスカーソルの動きに画像が連動するようにする 作成した ウィジェット をUEプロジェクトに適用する 作成した ウィジェット をPixelStreamingでも動くようにする 1. マウスカーソルの座標を取得 まず初めにマウスがクリックした際の座標を取得するBlueprintを作成します。 適当なプロジェクトを用意して、LevelBlueprintを開きます。 Blueprintでマウスの座標を取得するための関数は2つ存在します。 Get Mouse Position Get Mouse Position Scaled by DPI 今回は下の「Get Mouse Position Scaled by DPI」を使用します。 DPIとは解像度のことで、「Get Mouse Position Scaled by DPI」を使用すると解像度に合わせてマウスの座標を算出してくれます。 「Get Mouse Position Scaled by DPI」を使用してマウスの座標を取得するために、まずはコントローラーの情報を取得するための「Get Player Controller」のノードを作成します。 作成したノードのReturn Value から上記で説明した「Get Mouse Position Scaled by DPI」のノードを作成します。 このLocation X/Y にマウスの座標が入っているので、それぞれを「Print String」でUEに表示させます。 このままでは、まだマウスの座標を表示させるためのイベントが設定されていないので、今回はマウスを左クリックした際に座標を表示させるようにします。 「Left Mouse Button」のイベントノードを作成し、先ほど作成した「Print String」に繋ぐことで、左クリックをした際にマウスの座標をUEに表示するイベントが発火するようになります。 ※この段階でPixelStreamingでプレイをしても後述する設定がまだ完了していないためうまく作動しません。 2. マウスカーソル用の画像を設定する 次に、マウスカーソルを任意の画像に変えるためのBlueprintを作成します。 ContentDrawerを開き、任意の場所にWidgetBlueprintを作成します。 ( User Interface > Widget Blueprint) 今回は「WBP_MouseCursor」という名前で作成しました。 続いて、マウスカーソルとして使う画像も用意します。今回はグレーの丸い png 画像を用意しました。 同じ階層にインポートを行います。 それではBlueprintの作成に入っていきます。 先ほど作成した「WBP_MouseCursor」を開き、デザイナーエディターで作業を行います。 WidgetBlueprintを開くと最初に表示されている画面がデザイナーエディターなので、そのまま進めます。 まずは左上のpaletteにImageと記述し、検索します。 出てきたImageを左下のWBP_MouseCursorの中に ドラッグ&ドロップ をして配置します。 次に左下に配置したImageを右クリックし、「Wrap With > Canvas Panel」を選択し、 Canvas Panelでラッピングします。 これにより使用する画像のサイズや、位置の調整を行えるようになります。 またImageに「image_数字」という名前が付けられているので、任意の名前に変更します。今回はgray_circleという名前に変更しています。 Imageを追加しただけだと、白い四角い画像が追加されているだけなので、先ほどインポートしたグレーの丸い画像に変更します。 画面右側のBrush配下のImageのセレクトボックスから追加した画像の名前を検索します。 画面右側からサイズも変更します。 菊の花のようになっている部分の中心がカーソルの先端部分になるので、追加したグレーの丸の中心が菊の花の中心になるように画面右のPosition X/Y を変更します。今回は「-32」を記述しました。 下画像のようになっていたら成功です。 続いてグラフエディターに移動します。 3. マウスカーソルの動きに画像が連動するようにする マウスカーソルの動きに先ほど作成した画像を連動させるために、グラフエディターを使用します。 画面右上のGraphを選択し、グラフエディターに移動します。 先ほど作成したグレーの丸い画像をマウスの位置に置くために、一番初めに行ったマウスの座標を取得する処理と同じものを作成します。 「Get Player Controller」のノードを作成し、「Get Mouse Position Scaled by DPI」のノードにつなげます。 次に、先ほどデザイナーで作成したgray_circleを使うために、ノード追加で「Get gray_circle」と検索し追加します。 続いて、追加した「Gray Circle」からピンを伸ばし、「Slot as Canvas Slot」ノードを追加します。 次に、「Slot as Canvas Slot」のReturn Value から「Set Position」ノードを繋ぎ、先ほど作った「Get Mouse Position Scaled by DPI」のLocation X/Y も「Set Position」に繋ぎます。 最後に「Event Tick」と「Set Position」を繋いでグラフエディターでの作業も完了です。 4. 作成した ウィジェット をUEプロジェクトに適用する 今まで作成したWidgetBlueprintを本プロジェクトに追加するために、LevelBlueprintに処理を追加します。 今回は「Event BeginPlay」を使用します。実行ピンを伸ばし「Create Widget 」ノードを作成します。 作成すると属性の中にクラスを選択するセレクトボックスがあるので、先ほど作成した「WBP_MouseCursor」を選択します。 先ほど作成した「Create Widget 」ノードから「Add to Viewport」を繋げます。これでUEをプレイ時にマウスカーソル位置にグレーの丸い画像が表示されるようになります。 実際にプレイ画面を見てみると、マウスカーソルの位置にグレーの画像が表示されていることと、クリックした位置で座標がプリントされていることが確認できます。 5. 作成した ウィジェット をPixelStreamingでも動くようにする 次は、作成したプロジェクトをPixelStreamingでブラウザに反映させていきます。 PixelStreamingの設定方法は こちらの金融ソリューション事業部の山下さんの記事 を参考にしました。 ここまで作成したものをPixelStreaming上で接続すると、マウスクリックを行うたびに ポインター が画面の左上(座標0.0の位置)に移動してしまいます。 これはPixelStreamingを行う際、プレイヤーがUE画面をクリックすると、マウスカーソルをキャプチャしてロックする仕様で起こる事象なので、この設定を変えていきます。 変更するファイルは、 こちらの記事(UE5 PixelStreamingで、WebUI経由でUE Blueprintを操作する) で修正を行ったplayer.htmlになります。 先ほどの記事で「emitUIInteraction」を追加している近くの箇所で下記記述を追加します。 //マウスイベント変更 inputOptions.controlScheme = ControlSchemeType.HoveringMouse; inputOptions.hideBrowserCursor = true; この設定により、カーソルの制御をUE画面上でも行えるようになります。 またカーソルを隠すことにより、UE画面上でのカーソルを設定したグレーの丸い画像に置き換えることができます。 これにより、マウスクリックを行うたびに ポインター が画面の左上(座標0.0の位置)に移動してしまうこともなく、想定通りの挙動をブラウザ上でも行うことができます。 所感 今回はPixelStreamingの プラグイン を用いて、マウスクリックイベント(クリックした座標を表示させる)と、マウスカーソルを任意の画像に変更させてみました。 UEだけでプロジェクトを行う時とPixelStreamingを用いる時で、ユーザーインプットの扱い方があまりよくわかっていませんでしたが、今回の実装でよく理解することができました。 今回の調査を通じて、マウスクリックを使用してキャ ラク ターオブジェクトの移動や、 ECサイト への遷移などができることで、ゲームに慣れていない人もさまざまなシーンでUEを使うことができるのではないかと感じました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 https://docs.unrealengine.com/4.27/ja/SharingAndReleasing/PixelStreaming/CustomPlayer/ https://papersloth.hatenablog.com/entry/2018/02/06/220632 執筆: @okazaki.wataru 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )