cosq e - Tri Ace research

Report
物理ベースレンダリングを実装するときに役に立つこと
五反田義治
(株) トライエース 研究開発部
物理ベースレンダリングとは?
• 物理ベースレンダリング(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) cos2 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
2



 cos  e 
 cos  l
 

• 例えばcose=0となると、シェーダ内で極限問
題が発生する
– cose=0は物理的に不自然だが
– cose<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  ix 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等で応用されている
アイディア
( x b ) 2

2c
f ( x)  ae
ガウス関数の性質
• ガウス(正規)分布
f gauss ( x, s ,  ) 
1
2



1
2s 2
e
2s
( x )2

2s 2
2
e
dx  1
( x )2

2s 2
ガウス分布の性質
• 以下のようなガウスの確率分布関数がある
ときs2が分散, が平均となる
f gauss ( x, s ,  ) 
2
1
2s
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
ab
0 
2
2
(a  0 ) 2  (b  0 ) 2
s 
2
2
0
cd
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 
abcd 2
abcd 2
abcd 2
abcd 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
ab abcd  cd abcd 
(a  0 )2  (b  0 )2  (c  1 )2  (d  1 )2



 

2
4
4
  2
 
2

2
2
a

b
a
b 2
cd 2
cd 2
2
2
2
(a 
)  (b 
)  (c 
)  (d 
)
ab abcd  cd abcd 
2
2
2
2



 

2
4
4
  2
 
2

2
2
1
ab 2
ab 2
cd 2
cd 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が偶数の時
平均  
n
2
0  1
2 n
1   xk
n k  n 1
2
0   xk
n k 1
2
n
2
n
2
2
2
2
2
2
s

(
x


)
分散 s   ( xk  0 )
 k 1
1
n k  n 1
n k 1
2
0

0     1   
s 
2
2
2
2
2
(証明は省略)

s s
2
0
2
2
1
ガウス分布の再生性
• 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
2s xs y 1  s
2
xy
e
2


1
 ( x   x ) 2 ( y   y ) 2s xy ( x   x )( y   y ) 





2 
2
2
s
s
sy
 2 (1s xy ) 

x y
 sx
 
xとyの確率分布が独立((母)相関係数sxyが0)の場合
1
2s xs y
e
2 
 1
 ( x   x )2 ( y   y ) 

 


2
2
2
s y  
 
 sx
2次元ガウス分布の性質
1
2s xs y
e
2 
 1
 ( x   x )2 ( y   y ) 

 


2
2
s y  
 2 
 sx
2つの1次元ガウス分布に分離可能
1
e
2 s x
2

 ( x x ) 



2


2
s
x


1
2 s y
e
2

 ( y y ) 




2
2
s


y


2次元ガウス分布の性質
1
2s xs y
e
2 
 1
 ( x   x )2 ( y   y ) 

 


2
2
s y  
 2 
 sx
sx=syのx=y=0の時 (等方)
1
2s
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
2s
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
2
0   xk 1 
n k 1
n
n
2
2
s   ( xk  0 )2
n k 1
2
0
x
k
n
k  1
2
2 n
s   ( xk  1 )2
n k  n 1
2
1
2

0   2  1   2 s 02  s12
s 

2
2
n
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
投影面(センサー)
絞り
tan 
D cosa
f
E
 D sin a
cosa
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
e




2
  tan  
2

 2  s  
  2  
D cosa
tan 
f
E
 D sin a
cosa
2 

2



 1 
2
s  0.5 2 
tan   0.5 tan2 
 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  cosa
f
 p  sin a
cosa
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
e




2
  tan  
2

 2  s  
  2  
tan 
p  cosa
f
 p  sin a
cosa
2 

2



 1 
2
s  0.5 2 
tan   0.5 tan2 
 2
