cosq e - Tri Ace research
Download
Report
Transcript cosq e - Tri Ace research
物理ベースレンダリングを実装するときに役に立つこと
五反田義治
(株) トライエース 研究開発部
物理ベースレンダリングとは?
• 物理ベースレンダリング(PBR)
– レンダリング方程式の解を正しく求めること
– 各種パラメータが物理的要求を満たしていること
本日のトピック
• レンダリング方程式
– 今更ながらレンダリング方程式について
Lo (x, ) Le (x, ) f r (x, , ) Li (x, )( n)d
より正しい物理ベースへ
• 現行機でより複雑な計算が可能に
– 従来だったら適当に処理していた部分がより
物理的に正しい式を実装可能に
– その実装はどのくらい物理的に正確?
• 検証抜きでad-hoc的に対応していないか?
本当にエイリアシング?
• PBRでより問題になるエイリアシング
– とりあえずアンチエイリアシング
• Post-processing anti-aliasing
• Temporal anti-aliasing
– でもそのエイリアシングは本当に物理ベースの
せい?
• あなたのレンダリング方程式は正しく実装されている?
困ること(1)
• GGX
– Roughness(s)が0に近い時にどうなる?
lim
s 0
?
s
2
(1 (s 1) cos h)
2
2
2
困ること(2)
• Smith masking and shadowing function
– Grazing anglesでどうなる?
lim
e
2
?
2
1
1
2
2
cos e cos l 1 s
1 1 s
1
2
2
cos
cos
e
l
レンダリング方程式を解く
• [CEDEC 2011] レンダリストのための
物理ベースレンダリング – 基礎理論編 –
– ピクセルや絞りも考慮する
– 本来なら(露光)時間も
1
pixel ( x p )
2
La
pixel
dAp i (x )( n p E) dAa
4
Aa
レンダリング方程式
• レンダリング方程式は放射輝度を入力(Li)
して放射輝度(Lo)を出力する
– Pixelに格納されているのは放射輝度?
• 本来はエネルギー
• 放射輝度は放射束の2階微分
• 放射束はエネルギーの時間微分
レンダリング方程式
• レンダリング方程式自体も微分方程式
Lo (x, ) Le (x, ) f r (x, , ) Li (x, )( n)d
d 2 o ( x )
Le ( x, ) f r ( x, , ) Li ( x, )( n)d
cos dAd
レンダリング
• 常に方程式を意識する
– レンダリング方程式を解いている
• いろいろな微分方程式を解いている
• 積分をしている
– 常に積分範囲を意識しなればいけない
現在の基本的なレンダリング
1
pixel ( x p )
2
La
pixel
dAp i (x )( n p E) dAa
4
Aa
定義を代入すると
dQ(x p )
dt
Q( x p )
1
La 2
1
La 2
pixel
frame pixel
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa
Aa
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
Aa
現在の基本的なレンダリング
基本的には1spp(shading per pixel)
FSAAすれば別
MSAAはシェーディングしているわけではない
Q( x p )
1
La 2
frame pixel
Pre-filterのIBL, textureや
punctual, analytical lightsが基本
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
Aa
時間方向の積分もポストプロセス
で疑似的に処理
絞りの大きさに起因する表現は
基本的にポストプロセス
つまりここも1spp
現在のレンダリングの問題点
• 4つの積分それぞれにおいて積分範囲が
正しく考慮されているか?
– Pixel, Time, Aperture, (Incident) Light
Pixelのサンプリング問題
• Pixel積分の精度が足りないと
– エイリアシング
• ジオメトリによるエイリアシング
• シェーディングによるエイリアシング
– テクスチャによるエイリアシング
– Analyticalなシェーダ計算によるエイリアシング
Pixelのundersampling
• 現在の主な解決方法
– MSAA / Post-process AA
• 主にジオメトリのみ
– FSAA
• 負荷が高い
– TAA
• チートがたくさん必要
• 基本的にはPost-process AA
時間のサンプリング問題
• 時間方向のサンプリングが少ないと
– 極端に短いシャッタースピードで撮影している
状態
• ただし明るさは確保できている
• いわゆるモーションブラーが発生しない
– 絵的には好ましいことも
• 微妙な速度で移動しているピクセルのフリッカー
– シェーディングに起因するエイリアシング
時間積分のundersampling
• モーションブラー再現
– ジオメトリベース
– ポストプロセスベース
Apertureのサンプリング問題
• Apertureのサンプリングが少ないと
– 実際にレンダリング時に考慮されることは
ほとんどない
– 絞りやカメラの機構によって発生する幾何光学
現象が再現されない
• De-focus blur (Bokeh)など
Aperture積分のundersampling
• 基本的にはポストプロセス
– De-focus Blurの再現
– 各種Vignettingの再現
Lightのサンプリング問題
• Lightのサンプリングが不十分だと
– 正しくないシェーディング
– 面積が正しく考慮されないライティング
– Smoothなマテリアルが表現できない
• サンプリング問題をフィルタリングでごまかすため
Lightのundersampling
• DeferredやTile-basedの技法による多ライト化
• Pre-filtered textureによるImage-based
Lighting
• Screen Space Lighting
• Analyticalに積分(近似)された面光源
積分問題
• そもそも積分をちゃんとしないと何が問題か?
– エイリアシングに起因する問題だけではない
• デルタ関数問題
• 極限問題
デルタ関数問題
• GGXの例
D( h)
s2
(1 (s 2 1) cos 2 h) 2
lim
s 0
D( h)
0
h
0
h 0
極限問題
• Height-Correlated Smith Masking and
Shadowing Functionの例
G( e , l )
2
1
1
1 s 2
1 1 s 2
1
2
2
cos e
cos l
V ( e , l )
V ( e , l )
G ( e , l )
cos e cos l
とおくと
2
1
1
2
2
cos e cos l 1 s
1 1 s
1
2
2
cos
cos
e
l
極限問題
V ( e , l )
2
1
1
2
cos e cos l 1 s 2
1
1
s
1
2
cos 2
cos
e
l
• 例えばcose=0となると、シェーダ内で極限問
題が発生する
– cose=0は物理的に不自然だが
– cose<eでも問題は起きる
• 正しい積分範囲は考慮されているか?
問題
• 根本的には積分を(モンテカルロ的に)離散
サンプリングしていることに起因する
– デルタ関数問題
• デルタ関数も適切に積分すれば1になる
• 離散的にサンプリングすれば∞か0
問題解決
• 数値計算的に発生する問題
– Ad-hocに解決していないか?
• 根本的(数学的)な原因は検討しない
• とりあえずmin, max, saturate
• 各種解決法に数学的, 物理的根拠はあるか?
数値積分の精度
• 数値積分の精度をあげたい
– いろいろなアプローチ
• 単にサンプリング数を増やす
– Ad-hoc的だが数値積分的に意味のある増やし方であれば
効果は確実
• 精度の高い(収束の速い)数値積分法
• 解析的な積分
積分の精度が上がると
• 映像はボケます
– というか1sppな状態は積分の精度が低すぎる
• 信号処理的には最もエイリアシングが起きやすい
サンプリング周波数
• その代わり一切のローパスフィルタがかかっていない
ので異常に高コントラスト
– 非現実的
– レンズの波動光学的解像度の低下(エアリーディスク等)を
考慮しなかったとしてもおかしい
例
• 簡単に数値積分の精度を上げるのには台形
積分(ニュートン・コーツの1次式)が使える
平均?
• 結局は単なる平均
– 例えばシンプソンの公式を使って高次にしたとし
ても結局は周囲のピクセルからの重み付け平均
数値積分精度
• それでも数値積分として考えると精度は飛躍
的に高まる
– つまり1sppの状態が数値積分的に異常だと認識する
• 従来は信号の振幅が低いので1sppでも今よりは許容できた
• しかし現在は信号の振幅が大きくなったので数値積分誤差が
大きすぎる
– 極端な言い方をすれば平均を取った(ボケた)状態が
(統計的に)精度の高いレンダリング(数値積分)になる
よりよい解決策
• 解析的に積分できれば問題解決できる
– 完全でなくてもより説得力がある
• 物理的or数学的根拠
– レンダリング方程式に解析解は存在しない
• 積分をサンプリング以外の方法で近似できないか?
なぜ?
• レンダリング方程式全体を解析的に積分する
のは複雑すぎて不可能
– 部分的に積分できないか
• Pre-filter的なアプローチが応用できる
• モデル化できるかもしれない
積分の分離
• レンダリング方程式に戻ってみる
Lo (x, ) Le (x, ) f r (x, , ) Li (x, )( n)d
Microfacet modelを代入してみると
D(x, ) F (x, , )G (x, , )
Li (x, )( n)d
4 cos cos
Lo (x, ) Le (x, )
積分の分離
いろいろなモデル(関数)の積を積分している
D(x, ) F (x, , )G (x, , )
Lo (x, ) Le (x, )
Li (x, )( n)d
4 cos cos
積分の分離
• 「積の積分」の「積分の積」に分離したい
– [CEDEC 2011]で触れた内容
復習[CEDEC 2011]
• 畳み込み定理を使う
– フーリエ変換が必要なので手軽ではない
•
f ( x)g (t x)e ix dx F ( )G ( )
• 基底変換を使う
– Spherical Harmonicsを利用したPRT等
復習[CEDEC 2011]
• 無理やり分離 f ( x)dx g ( x)dx f ( x)g ( x)dx
– 数学的には正しくない
• AmbientBRDF
• Pre-filtered Texture Lighting
– 誤差をどう許容するか
• 評価については[CEDEC 2011]で解説
他の手法
• ガウス関数(積分)を利用する
– LEAN, CLEAN, Toksvig等で応用されている
アイディア
f ( x) ae
( x b ) 2
2c
ガウス関数の性質
• ガウス(正規)分布
f gauss ( x, s , )
1
2
1
2s
2
e
2s
( x )2
2s 2
2
e
dx 1
( x )2
2s 2
ガウス分布の性質
• 以下のようなガウスの確率分布関数がある
ときs2が分散, が平均となる
f gauss ( x, s , )
2
1
2s
2
e
( x )2
2s 2
平均と分散の性質
• 数列{a,b,c,d}がある
– (a+b+c+d)/4が平均となる
– ( (a- )2+(b- )2+(c- )2+(d- )2)/4が分散s2となる
平均と分散の性質
• 数列{a,b,c,d}がある
– 平均, 分散には以下の式(1)が成り立つか?
0 1
ab
0
2
2
(a 0 ) 2 (b 0 ) 2
s
2
2
0
cd
1
2
(c 1 ) 2 (d 1 ) 2
s
2
2
1
0 2 1 2 s 02 s 12
s
2
2
2
式(1)
証明
分散の定義から
s2
( a ) 2 (b ) 2 ( c ) 2 ( d ) 2
4
(a
a2
abcd 2
abcd 2
abcd 2
abcd 2
) (b
) (c
) (d
)
4
4
4
4
4
a(a b c d ) (a b c d )2
b( a b c d ) ( a b c d ) 2
c( a b c d ) ( a b c d ) 2
d (a b c d ) (a b c d )2
b2
c2
d2
2
16
2
16
2
16
2
16
4
a 2 b2 c 2 d 2
( a b c d )( a b c d ) (a b c d ) 2
2
4
4
(a b c d )2
a b c d
4
4
2
2
2
2
式(2)
証明
0 2 1 2 s 02 s 12
s
2
2
2
ab abcd cd abcd
(a 0 )2 (b 0 )2 (c 1 )2 (d 1 )2
2
4
4
2
2
2
2
a
b
a
b 2
cd 2
cd 2
2
2
2
(a
) (b
) (c
) (d
)
ab abcd cd abcd
2
2
2
2
2
4
4
2
2
2
2
1
ab 2
ab 2
cd 2
cd 2
( a b) 2 ( c d ) 2 ( a b c d ) 2 ( a
) (b
) (c
) (d
)
2
2
2
2
2
4
2
2
2
2
1
( a b) ( c d ) 2
( a b) 2 ( c d ) 2 ( a b c d ) 2 a 2 b 2 c 2 d 2
2
2
4
2
2
2
2
2
(a b c d )2
a b c d
4
=式(2)なので式(1)は成り立つ
4
2
2
2
2
平均と分散の性質
• 数列{x1, x2,… xn}がある
– 平均, 分散には以下の計算が成り立つ
1 n
平均 xk
n k 1
n
1
分散 s 2 ( xk )2
n k 1
平均と分散の性質
• 数列{x1, x2,… xn}がある
– nが偶数の時
平均
0 1
2
n
2
n
2
2
0 xk
n k 1
2 n
1 xk
n k n 1
n
2
2
2
2
2
2
s
(
x
)
分散 s ( xk 0 )
1
k
1
n k n 1
n k 1
2
0
2
0 2 1 2 s 02 s 12
s
2
2
(証明は省略)
2
ガウス分布の再生性
• s0, s1 および0, 1がガウス分布の独立した
パラメータの時
f gauss ( x, s 0 s , 0 1 ) f gauss ( x t , s 0 , 0 ) f gauss (t , s 1 , 1 )dt
2
2
1
2
2
ガウス分布の再生性
f gauss ( x, s 0 s , 0 1 ) f gauss ( x t , s 0 , 0 ) f gauss (t , s 1 , 1 )dt
2
2
1
2
2
• つまり2関数が共にガウス分布関数の場合
– 平均と分散の和を取ってできた新しいガウス分布
関数が元の関数の畳み込みになる
• 単純な計算で元の関数の積の積分ができる!
– Pre-filter処理しているのと同じ
確率密度関数(PDF)の再生性
• ガウス分布関数はPDF
– 再生性のあるPDFはガウス分布関数だけでは
ない
•
•
•
•
二項分布
コーシー分布
ポアソン分布
ガンマ分布
– カイ2乗分布
再生性
• 再生性のあるPDFを利用すれば関数の積の
積分(畳み込み)を解析的に分離することが
可能
– ガウス分布関数はシェーダ的にも軽くて便利
– 対応する関数のフィッティング的に他のPDFの
ほうが精度が高くなるケースがある
2次元ガウス分布
1
2s xs y 1 s
2
xy
e
( x ) 2 ( y y ) 2 2s xy ( x x )( y y )
1
x
2
2
2
s
s
sy
2 (1s xy ) s x
x y
xとyの確率分布が独立((母)相関係数sxyが0)の場合
1
2s xs y
e
1 ( x ) 2 ( y y ) 2
x
2
2
2
s
s
x
y
2次元ガウス分布の性質
1
2s xs y
e
1 ( x ) 2 ( y y ) 2
x
2
2
2
s y
s x
2つの1次元ガウス分布に分離可能
1
2 s x
e
2
( xx )
2
2
s
x
1
2 s y
e
2
( y y )
2
2
s
y
2次元ガウス分布の性質
1
2s xs y
e
1 ( x ) 2 ( y y ) 2
x
2
2
2
s y
s x
sx=syのx=y=0の時 (等方)
1
2s
2
e
x2 y2
2s 2
ここまでのまとめ
• 積分を分離して単純化したい
– 単純な分離による近似や基底変換もあるけど
• いつも使えるわけではない
– 確率密度関数を近似関数として利用できないか?
• ガウス分布関数は様々な便利な特性がある
• ちなみにNDFであるD項も確率密度関数
GGXをフィッティング
• GGXをガウス分布関数として扱う
– ガウス分布関数のさまざまな性質を利用できる
– GGXをガウス分布関数で近似してみる
GGXフィッティング
1
s
2
2
2
e
2
tan
2
s
2
2
フィッティングした式
GGXフィッティング
roughness = 0.1
青 : GGX
赤 : フィッティングした式
GGXフィッティング
roughness = 0.2
青 : GGX
赤 : フィッティングした式
GGXフィッティング
roughness = 0.3
青 : GGX
赤 : フィッティングした式
GGXフィッティング
1
s
2
2
2
e
2
tan
2
2 s
2
フィッティングした式
1
2s
2
e
x2 y2
2s 2
2次元ガウス分布関数(等方)
応用例
• Roughnessを正しく計算してみたい
– 今更?
– 良い既存手法がたくさんがある?
既存手法では?
• Toksvig
– 古い(10年前)のでハード的な制約を受けている
– 当時の手法としては便利
• (本来は)追加のテクスチャマップもいらない
• シェーダだけで計算できる
既存手法では?
• LEAN, CLEAN, LEADR系
– 特定のモデルを前提としている
• いろいろなBRDFモデルに対応したいときに不便
– 追加のパラメータ(テクスチャ)が必要
• G-Buffer等もいじる?
– ただし解析的積分の手法(設計)としては正しい
アプローチ
Roughness計算の目的
• 実装済みのBRDFモデルやレンダリングパイプライン
をそのまま使いたい
– 独自に設計することにより他のBRDFモデルにも適用する
モデルを自分でデザインできる
• 簡単な計算で求めたい
– 非線形最小二乗法を利用するのは精度が高いが遅い
• 追加のメモリ(テクスチャ)を使いたくない
– 既存のG-bufferデザインをそのまま使える
Roughnessの計算
• D項 = Normal Distribution Function
– つまりD(x)に対してxの方向の法線の割合(確率)
を示している
• 実際の法線の分布がD(x)に従っていると仮定する
– 現実の分布をよく表している
– その分布に従わないマイクロファセットもたくさん存在する
» 人為的な傷など
Roughnessの計算
• 実際の法線の分布がD(x)に従っていると仮定
– 法線の分布がわかればD(x)のパラメータ(roughness)を決定できる
– ノーマルマップやハイトマップがあれば法線の分布もわかる
» スカルプトツールで超高解像度のノーマルやハイトを出力すれ
ばroughnessを自動計算できる?
– ガウス分布においてはroughness(s )の2乗(s2)は分散になる
» 法線の分散を求めることができればroughnessを計算できる
Roughnessの計算
1
s
2
2
2
e
2
tan
2
2 s
2
実際にはではなくtanで
分散を求める
求めた分散の平方根を 2 で
割った値
Roughnessミップマップ
• 以下の式が使える
平均
0 1
2
n
2
2 n
2
0 xk 1 xk
n k 1
n k n 1
2
分散
n
2
2
s ( xk 0 )2
n k 1
2
0
2 n
s ( xk 1 )2
n k n 1
2
1
2
0 2 1 2 s 02 s 12
s
2
2
2
Roughnessミップマップの作成手順
• 法線とroughness2の平均を取る
– 平均法線をノーマルマップへ
– 平均法線と法線との差(tan)から新しい分散を
計算する
– 新しい分散とroughness2の平均を足して
roughnessマップに格納
Roughnessのbilinear filtering
• Roughnessマップにはroughnessの2乗を入れ
ておくほうが良い
– Bilinear filteringにより法線が平均化されてかつ
roughnessの2乗も平均化されると定義通りの計
算がおこなわれる
2
2
2
2
s
s
1
1
s2 0
0
2
2
異方性GGXのroughness計算
• u,v方向それぞれroughnessを計算する
– 2つの1次元ガウス分布関数の積と考えると
• u方向とv方向に投影した法線でroughnessを計算
すればよい
• 正規化に注意
Roughness計算の結果
Roughness mipmap with normal
Regular roughness mipmap
Roughness計算の結果
Roughness mipmap with normal
Regular roughness mipmap
Box-kernelにフィッティングしてみる
• 誤差が大きいので誤差の評価でいろいろな
値の取り方がある
– 最小二乗法でフィッティング
– 全体のバランスでフィッティング
• 見た目で手動で調整
Box-kernelにフィッティングしてみる
1
e
2 (0.5 2s )
x2
2 0.5 2s
2
応用例(1) – aperture積分の考慮
• 絞りが変われば積分範囲が変わる
– 同じ露光(明るさ)でも見た目が変わるはず
– Glare(絞りによる回折現象)とは異なる
• ただし共にF値により変動するので分離するのは
難しい
– 鋭いスペキュラハイライトに差が出やすい
• ディフューズや鈍いスペキュラは絞りによる視線の
ズレでの変化が少ないため
aperture積分(実例)
F1.4
F4.0
aperture積分(実例)
F1.4
F4.0
Aperture積分
Q( x p )
1
La 2
frame pixel
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
Aa
• 絞りを考慮する
– レンズの効果は考えない
• 絞りの中は一定のサンプリング
– 今回の解法ではガウス分布にフィッティングするので一定で
はない
» STFレンズっぽくなる
Aperture積分
Q( x p )
1
La 2
frame pixel
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
Aa
絞りを開口部が1, 光が通らない部分を0とした
visibility関数V()で表現すると
Q( x p )
1
La 2
frame pixel
dAp Le (x, ) V ( ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
ここを分離できればよい
Aperture積分
V () f (x, , )L (x, )( n)d
r
i
BRDFをMicrofacetモデルに分解すると
D F G
V ( ) 4( n)( n) Li (x, )( n)d
整理する
1
V ( ) D F G Li (x, )d
4( n)
Aperture積分
1
V ( ) D F G Li (x, )d
4( n)
• D項をガウス分布で表現(近似)しているなら
– V()をガウス分布で近似できれば再生性を利用
できる
• Box-kernelのガウス近似
• あとは積分範囲を求める
Aperture積分の積分範囲
f
a
D
E
投影面(センサー)
絞り
D cos a
tan
f
E
D sin a
cos a
f
D 0.5
F
Aperture積分の積分範囲
2次元box-kernelフィッティング
1
e
2
2 (0.5 2s )
x2
2 0.5 2s
2
1
s
2
2
2
e
2
tan
2
2 s
2
D cos a
tan
f
E
D sin a
cos a
1
2
s 0.5 2
tan 0.5 tan 2
2
2
絞りを考慮した積分範囲(分散)
Aperture積分の適用
• 計算したs2をD項に適用すればよい
– Specular, diffuse両方に適用するかはモデル次第
– ガウス分布関数が積分を正規化してしまうので
明るさは変わらない
• 露光量をコントロールするには別途手法が必要
– 絞り(露光量)に応じたスケールファクタ
– ポストプロセス
Aperture積分の結果
F1.4
Aperture積分の結果
F2.8
応用例(2) – pixel積分の考慮
• 本来はpixelのサイズの範囲で積分している
– デルタ関数も積分範囲があれば大きさは1以下
(無限大ではない)
• GGXがroughness=0の時でも無限大にならないはず
応用例(2) – pixel積分の考慮
Q( x p )
1
La 2
frame pixel
dAp Le (x, ) f r (x, , ) Li (x, )( n)d (n p E) 4 dAa dt
Aa
• ピクセルサイズを考慮する
– レンズの効果は考えない
• ピクセルの中は一定のサンプリング
• Aperture積分と同じ手法を用いる
– 今回はaperture積分と同じくガウス分布になる
pixel積分の積分範囲
f
p
投影面(センサー)
tan
p cos a
f
p sin a
cos a
a
E
絞り(pin-holeとみなす,
絞りの大きさ自体はaperture積分)
2
sensor _ width sensor _ height
p 0.5c
resolution
_
width
resolution
_
height
cは調整ファクター
ピクセルは四角なので円形に対する調整項目
2
pixel積分の積分範囲(同じ)
2次元box-kernelフィッティング
1
e
2
2 (0.5 2s )
x2
2 0.5 2s
2
1
s
2
2
2
e
2
tan
2
2 s
2
tan
p cos a
f
p sin a
cos a
1
2
s 0.5 2
tan 0.5 tan 2
2
2
ピクセルサイズを考慮した積分範囲(分散)
Pixel積分の適用
• それほど大きい値ではない
– 本来はpixel位置で異なるがCPUでどこかの1pixel
を計算してシェーダでは固定値にしてもよい
• 1920x1080, 28mmレンズ, 35mmフィルム
• s=0.001程度
– Full HDでは誤差レベル
– ただroughnessは常に0にはならない
Grazing angleの極限問題
• 主にcose<eで起こる問題
– そもそもどういう状態か?
投影された面積
法線
e
pixel
シェーディング面
• coseが小さくなると投影されるシェーディング
面の面積は大きくなっていく
– cose =0になると無限大になる
無限大?
• 現実に無限大の面積を見るはずがない
– そもそもシェーディング面の面積が無制限に
大きくなるのがおかしい
シェーディング面積
• ポリゴン単位でシェーディングしていることを
考えれば
– 1シェーディングでポリゴンの面積を超えるのは
おかしい
• 本来は1pixel内に複数ポリゴンあるときはそれぞれ
シェーディングして加算する必要がある
– FSAA?
現実的な対処
• coseをクランプする
– どのくらいでクランプすればいい?
– ad-hoc的に決めていないか?
クランプ値の決定法(1)
• ポリゴンの面積で決める
– ただし1pixel内に複数ポリゴンある場合は
ピクセルが暗くなってしまう
– 比較的コンサバティブな手法
クランプ値の決定法(1)
• ポリゴンの面積を求める
– ジオメトリシェーダで計算する
– Vertexに事前に計算して埋め込んでおく
• ポリゴンの面積を1ピクセルをシェーディング
位置に投影したサイズで割る
– その値の逆数が最小クランプ値となる
– 本来はポリゴンの向きによって異なる
クランプ値の決定法(2)
• オブジェクトの投影面積で決める
– 本当にgrazing angleに近い時は複数ポリゴンを
見ているはず
• 一番広いケースではオブジェクト全体
– ポリゴン単位より暗くなりづらい
• ポリゴン単位で処理するとき正しくブレンドしないなら
– こちらのほうがより物理的には正しい見た目になる
クランプ値の決定法(2)
• オブジェクトの投影サイズを求める
– リアルタイムに求めるのは出来ないことはないが
コストに見合わない
• 事前計算しておく
– 投影サイズの最大値, 最小値, 平均値など
– テンソル化しておいてランタイムで視線ベクトルから決定
クランプ値の決定法(2)
• あとはポリゴンの時と同じ
– ポリゴンの面積を1ピクセルをシェーディング位置
に投影したサイズで割る
• その値の逆数が最小クランプ値となる
クランプ値の例(1)
• 例えば
– 1920x1080, 28mmレンズ(35mmフォーマット換算)
– 10mのところにある大きさ10x10cmのポリゴンを
見ているとすると
• coseのクランプ値は0.066943
クランプ値の例(2)
• 例えば
– 1920x1080, 28mmレンズ(35mmフォーマット換算)
– 5mのところにある大きさ1x1mのオブジェクトを
見ているとすると
• coseのクランプ値は0.00334821
実装
• 実際にはオブジェクトごとにオフラインで事前
計算してもよい
–
–
–
–
アニメーションでそれほど変動しないなら
シェーダ内では固定値
またはシーン全体で固定値
あまりコンサバな値にするとG項の効果が怪しくなる
• リアリティにかける
• エイリアシングやエッジにおけるfirefly artifactとの兼ね合い
まとめ
• 物理ベースレンダリングを実装するのであればいか
なる時もレンダリング方程式を意識する
– レンダリングに問題があった時はいきなりad-hoc
に対処するべきでない
• その原因を追及して正しい対処法を検討する
– 結果数値積分の限界やパフォーマンス的な理由
でad-hoc的に対処することになったとしても
• 物理的, 数学的な意味を可能な限り検討する
謝辞
ご質問は?
• スライドは以下のページでダウンロード可能
です
– http://research.tri-ace.com/