Gaming Life

一日24時間、ゲームは10時間

私的ゲーム開発技術情報集め ver. 2020年12月

本記事はai_9684_dctソロ Advent Calendar 2020 1日目の記事です。

まだ大学生だった1年前、下記の記事のような、私流の技術情報収集の手段をまとめた記事を書いた。今年、ゲームエンジニアとして就職して以降、当時の情報収集手段とは少し変わってきたので、今年もこの内容で記事を書くことにした。

ai-gaminglife.hatenablog.com

Google検索

疑問に思うことがあればまずはGoogleで検索。プログラムの深い部分を調べたい時は、検索言語を英語に変えると良い。

余談だが、「英語の記事は理解できないから絶対読まない」なんてプログラマは、自身の価値を大きく毀損している。今の時代、たとえ自分で英語が読めなくても、DeepL翻訳やGoogle翻訳があるので何とかなる。特にアプリ版DeepL翻訳は、Ctrl + Cを2回押すだけでそれなりの精度で自動翻訳してくれるのでオススメ。

書籍

信頼と安心の情報源。書籍の情報が全て正しい、というわけではないが、インターネット上で無料で手に入る情報よりは確実に精度が高い。体系立った情報を手に入れたいなら、値は張るが、まず最初に書籍を当たったほうが良いと思う。

これまで、私は技術書は本屋かAmazonで買って読むだけのものだったが、最近もう一つ技術書の付き合い方が増えた。図書館だ。今年、私は横浜に引っ越したのだが、夏頃から最低でも月に1度は横浜市立中央図書館に足を運ぶようになった。中央図書館には、最新の技術書や古典的な名著など沢山の技術書が揃っていることに気づいたからだ。あなたがもし都会に住んでいるのなら、是非一度は近所の大きな図書館に足を運んでみてほしい。沢山の技術書にタダで触れることができる。

Twitter

自分がよく使うフレームワークやアプリなどの第一人者、今風にいうとエヴァチェリストを数人フォローしておけば、最新の情報がすぐ手に入る。一年前はTweetDeckでそういった人のツイートを全て追っかける……ということをよくやっていたが、最近は公式TwitterクライアントでTLを見ることが多くなったので、そうしたストーカーまがいの行為はやってない。

作業中、困ったことがあればGoogle検索に加え、Twitterでも検索するというのは今も続けている。それで業務中助けられた事が何度かあった。

Inoreader(RSSリーダー

今年に入って、Inoreaderを使った情報収集を始めた。これがなかなか良い。これまで取りこぼしていた情報を集めることができるようになった。最近RSSを使う人は減っていると聞くが、私には性に合った。

以下に、今購読しているサイトで、特に有用だと思うサイトを挙げる。

プログラミング関連

IT News

はてなブックマーク

はてなブログを使っておきながら言うのもなんだが、今からはてブを見るというのはオススメできない。はてブの技術カテゴリは、有用な情報を集める事ができるが、Web系の技術記事ばかりがトレンドに上がるし、雑音(ノイズ)が多すぎる。はてなブックマークという場所がこの一年で更に政治臭が強くなったので、その辺り耐性のない人は、使わないほうがいい。

なお私は今更はてブやめれなくなったので今後も使います。

NotionのWebクリッピング

最強のAll in Oneメモツールには、Webクリッピング機能が備わっている。ChromeFirefox拡張機能ですぐにNotion上にWebサイトをクリップできる。私は、上記のサービス・ニュースサイトで集めた情報は、ほぼすべてNotionのWeb クリッピングで収集している。

まとめ

今年はQiitaの対抗サイトとしてZennが登場するなど、技術トレンドを追う手段は強烈な速さで移り変わっている。情報過多のこの時代、どれだけノイズを排してほしい情報を得るかが大切だと思っている。今後も、トレンドに合わせて、情報収集の手段を適宜アップデートしていくことになるだろう。

VS 16.7以前では一時オブジェクトのアドレスを&演算子で取得してもエラーが出なかったらしい

Visual Studio 2019のバージョンを16.8に上げてから、DirectX12のコードをビルドしてみたら、これまでコンパイルできていたものができなくなっていた。そのコードがこれ。

hr = m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), // ここでC2102エラー
            D3D12_HEAP_FLAG_NONE,
            &depthBufferDesc,
            D3D12_RESOURCE_STATE_DEPTH_WRITE,
            &depthClearValue,
            IID_PPV_ARGS(&m_depthBuffer)
        );

docs.microsoft.com