2
ピクセルサイズを考慮した積分範囲(分散)
Pixel積分の適用
• それほど大きい値ではない
– 本来はpixel位置で異なるがCPUでどこかの1pixel
を計算してシェーダでは固定値にしてもよい
• 1920x1080, 28mmレンズ, 35mmフィルム
• s=0.001程度
– Full HDでは誤差レベル
– ただroughnessは常に0にはならない
Grazing angleの極限問題
• 主にcose<eで起こる問題
– そもそもどういう状態か?
投影された面積
法線
e
pixel
シェーディング面
• coseが小さくなると投影されるシェーディング
面の面積は大きくなっていく
– cose =0になると無限大になる
無限大?
• 現実に無限大の面積を見るはずがない
– そもそもシェーディング面の面積が無制限に
大きくなるのがおかしい
シェーディング面積
• ポリゴン単位でシェーディングしていることを
考えれば
– 1シェーディングでポリゴンの面積を超えるのは
おかしい
• 本来は1pixel内に複数ポリゴンあるときはそれぞれ
シェーディングして加算する必要がある
– FSAA?
現実的な対処
• coseをクランプする
– どのくらいでクランプすればいい?
– ad-hoc的に決めていないか?
クランプ値の決定法(1)
• ポリゴンの面積で決める
– ただし1pixel内に複数ポリゴンある場合は
ピクセルが暗くなってしまう
– 比較的コンサバティブな手法
クランプ値の決定法(1)
• ポリゴンの面積を求める
– ジオメトリシェーダで計算する
– Vertexに事前に計算して埋め込んでおく
• ポリゴンの面積を1ピクセルをシェーディング
位置に投影したサイズで割る
– その値の逆数が最小クランプ値となる
– 本来はポリゴンの向きによって異なる
クランプ値の決定法(2)
• オブジェクトの投影面積で決める
– 本当にgrazing angleに近い時は複数ポリゴンを
見ているはず
• 一番広いケースではオブジェクト全体
– ポリゴン単位より暗くなりづらい
• ポリゴン単位で処理するとき正しくブレンドしないなら
– こちらのほうがより物理的には正しい見た目になる
クランプ値の決定法(2)
• オブジェクトの投影サイズを求める
– リアルタイムに求めるのは出来ないことはないが
コストに見合わない
• 事前計算しておく
– 投影サイズの最大値, 最小値, 平均値など
– テンソル化しておいてランタイムで視線ベクトルから決定
クランプ値の決定法(2)
• あとはポリゴンの時と同じ
– ポリゴンの面積を1ピクセルをシェーディング位置
に投影したサイズで割る
• その値の逆数が最小クランプ値となる
クランプ値の例(1)
• 例えば
– 1920x1080, 28mmレンズ(35mmフォーマット換算)
– 10mのところにある大きさ10x10cmのポリゴンを
見ているとすると
• coseのクランプ値は0.066943
クランプ値の例(2)
• 例えば
– 1920x1080, 28mmレンズ(35mmフォーマット換算)
– 5mのところにある大きさ1x1mのオブジェクトを
見ているとすると
• coseのクランプ値は0.00334821
実装
• 実際にはオブジェクトごとにオフラインで事前
計算してもよい
–
–
–
–
アニメーションでそれほど変動しないなら
シェーダ内では固定値
またはシーン全体で固定値
あまりコンサバな値にするとG項の効果が怪しくなる
• リアリティにかける
• エイリアシングやエッジにおけるfirefly artifactとの兼ね合い
まとめ
• 物理ベースレンダリングを実装するのであればいか
なる時もレンダリング方程式を意識する
– レンダリングに問題があった時はいきなりad-hoc
に対処するべきでない
• その原因を追及して正しい対処法を検討する
– 結果数値積分の限界やパフォーマンス的な理由
でad-hoc的に対処することになったとしても
• 物理的, 数学的な意味を可能な限り検討する
謝辞
ご質問は?
• スライドは以下のページでダウンロード可能
です
– http://research.tri-ace.com/

similar documents