BSDF やシェーダの振る舞いを調べるために Cycles を standalone でビルドしデバッグできるようにします.
ソースコード
git://git.blender.org/cycles.git
ビルド
cmake が用意されています.
Standalone でも GUI 周りが必須のようで, OpenGL required などになっていますので注意ください.
純粋に CLI 実行には対応していません.
Ubuntu 16.04 では, 依存ライブラリは apt でだいたい入ります.
(e.g. libpugixml-dev)
WITH_CYCLES_LOGGING
を On にしてログ出力ができるようにしておきます.
(WITH_CYCLES_DEBUG
も On がおすすめかも)
最小依存 Cycles
aarch64 対応もかねて OpenGL や OpenImageIO などの依存ライブラリを決して最小 CLI ビルドできるようにしたブランチを作りました. OpenGL インストールがうまくいかないとか, サーバーで動かしたいなどのときに利用ください.
cmake 設定は
を参考ください.
$ ./cycles --output bora.png --samples 32 input.xml
のように使います. 現状 8bit PNG 出力のみ対応しています. デフォルトでは無限に progressive path tracing するので, --samples
で回数を指定しましょう.
シーンファイル
入力シーンとして xml を用意する必要があります.
examples
にサンプルがいくつかあります.
形状データを xml に変換は面倒かもしれませんね(Blender から cycles 用の xml をエクスポートする機能はないっぽい?)
などありますが開発は止まっています.
BSDF closure 定義
OpenShadingLanguage や Blender での node editor によるシェーダ定義の知識があるとします.
<diffuse_bsdf> ... </diffuse_bsdf>
のように tag で定義します.
使える closure の名前とパラメータは
src/render/nodes.cpp
にあります.
subsurface_scattering
の場合は BSDF
のカテゴリではなく BSSRDF
のカテゴリに所属するため, ノードの接続を記述するときは bssrdf
を使います. e.g.
<connect from="monkey_closure BSSRDF" to="output surface" />
光源定義
shader tag で定義します.
src/render/light.cpp
で定義がわかります.
実行する.
$ ./cycles input.xml
で動きます. CUDA など有効になってビルドされている場合, --device CPU
などとして明示的に利用するデバイスを指定できます.
レンダリングをすると画面表示用に UI が出ます.
あまり機能はありませんが, i
キーで interactive モードになり, 視点をちょこっと変えることができます
h
キーでヘルプが出ます.
サンプルシーン
頂上からの平行光源 + subsurface scattering です.
examples/scene_monkey.xml
を参考にしています.
<cycles>
<!-- Camera -->
<camera width="800" height="500" />
<transform translate="0 0 -4" scale="1 1 1">
<camera type="perspective" />
</transform>
<shader name="dirlight_shader">
<emission name="emission" color="1.0 1.0 1.0" strength="1" />
<connect from="emission emission" to="output surface" />
</shader>
<state shader="dirlight_shader">
<light type="distant" dir="0 -1 0" size="0.0" />
</state>
<!-- Monkey Shader -->
<shader name="monkey">
<subsurface_scattering name="monkey_closure" falloff="random_walk" radius="1.0, 0.2, 0.1" scale="1.0"/>
<connect from="monkey_closure BSSRDF" to="output surface" />
</shader>
<!-- Objects -->
<transform rotate="180 0 1 1">
<state interpolation="smooth" shader="monkey">
<include src="./objects/suzanne.xml" />
</state>
</transform>
</cycles>
ログを仕込む
LOG, VLOG などの glog っぽいマクロが使えます.
util/util_logging.h
をインクルードして
VLOG(1) << "color = " << color;
などとします.
kernel あたりに仕込むと再コンパイルがたくさん発生するので注意.
このログを表示するには --debug
オプションを起動時に指定します.
--verbose
でレベルを指定します. たとえば上の VLOG(1)
ですと,
--debug --verbose 0
ではログが出力されないようになります.
Fresnel について
Cycles では OpenShadingLanguage と一緒にするためか, Fresnel は mix シェーダなど BSDF の外部で定義するのが基本となります.
注目すべきソースコード
- kernel/ BSDF や シェーダの実装があります. CPU/GPU 共通で書かれているようです.
- kernel/svm/svm_closure.h シェーダ設定(shader graph など)の入力を個別の BSDF(closure) カーネルに変換したりします. たとえば Principle BSDF の場合は diffuse, specular(microfacet), subsurface などに分解します.
- kernel/closure 各 closure(BSDF)や補助ユーティリティ関数の実装があります.
Subsurface について
random walk
ランダムウォークでは経路としては分岐せずに一つだけ追跡します.
また, sss したあとの経路で再度 sss 物体に入ると計算が複雑になって noise が出やすいので, 一度 sss した経路では残りは BSDF 反射(diffuse や specular など)だけを考慮するようにしています.
(PATH_RAY_DIFFUSE_ANSCESTOR フラグが立つ)
diffusion(Chiristensen-Burley)など
cubic, gaussian, burley(Christensen-Burley) は diffusion ベースのアルゴリズムを使います.
PBRT-v3 などと違い, 交差するシェーディングポイント全てで経路追跡をする模様(なのでふるまいを追うのが大変そう)