C2102: '&'に左辺値がありません。

エラーの原因は、一時オブジェクト(右辺値)である CD3DX12_HEAP_PROPERTY のアドレスを、&演算子で取得しようとしたこと。よく考えれば、一時オブジェクトのアドレスを取得なんてしてはいけないことだと思う。なので、試しに他のコンパイラで似たようなコードを書いてみた。

#include <iostream>

struct A { int a, b, c, d; };

A make_A() { return A{}; }

void func(A*) {}

int main() {
    func(&(A{}));
    func(&make_A());
}

wandbox.org

gccでもclangでも、このコードはコンパイル出来なかった。右辺値のアドレスを取ろうとするのは駄目みたい。

で、MSVCのオンラインコンパイルも可能な、Compiler Explorerでも同じコードをコンパイルしてみた。すると、MSVCだけコンパイルが通ることが確認できた。

godbolt.org

どうもVisual Studioが間違っていて、バージョン16.8からコンパイルが通るようになったみたい。

ちなみに手元で試した限り、Visual Studio 2017では、このコードのコンパイルが通った。

UE4でNVIDIA NSight Graphicsを使ったGPUプロファイリングをしてみる

本記事は、「Online Game-Tech LT 2020」のLT発表の補足資料として用意しました。登壇一日前で時間がない中で本記事を執筆しているため、必要最低限の説明だけにとどまっていることをご容赦ください。時間があればそのうち修正します。

connpass.com

NVIDIA NSight Graphicsとは

NVIDIAが開発したグラフィックアプリケーション用のプロファイラ。RenderDocと比べて、GPUの低レイヤの調査に向いている。

セットアップ

今回は、UE4で作成したゲームパッケージでプロファイルするのではなく、エディタ上でプロファイルする。製品版に近い状態でプロファイルしたい場合は、Developmentパッケージを作成し、それをプロファイルするのがよい。

公式サイトからNVIDIA NSight Graphicsをダウンロードする(以下NSightと表記)。 developer.nvidia.com

プロファイルする時は、必ず管理者権限で実行すること。そうしないと警告メッセージが出て、詳細な調査ができない。

起動するとこのようなウィンドウが表示される。「Create New Project」を選択し、プロファイルのための新しいプロジェクトを作成する。 f:id:ai_gaminglife:20201031210430j:plain

プロセス立ち上げのための設定ウィンドウが立ち上がったら、「Application Executable」にUE4Editor.exeのパスを、「Commnad Line Arguments」にプロファイルしたいuprojectのパスと-game引数を記述する。なお、私の環境ではなぜか「-dx12」引数をつけないとプロファイルできなかった。そんなことをしなくても普通は出来るはずなんだけど……もし「-game」だけで起動しない方がいれば試してみてください。

UE4Editor.exeはデフォルトで、「C:\Program Files\Epic Games\UE_4.「バージョン番号」\Engine\Binaries\Win64\UE4Editor.exe」のパスにある。

f:id:ai_gaminglife:20201031211100p:plain

「Launch Frame Debugger」を押すとUE4Editorが起動する。プロファイルしたいシーンに移動したら、NSightウィンドウで「Capture for Live Analysis」ボタンをクリックする。すると、下図のような画面が立ち上がる。これを使ってフレーム単位の詳細なプロファイリングを行っていく。

f:id:ai_gaminglife:20201031211938j:plain

実際のNSightを使ってのプロファイリング手順は「Unreal Fest 2019」講演が詳しいので、そちらを参考のこと。

www.slideshare.net

【C++20】constメンバ関数の実装を要求するconcept

C++20から導入されるコンセプトは、requires節を使用して、型に対してあるメンバ関数の実装を要求することが出来る。 そのメンバ関数に対して、const関数であることを要求できないかと考え、実装してみた。

#include <type_traits>

template <typename T>
concept Drawable = requires(T x) {
    // 型がdraw() const:関数を持つことを要求する
    std::declval<std::add_const_t<T>>().draw();
};

template <Drawable T>
void f(T& x) {
    x.draw();
}

struct A {
    void draw() const {}
};
struct B {
    void draw() {}
};
struct C {
    void func() {}
};

int main() {
    A a;
    B b;
    C c;
    f(a);
    f(b); // draw()関数が非constなのでコンパイルエラー
    f(c); // draw()関数をもたないのでコンパイルエラー
}

wandbox.org

※追記

他の書き方もあるみたい。

