世界を数式で描く 02 / 05 もくもく会トップ
SERIES 世界を数式で描く ― 02

Blender は何を省略して絵を描くのか物理ベース CG の近似

Blender の画像は「物理ベース」と呼ばれます。でも、光の物理を厳密に計算しているわけではありません。人間の目に分からない所を上手に省いています。この記事では、どこを省いているのかを、実際のレンダーと触れる実験で確かめます。

この記事で持ち帰る3行
  1. レンダリングは、光の積分を近似で解く計算
  2. 計算を落とす手口は4種類ある
  3. CG は物理に対してではなく、「人間の視覚」に対する近似の理論

コラム:Blender とは

Blender は、無料で使えるオープンソースの総合3DCGソフトです。形を作る(モデリング)、見た目を決める(材質・照明・レンダリング)、動かす(アニメーション・物理シミュレーション)、仕上げる(合成・動画編集)までを1本でこなします。ほぼすべての操作を Python で書けるので、AI にコードを書かせて動かすこともできます。04の点群も、Blender の Python で作りました。

レンダリングの方式は2つあります。光の道筋を追って計算する Cycles と、ゲームと同じ仕組みで速く描く EEVEE です。この記事で扱うのは主に Cycles です。

生い立ちも少し変わっています。オランダのアニメーション会社 NeoGeo の社内ツールとして、Ton Roosendaal が1994年1月2日に最初のソースファイルを書きました。NeoGeo の後継会社 NaN が2002年初めに閉じると、Roosendaal は同年5月に非営利の Blender 財団を作り、寄付キャンペーンで7週間に11万ユーロを集めて投資家から権利を買い戻しました。2002年10月13日に GNU GPL のオープンソースとして公開され、今も財団を中心に開発が続いています。

出典:blender.org「History」(2026年10月21日に確認)

記述の層:Blender は世界を何で書いているか

書く対象使う数学ひとことで
形頂点のベクトルと、それをつないだ面(メッシュ)形は点の座標の表
姿勢4×4の行列(回転にはクォータニオンも)平行移動も回転も、行列の掛け算1つにまとめる
光レンダリング方程式(積分方程式)ある点から出る光=自分で光る分+周りから来た光の反射
材質BRDF(反射の仕方を表す関数)エネルギーを増やさない、入れ替えても同じ、という制約を守る
動き微分方程式を時間で刻んで解く剛体・布・流体を、短い時間ごとに少しずつ進める

レンダリング方程式を言葉で読む

画面の1画素の明るさは、「そこに写る点から、カメラの方向へ出ていく光」です。その光は、自分で光っている分と、周りのあらゆる方向から届いた光が、材質に従って反射した分の合計です。ところが「周りから届いた光」も、別の点から出た光なので、同じ式がまた中に現れます。光が何度も跳ね返るので、式が入れ子になり、紙と鉛筆では解けません。

数式で見る
L_o(x, ω_o) = L_e(x, ω_o) + ∫_Ω f_r(x, ω_i, ω_o) · L_i(x, ω_i) · (ω_i · n) dω_i

L_o は点 x から方向 ω_o へ出る光、L_e は自己発光、f_r は材質(BRDF)、L_i は方向 ω_i から入る光、n は面の法線、Ω は面の上側の半球です。L_i が別の点の L_o なので、式が再帰的になります。この形で書いたのは Kajiya の論文「The Rendering Equation」(SIGGRAPH 1986)です。

Cycles は、この積分を乱数で近似します。画素ごとに光の道筋(パス)をランダムに何本も追いかけ、その平均を明るさとします。これをパストレーシングと呼び、追いかける本数をサンプル数と呼びます。

計算を落とす4つの手口

手口例捨てているもの
モデルを単純にする光をまっすぐな線として扱う。色を RGB の3つの数で表す回折や干渉(光の波の性質)、スペクトル(色の細かい成分)
連続を飛び飛びにする(離散化)形をメッシュで、時間をステップで表すなめらかさ。誤差や、計算の暴走(下の V02-3)
乱数で見積もる(確率的推定)パストレーシング=モンテカルロ積分厳密な答え。ノイズは 1/√N でしか減らず、半分にするにはサンプルが4倍いる
構造と知覚を利用するBVH(当たり判定を速くする木構造)、重点サンプリング、AI によるノイズ除去人間に見えない差

ノイズはなぜ 1/√N でしか減らないか

サンプルを増やすと、画像のざらつき(ノイズ)は減ります。ただし、減り方は遅く、サンプルを4倍にして、やっとノイズが半分です。これは、ランダムな見積もりの平均をとるときの一般的な性質です。まず実物で確かめましょう。

V02-1実例

同じ場面を、サンプル数だけ変えてレンダーする

何を見るか04の地下通路を、同じ視点・同じ設定で、サンプル数だけを変えて Blender でレンダーした画像です。 触ってみようスライダーを動かして、暗い天井や壁のざらつきが減っていく速さを見る。最後の「16+ノイズ除去」と1024を見比べる。
16サンプルでレンダーした地下通路
サンプル数誤差(RMSE)前の行との比レンダー時間
160.0956—3.9秒
640.05440.576.4秒
2560.02780.5139.2秒
10240.01480.5367.1秒
16+ノイズ除去0.0109—8.7秒
Blender 5.2.2・Cycles(Mac の GPU、Metal)・640×640画素・光の反射は最大4回・サンプル数を固定(適応サンプリングは切る)・乱数の種は0。誤差は、4096サンプルの画像を正解の代わりにして、0〜1 に直した画素値で測った二乗平均平方根誤差です。4倍ごとの比は理屈では0.5、実測は0.51〜0.57(両対数の傾き −0.45)でした。4096サンプルの画像にも少しノイズが残ること、表示用の明るさの変換を通した画素で測っていることが、ずれの理由と考えられます。

