先日「ポケットモンスター Let's Go! イーブイ」が発売開始されましたが、Blenderも次バージョンの2.8でEEVEEをリリースする旨が Blender 2.80 Release Notes に載っています。
Emacsの環境
私はピカチュウ版を買いましたが、ゲームをし続ける技量は既になく、気分転換にBlenderのコードリーディングをしています。このコードリーディングはちょっとした出来心で始めたのですが、ふと気がつくと init.el
には以下を追記していました。
;; helm-ag or ripgrep
(setq helm-ag-base-command "rg -S --vimgrep --no-heading")
(global-set-key (kbd "C-x g g") 'helm-ag)
どうした事でしょう。 ripgrep
をEmacsから実行するために helm-ag
をインストールし設定を追加していたのです。この設定をし終えた頃にトキワの森を通過した記憶があります。
ちなみに私は以下の環境でEmacsを動かしています。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G3025
$ emacs -nw # GNU Emacs 26.1
EEVEEをどこから読み始めるべきか
普段はSwiftかShell Scriptぐらいしか読み書きしないものですから、Cのソースコードは未知領域でして、さてどこから読み始めるべきでしょうかと考えるわけです。
とりあえず何の意味もなくビルドをしてみるかと思い、数分Google検索をして Building Blender/Mac を見つけ、ビルドを成功させます。
$ mkdir ~/blender-build
$ cd ~/blender-build
$ git clone https://git.blender.org/blender.git
$ cd blender
$ make update
$ make
ビルド成功後、Emacsでblenderのsourceディレクトリに移動して以下の操作をします。
-
M-x helm-ag
-
Patternを問われるので、eevee と入力する
その結果が下図になりますが、2526件ヒットしています。
しかし、ポケモンをやっていることも考えると全てに目を通すのは困難です。
どれから見れば良いのかわかりませんが、ファイル名にエンジンと書いてあるぐらいですから中核を成していそうな eevee_engine.c
を開きます。
色々とincludeされていますがファイル冒頭の段階で次の2点が気になりました。
-
defineされた
EEVEE_ENGINE
-
static関数の
eevee_engine_init
例えば、defineされている EEVEE_ENGINE
は何に使っているのだろうと思ったとして、Emacsで以下の操作をします。
-
M-x helm-ag
-
Patternを問われるので、EEVEE_ENGINE と入力する
上の結果が下図です。
どうやら eevee_engine.c
の474行目にさらに情報がありそうです。開いてみます。
RenderEngineType DRW_engine_viewport_eevee_type = {
NULL, NULL,
EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES | RE_USE_PREVIEW,
NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL,
&EEVEE_render_update_passes,
&draw_engine_eevee_type,
{NULL, NULL, NULL}
};
DRW_engine_viewport_eevee_type
という変数が宣言されていますが、これは誰が参照しているのでしょうか。Emacsで以下の操作をします。
-
M-x helm-ag
-
Patternを問われるので
DRW_engine_viewport_eevee_type
と入力する
上の結果が下図です。
この図から以下のように見えます。
-
draw_manager.cとeevee_materials.cで参照されている
-
eevee_engine.hでDRW_engine_viewport_eevee_typeをexternしているとわかる
ところで DRW_engine_viewport_eevee_type
の型である RenderEngineType
は何者なのでしょうか。Emacsで以下の操作をします。
-
M-x helm-ag
-
Patternを問われるので、RenderEngineType と入力する
上の結果が下図です。
これを見て私は以下のように思いました。
-
RenderEngineTypeという型がある
-
RenderEngineTypeという構造体がある
そこで typedef struct
をしているコードを探すことにしました。Emacsで以下の操作をします。
-
M-x helm-ag
-
Patternを問われるので、RenderEngineType と入力する
-
検索結果でPatternを問われるので typedef struct と入力する
上の結果が下図です。
RE_engine.h
に RenderEngineType
の定義があります。開いてみます。
// blender/render/extern/include/RE_engine.h
typedef struct RenderEngineType {
struct RenderEngineType *next, *prev;
/* type info */
char idname[64]; // best keep the same size as BKE_ST_MAXNAME
char name[64];
int flag;
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Depsgraph *depsgraph);
void (*render)(struct RenderEngine *engine, struct Depsgraph *depsgraph);
void (*bake)(struct RenderEngine *engine, struct Depsgraph *depsgraph,
struct Object *object, const int pass_type,
const int pass_filter, const int object_id, const struct BakePixel *pixel_array, const int num_pixels,
const int depth, void *result);
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node);
void (*update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
struct DrawEngineType *draw_engine;
/* RNA integration */
ExtensionRNA ext;
} RenderEngineType;
さて、ここから更に読み進めていきたいところですが、この辺で。