// conceptの引数型をconst型にする
template <typename T>
concept Drawable = requires(const T& x) {
    { x.draw() };
};

// 非constメンバ関数の実装も同時に制約条件に加えたい場合
// 1.
template <typename T>
concept ActorClass = requires(const T& x, T& y) {
    { x.draw() };
    { y.update() };
};

// 2.
template <typename T>
concept ActorClass = requires(const T& x) {
    { x.draw() };
} and
requires(T& x) {
   { x.update() };
};

// 3.
template <typename T>
concept ActorClass = requires(const T& x) {
    { x.draw() };
    { const_cast<T&>(x).update() };
};

個人的には、2の書き方が記述量こそ多いが一番直感的かなと思う。が、どれも特に挙動に違いはないと思われるので、好きなのを使えばいい。

Visual Studioのコードスニペットのshortcut名にはハイフンは使えない

Visual Studioコードスニペットを自作していたら、表題の件にハマったのでメモがてら共有。

qiita.com

上記の記事で紹介されている Visual Studio Snippet Generatorで、スニペットを作ったのだが、Shortcutにハイフン(-)を入れると、コードスニペットが正しく機能しなくなった。

tools.unitycoder.com

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>commentblock-test</Title>
      <Shortcut>commentblock-test</Shortcut>
      <Description>create basic style comment block</Description>
      <Author>ai</Author>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="false"></Literal>
      </Declarations>
      <Code Language="cpp"><![CDATA[// ---------------------------------------------------------------- //
//  $end$
// ---------------------------------------------------------------- //]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

このXMLVisual Studioにインポートして commentblock-test を入力してTabキーを押すと、正しく動かない。

f:id:ai_gaminglife:20200813201649j:plain f:id:ai_gaminglife:20200813201651j:plain

色々試した結果、Shortcutからハイフンを取り除くと、正しく動作するようになった。

↓改良後のXML

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>commentblockTest</Title>
      <Shortcut>commentblockTest</Shortcut>
      <Description>create basic style comment block</Description>
      <Author>ai</Author>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="false"></Literal>
      </Declarations>
      <Code Language="cpp"><![CDATA[// ---------------------------------------------------------------- //
//  $end$
// ---------------------------------------------------------------- //]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

f:id:ai_gaminglife:20200813201707j:plain f:id:ai_gaminglife:20200813201712j:plain

ちなみに

Visual Studio Snippet Generatorは、デフォルトでC#用のスニペットファイルを出力する。C++などでそのスニペットを使用したいときは、 <Code Language> をcppなどに変更する必要がある。

参考

docs.microsoft.com

WPF勉強中(1)最初に参考にした資料とか疑問点とか

前回の記事以来、時間を見つけてはWPFの学習を進めている。しかし、ただ黙々と一人学習していてもモチベが続かないので、定期的にブログで進捗や参考にしている資料、疑問点を文章化していこうと思う。

参考にしている資料

» WPF 学習用ドキュメント作りました

最初の学習に利用した資料。「WPF 入門」「WPF 実践」「WPF 逆引き集」の内、「WPF 実践」しか読んでないが、非常に良かった。私はあるフレームワークを最初に学ぶ時、参考コードの設計をやたら気にしてしまうタイプなのだが、この資料のサンプルコードはMVVMのスタイルを守っているので、かなり肌にあっていた。

  • WPF 4.5入門

www.slideshare.net

日本語でWPFについて調べると、必ずヒットする「かずきのBlog@hatena」の著者が執筆した、WPFの入門資料。全部は読んでないが、ざっと流し見した感じ、WPFの機能について順を追って丁寧に説明されており良さげ。何より現役マイクロソフト社員が作成した資料ということもあり、信頼ができる。

特に参考になったのは「6.2 データバインディングを前提としたプログラミングモデル」の章。MVVMライブラリであるPrismの簡単な使い方が学べた。

  • XAML Controls Gallery

www.microsoft.com

マイクロソフト謹製、XAMLのサンプルをまとめたアプリ。このコントロールでどんな表現ができるのだろう、と確認したい時によく使う。ただ問題点が一つありまして(後述)……

github.com

マイクロソフト謹製のWPFのサンプル集。大量のサンプルコードが公開されている。MVVMデザインは(見た限り)無視して、初学者に理解しやすい形でコーディングされてるっぽい。

作ったもの

f:id:ai_gaminglife:20200721011956g:plain 実用性は皆無の習作。一応MVVMを意識してコーディングした。

疑問点

どうもXAML Controls Galleryは、UWP(WPFの後継的扱いのライブラリ)で作られているっぽい。一応下記の手順で、UWPのコントロールWPFで扱うことはできるらしいのだが、うまくいかなかった。その内リベンジしたい。

docs.microsoft.com

  • Prism(もしくはLivet)の使い方

「WPF4.5入門」で、BindableBaseとDelegateCommandの使い方は大体把握したが、それ以外はまだからっきし。WPFでそこそこの規模のアプリケーションを作るなら、PrismやLivetといったMVVMフレームワークを使うのが普通らしいので、使えるようにしたい。どこかにサンプル無いかなあ。

  • データの永続化

SQ Liteとかでデータを永続化できるらしいけど……外に公開するようなツールを作る、という段階まで来たらこれも意識しなきゃ駄目っぽい。まだそこまで出来そうにないので優先度は低め。

まとめ

というわけで、現時点での進捗をまとめてみた。思い描くようなツールを実装できるまでには、まだまだ時間がかかりそう。

DirectX12の魔導書を読んだ

『DirectX12の魔導書』を大体読み終わったので感想。

自分はDirectXOpenGLなどのグラフィックスAPIをほぼ触ったことがなかったので(昔DX11で三角ポリゴン出したくらい?)、勉強として買った。

本の構成は以下の通り。

  • Chapter1 前提となる知識とDirectX12の概略
  • Chapter2 グラフィックスパイプラインと様々なシェーダー
  • Chapter3 初期化から画面クリアまで
  • Chapter4 ポリゴンの表示
  • Chapter5 ポリゴンにテクスチャを貼り付ける
  • Chapter6 行列による座標変換
  • Chapter7 PMDの読み込みとモデルの表示
  • Chapter8 マテリアル
  • Chapter9 リファクタリング
  • Chapter10 スキニングとアニメーション
  • Chapter11 インバースキネマティック(IK)
  • Chapter12 マルチパスレンダリング
  • Chapter13 影行列とシャドウマップ
  • Chapter14 マルチレンダーターゲットとその応用
  • Chapter15 スクリーンスペースアンビエントオクルージョン(SSAO)
  • Chapter16 imguiの利用
  • Chapter17 Effecseerライブラリの利用
  • Chapter18 DirectXTKの利用(文字列表示)

自分はChapter13以降、実装がしんどそうだったので軽く流し読みした程度。その代わり、Chapter12まではかなり時間をかけて実際にコーディングして実装した。(ただしChapter11のIKは難しくて断念した)

以下その頃の作業記録ツイート。

本書は高校数学とC++の最低限の知識がある読者を想定して描かれている。ただ、自分が読んだ限りそこまでの知識でこの本を完走するのは厳しく、追加でグラフィックスパイプライン(頂点シェーダとかピクセルシェーダとか……)など、現代のコンピュータグラフィックスに求められる基礎知識を持っておいたほうが良いと感じた。(副読書としてCGエンジニア検定の参考書あたりを持っておくのがよさそう)

2020年7月現在、DirectX12に関する日本語の参考資料は公式のリファレンスぐらいしかない(追記: すらりんラボさんの本があった)。そのため本書の発売前は、3Dモデルの描画まで実装したら、後は影を描画して終わりくらいの分量かなーと思っていた。

ところが実際には、DirectX12の初期化から始まり、ポリゴンを描画し、3Dモデルの描画にアニメーション、果てはポストプロセスの実装とかなり奥深くまで解説している。ここまでの分量の実装を一冊で解説する本は、DirectX11の解説書も含めて心当たりがない(OpenGLならあるかも)。この分量をこなすのには時間はかかったが、ポストプロセスを使ってアウトラインもどきのシェーダーが実装できた時は感動した。

誤植がやたら多かったのはマイナスポイント。また、Github経由で動作確認が取れているサンプルコードが公開されているのだが、それもある章を境にほぼ別モノに書き換わっていて、対応を取るのに苦労した。

しかしながら、誤植などの対応を取る作業がむしろDirectX12の理解を深める一助となったところがある。誤植がほぼ無い書籍だったら、サンプルコードを写経するばかりで、ほぼ理解できずに終わっていたと思う。なのでヨシ(?)。

総じて、DirectX12の入門書として充分人に勧められるクオリティだった。どうしてもDirectX12を習得しなければならない人や、DirectX12そのものの難解さや書籍中の誤植も笑って許せる、マゾ気質の人は是非買って挑戦してみることをおすすめします。

……これ推薦文になってるのか?