ノイズ除去(デノイズ)をかけた16サンプルの画像は、数字の上では1024サンプルより誤差が小さくなりました。ただし、ノイズ除去は細かい模様をぼかして「なめらかで、ありそうな画像」に寄せる処理です。誤差の数字が小さくても、細部が正しいとは限りません。4096サンプルの画像と拡大して見比べると、ノイズ除去版では壁のコンクリートのむら(場面に付けた模様)が消えて、のっぺりした壁になっていました。ノイズと細かい模様を区別できず、模様まで消してしまったのです。

なぜ 1/√N なのかを、もっと小さな場面で、計算の中身まで見えるようにしたのが次の実験です。

V02-2

モンテカルロのノイズ:サンプルを積むと、誤差はどう減るか

何を見るか天井の四角い照明に照らされた床を、真上から見た画像です。球が影を落としています。床の各点で「照明のどこか1点を乱数で選び、そこから光が届くか」を何度も試し、平均をとって明るさを決めます。右のグラフは、試した回数 N と、正解(4096回の層別サンプリング)との誤差です。 触ってみよう再生して、影のふち(半影)のざらつきが消えていく様子を見る。グラフの点が、傾き −1/2 の点線に沿うかを確かめる。
画面に入ると準備します
誤差の傾きは、N = 4 以降の点に直線を当てはめて求めています。正解の画像も同じ式を4096回(64×64の層別)で平均したもので、厳密解ではありません。
数式で見る

N 回の独立なサンプルの平均は、ばらつき(標準偏差)が 1 / √N に比例して小さくなります。

誤差 ∝ σ / √N  →  log(誤差) = −½ · log(N) + 定数

だから両対数グラフでは、傾き −1/2 の直線になります。ノイズを半分にするには N を4倍、10分の1にするには100倍にする必要があります。重点サンプリングや層別サンプリングは、σ(1回あたりのばらつき)を小さくする工夫です。

RGB の3つの数で足りる理由

現実の光は、波長ごとに強さが違う、なめらかな分布(スペクトル)です。数字で書けば無限に多くの値が要ります。それなのに CG は、赤・緑・青の3つの数で色を表します。

これで足りるのは、人の目が色を感じる細胞(錐体)が3種類しかないからです。目は、届いた光を3つの数に縮めてから脳へ送っています。だから、スペクトルが違っても、3つの数が同じになる光は同じ色に見えます(条件等色)。CG はこの性質を使い、最初から3つの数で計算しています。

つまり CG の近似は、物理に対してではなく、「人間の視覚」というものさしに対して作られています。「物理ベース」と「物理的に厳密」は別物です。プリズムで光を分けるような場面や、虹色に光る薄膜のような現象は、3つの数では正しく描けません。

時間を刻むと何が起きるか

動きの計算(物理シミュレーション)では、時間を短いステップに区切って、少しずつ状態を進めます。区切り方の工夫を数値積分と呼びます。区切り方が素朴だと、本当は一定のはずのエネルギーが増え続け、ばねや布が「爆発」します。

V02-3

同じばねを、3つの数値積分で動かす

何を見るか同じばね(質量1・ばね定数1・摩擦なし)を、3つの方法で同時に動かします。本当はエネルギーが一定で、同じ振れ幅で振動し続けるはずです。下のグラフはエネルギーの推移です(最初を1とする)。 触ってみよう時間の刻みを大きくする。陽的オイラー法だけ、振れ幅とエネルギーが増え続ける。
3つとも、1ステップで使う計算の量はほぼ同じです。違うのは、位置と速度をどの順番で更新するかだけです。
数式で見る
陽的オイラー:x ← x + v·Δt, v ← v − x_old·Δt
シンプレクティック・オイラー:v ← v − x·Δt, x ← x + v_new·Δt
速度ベルレ:v ← v − ½x·Δt, x ← x + v·Δt, v ← v − ½x_new·Δt

陽的オイラー法では、1ステップごとにエネルギーがちょうど (1 + Δt²) 倍になります。残りの2つは、エネルギーが少し揺れますが、増え続けはしません。物理の法則がもつ構造(位相空間の体積を保つ)を、計算の順番で守っているからです。

用語集

レンダリング
3Dの場面から画像を計算すること
レンダリング方程式
ある点から出る光を、自己発光と周りからの光の反射の和として書いた式
BRDF
光がある方向から来たとき、別の方向へどれだけ反射するかを表す関数。材質の正体
パストレーシング
光の道筋をランダムに何本も追い、その平均で明るさを決める方法
サンプル数
1画素あたりに追う光の道筋の本数
モンテカルロ法
乱数を使った試行の平均で、積分などの値を見積もる方法
重点サンプリング
答えに効く所を多めに試して、ばらつきを減らす工夫
デノイズ
ノイズの残った画像を、なめらかに整える処理。Blender では AI を使ったものがある
条件等色
スペクトルが違うのに、人の目には同じ色に見えること
数値積分
時間を短いステップに区切り、状態を少しずつ進めて動きを計算すること

この記事の問い