SlideShare a Scribd company logo
1 of 126
Download to read offline
中級グラフィックス入門
~シャドウマッピング総まとめ~
はじめに…
• CEDEC 2015公募の落選したものを
改変したものです。
内容については落ちたものなのでお察しください。
• Web公開にあたりスライド内容を
一部変更しています。
• 間違いがあるかもしれないので,
指摘していただけると助かります。
Motivation
• デモプログラム作成で,シャドウマップを任される。
ちょっと残念な結果になってしまった… orz
他社や,最新論文等はどんな技術をつかっているんだろう???
シャドウマッピング法についてまとめてみよう!
最近の主流
Z-Partitioning
Filtering
ひと昔前に流行った
Projective Warping Algorithm(PSM, LiSPSMなど)は,
扱いずらいせいか最近はあまり使われていない印象。
シャドウマッピング法の基本
• ライトへの距離 を 測って 遮蔽を判定する
シャドウマップ 深度値を求める 深度値を比較
透視投影変換後のXYZ座標をW値で割ることで
射影テクスチャの座標が求まる。
これをSampleCompLevelZero()などを使って,
シャドウマップに格納された深度値と比較する
シャドウマップの問題点
ジャギる
バイアス
シャドウアクネ
ピーターパン問題
シャドウアクネ
画面上に斑点上の模様が現れる。
この斑点(ぶつぶつ)を”にきび”に例えて,シャドウアクネ(Shadow acne)と呼ぶ。
なぜ発生するの?
• シャドウマップによって深度が量子化されることが原因
なぜ発生するの?
• シャドウマップによって深度が量子化されることが原因
解決方法は?
• 下駄をはかせる。
深度値にバイアスをかけることで,シャドウアクネを低減する。
バイアスの他に,サーフェイスを背面描画してシャドウマップを作成するのが普通。
実は簡単な問題ではない
• 深度バイアスをかけすぎると…
ピーターパン問題が発生する
※図はMicrosoft, “シャドウ深度マップの品質向上のための一般的な技法” https://msdn.microsoft.com/ja-jp/library/ee416324(v=vs.85).aspx より引用
ピーターパン問題
• 特にピーターパン問題が発生しやすいのは,
深度勾配が大きいもの
定数バイアスをかける
勾配がきつい所は
あんまりオフセットされない
このような場合は深度傾斜バイアスを使って対処する。
深度傾斜バイアスって?
typedef struct D3D11_RASTERIZER_DESC
{
D3D11_FILL_MODE FillMode;
D3D11_CULL_MODE CullMode;
BOOL FrontCounterClockwise;
INT DepthBias;
FLOAT DepthBiasClamp;
FLOAT SlopeScaledDepthBias;
BOOL DepthClipEnable;
BOOL ScissorEnable;
BOOL MultisampleEnable;
BOOL AntialiasedLineEnable;
} D3D11_RASTERIZER_DESC;
• 深度の傾斜に応じてバイアスを設定する方法。
• 大抵のAPIでサポートされている。
使いたい場合は数値を設定するだけ
APIでサポートされていない場合
の計算例は次の通り
Bias = (float)DepthBias + SlopeScaledDepthBias * MaxDepthSlope;
float MaxDepthSlope = max( abs( ddx( Depth ) ), abs( ddy( Depth ) ) );
ジャギる
なぜ,ジャギるのか?
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
エイリアシング誤差
• 2次元での話
ライト
シャドウ平面
視錘台
視点
※3次元の視錘台の側面から見ていると想定
𝑚 =
𝑟𝑗
𝑟𝑡
d𝑗
d𝑡
𝑗 ∈ 0,1
𝑡 ∈ [0,1]
シャドウマップの
テクスチャ座標
𝑟𝑗, 𝑟𝑡 テクスチャの解像度
𝑚 > 1
エイリアシング発生
エイリアシング誤差
• 話を3次元に拡張
𝐹 : シャドウマップパラメタライゼーション
𝐺:逆シャドウマップパラメタライゼーション
下付きの 𝑒 は視空間,𝑙 はライト空間を示す。
𝐬
𝐬
𝐬
ベクトルは列ベクトル表記とする。
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
エイリアシング誤差
• 各平面上の点を求める
𝐬𝒍
𝐬
𝐩𝑙 = 𝐩𝑙0 + 𝑣𝑊𝑙 𝐲𝑙
𝐩 = 𝐩𝑙 −
𝐬𝐩𝑙
𝐬 𝐩𝑙 − 𝐥
𝐩𝑙 − 𝐥
𝐩 𝒆 = 𝐩 −
𝐬 𝑒 𝐩
𝐬 𝑒 𝐞 − 𝐥
𝐞 − 𝐥
𝑗 =
𝐲 𝑒 ∙ 𝐩 𝑒 − 𝐩 𝑒0
𝑊𝑒
=
𝐲 𝑒
⊺
𝐩 𝑒 − 𝐩 𝑒0
𝑊𝑒
𝑊𝑙はシャドウマップによって覆われる𝐬𝑙の幅の一部
ハット付きは正規化済みベクトル
𝑊𝑒はイメージ画像によって覆われる𝐬 𝑒の幅の一部
𝐬 𝒆
𝐷
𝐬を法線ベクトル𝐧と原点から距離𝐷を使って
平面の方程式を用いて行ベクトルで表現すると
𝐬 = 𝐧⊺
, −𝐷
シャドウマップ上の𝑡に対応する
正規化したライト画像平面座標は𝑣 ∈ 0,1 で,
これを用いてライト画像平面上の点𝐩𝑙を表すと
𝑊𝑙
𝑊𝑒
ライト位置𝐥を通過して線分Lに沿って
平面𝐬上へと射影することで次を得る
視点𝐞を通過して線分Eに沿って
平面𝐬 𝒆上へと射影することで次を得る
𝑣と同様に視画像平面は𝑗によってパラメータ化され
𝐩 𝑒から次のように計算できる
エイリアシング誤差
d𝑗
d𝑡
=
𝜕𝑗
𝜕𝐩 𝑒
𝜕𝐩 𝑒
𝜕𝐩
𝜕𝐩
𝜕𝐩𝑙
𝜕𝐩𝑙
𝜕𝑣
d𝑣
d𝑡
𝜕𝑗
𝜕𝐩 𝑒
=
𝐲 𝑒
⊺
𝑊𝑒
𝜕𝐩 𝑒
𝜕𝐩
= 𝐈 +
𝐬 𝑒 𝐩
𝐬 𝑒 𝐞 − 𝐩
𝐈 −
𝐬 𝑒 𝐞
𝐬 𝑒 𝐜 𝑒 − 𝐩 2
𝐞 − 𝐩 𝐬 𝑒
𝜕𝐩
𝜕𝐩𝑙
= 𝐈 −
𝐬𝐩𝑙
𝐬 𝐩𝑙 − 𝐥
𝐈 +
𝐬𝐥
𝐬 𝐩𝑙 − 𝐥 2 𝐩𝑙 − 𝐥 𝐬
𝜕𝐩𝑙
𝜕𝑣
= 𝑊𝑙 𝐲𝑙
d𝑣
d𝑡
=
d𝐺
d𝑡
𝑗 =
𝐲 𝑒
⊺
𝐩 𝑒 − 𝐩 𝑒0
𝑊𝑒
𝐈 は単位行列
𝐩 𝒆 = 𝐩 −
𝐬 𝑒 𝐩
𝐬 𝑒 𝐞 − 𝐩
𝐞 − 𝐩
𝐩 = 𝐩𝑙 −
𝐬𝐩𝑙
𝐬 𝐩𝑙 − 𝐥
𝐩𝑙 − 𝐥
𝐩𝑙 = 𝐩𝑙0 + 𝑣𝑊𝑙 𝐲𝑙
商の導関数を利用
d𝑗
d𝑡
を求めたいが,直接解くことができないので,連鎖律(Chain Rule)を適用する
微分法において連鎖律とは、複数の関数が合成された合成関数を微分するとき,
その導関数がそれぞれの導関数の積で与えられるという関係式のこと。
エイリアシング誤差
𝜕𝐩
𝜕𝑡
=
𝜕𝐩
𝜕𝐩𝑙
𝜕𝐩𝑙
𝜕𝑣
𝜕𝑣
𝜕𝑡
= 𝑊𝑙
d𝐺
d𝑡
𝐬𝐥
𝐬 𝐩𝑙 − 𝐥
𝐲𝑙 −
𝐬𝐲𝒍
𝐬 𝐩𝑙 − 𝐥
𝐩𝑙 − 𝐥
長さの比率と考えると
𝑑𝑙
𝑛𝑙
𝐬
𝐬
𝐬
𝐳𝑙 𝐧と のなす角を 𝛽𝑙 とすると
𝐬𝐲𝒍 = − sin 𝛽𝑙𝐩𝑙 − 𝐥 = 𝐩𝑙 − 𝐥 𝐯𝑙
と書ける
= 𝑊𝑙
d𝐺
d𝑡
𝑑𝑙
𝑛𝑙
𝐲𝑙 −
− sin 𝛽𝑙
𝐬 𝐩𝑙 − 𝐥 𝐯𝑙
𝐩𝑙 − 𝐥 𝐯𝑙
−𝐯 とする
−𝐬𝐯 = −cos 𝜓𝑙
= 𝑊𝑙
d𝐺
d𝑡
𝑑𝑙
𝑛𝑙
𝐲𝑙 −
sin 𝛽𝑙
cos 𝜓𝑙
𝐯𝑙
𝛽𝑙
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
エイリアシング誤差
𝐧, 𝐛𝐲𝑙, 𝐯𝑙 を で展開する
𝐲𝑙 = cos 𝛽𝑙 𝐛 − sin 𝛽𝑙 𝐧
𝐯𝑙 = −sin 𝜓𝑙 𝐛 − cos 𝜓𝑙 𝐧
d𝐩
d𝑡
= 𝑊𝑙
d𝐺
d𝑡
𝑑𝑙
𝑛𝑙
cos 𝜓𝑙 cos 𝛽𝑙 + sin 𝜓𝑙 sin 𝛽𝑙
cos 𝜓𝑙
𝐛
𝑊𝑙
d𝐺
d𝑡
𝑑𝑙
𝑛𝑙
𝐲𝑙 −
sin 𝛽𝑙
cos 𝜓𝑙
𝐯𝑙
代入
= 𝑊𝑙
d𝐺
d𝑡
𝑑𝑙
𝑛𝑙
cos 𝜓𝑙 − 𝛽𝑙
cos 𝜓𝑙
𝐛
𝜓𝑙 − 𝛽𝑙 = 𝜙𝑙
d𝑗
d𝑡
=
𝜕𝑗
𝜕𝐩 𝑒
𝜕𝐩 𝑒
𝜕𝐩
d𝐩
d𝑡
𝐬 𝑒 𝐞 = 𝑛 𝑒
𝐬 𝑒 𝐞 − 𝐩 = 𝑑 𝑒
𝐞 − 𝐩 = 𝐞 − 𝐩 𝐯 𝑒
=
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
𝐲 𝑒
⊺
𝐛 −
𝐲 𝑒
⊺
𝐯 𝑒 𝐬 𝑒 𝐛
𝐬 𝑒 𝐯 𝑒
d𝐺
d𝑡
cos 𝜙𝑙
cos 𝜓𝑙
𝛽𝑙
𝐬𝒍
𝐬
𝐬 𝒆
エイリアシング誤差
d𝑗
d𝑡
=
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
𝐲 𝑒
⊺
𝐛 −
𝐲 𝑒
⊺
𝐯 𝑒 𝐬 𝑒 𝐛
𝐬 𝑒 𝐯 𝑒
d𝐺
d𝑡
cos 𝜙𝑙
cos 𝜓𝑙
𝐲 𝑒
⊺
𝐛 = cos 𝛽𝑒
𝐲 𝑒
⊺
𝐯 𝑒 = sin 𝜙 𝑒
𝐬 𝑒 𝐛 = − sin 𝛽𝑒
𝐬 𝑒 𝐯 𝑒 = cos 𝜙 𝑒
=
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
cos 𝜙 𝑒 cos 𝛽𝑒 + sin 𝜙 𝑒 sin 𝛽𝑒
cos 𝜙 𝑒
d𝐺
d𝑡
cos 𝜙𝑙
cos 𝜓𝑙
=
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
cos 𝛽𝑒 − 𝜙 𝑒
cos 𝜙 𝑒
𝑑𝐺
𝑑𝑡
cos 𝜙𝑙
cos 𝜓𝑙
𝛽𝑒 − 𝜙 𝑒 = 𝜓 𝑒
𝑚 =
𝑟𝑗
𝑟𝑡
d𝐺
d𝑡
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
cos 𝜙𝑙
cos 𝜙 𝑒
cos 𝜓 𝑒
cos 𝜓𝑙
𝑚 =
𝑟𝑗
𝑟𝑡
𝑑𝑗
𝑑𝑡
に求まった式を代入すると,
エイリアシング誤差
𝑚 =
𝑟𝑗
𝑟𝑡
d𝐺
d𝑡
𝑊𝑙
𝑊𝑒
𝑛 𝑒
𝑛𝑙
𝑑𝑙
𝑑 𝑒
cos 𝜙𝑙
cos 𝜙 𝑒
cos 𝜓 𝑒
cos 𝜓𝑙
透視要素 射影要素
見なかったことにして
スルーすることが多い
頑張ってみる
カメラとライトのみで決定される
=有界値となる
シーンに依存する
=有界値とならない
Perspective Shadow Map
などが代表例
Adaptive Shadow Map
などが代表例
シャドウマップを良くする
𝑚 =
𝑟𝑗
𝑟𝑡
d𝑗
d𝑡
𝑚 > 1 エイリアシング発生
[解決策]
・シャドウマップのサイズを大きくする
・シャドウマップの1テクセルあたりの品質を上げる
・適当にごまかす
・シャドウマップを諦める
要は…
シャドウマップの
テクセルの割合が,
カメラ視点での
テクセルの割合
より大きければよい
Projective Warping Algorithm
代表例:
• Perspective Shadow Maps(PSM)
• Light-Space Perspective Shadow Maps(LiSPSM)
• Trapezoidal Shadow Maps(TSM)
• Logarithmic Perspective Shadow Maps(LogPSM)
画面に近い所だけ品質あげればよくね?
…というアイデア
※動画は,Lloydが当時プレゼンテーションで使用していたものを引用。URLが現在不明です。
Perspective Shadow Map
シャドウマップに使う行列を変えてみればいいんじゃね?
…というアイデア。
※図はMarc Stamminger and George Drettakis, “Perspective Shadow Maps”, http://igm.univ-mlv.fr/~biri/Enseignement/IMAC3/Donnees/PSM.pdfより引用
注意点
透視変換を使用するため,
ライトの当たる順番が
変わることがある。
注意点
透視変換を使っているため,ライトが変わることがある。
注意点
透視変換を使っているため,ライトが変わることがある。
注意点
透視変換を使っているため,ライトが変わることがある。
対処方法
• ライトが後ろにある場合は,
順番が正しくなるようにカメラを後ろに下げてしまう
カメラを後退するということは
無駄な領域が増えるということ。
シャドウマップの品質が落ちる
※図は,Simon Kozlov, “Perspective Shadow Maps: Care and Feeding”, GPU Gems,
https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch14.html より引用
Practical Perspective Shadow Maps
• 特殊な透視変換行列を使用する
nearClip = a, farClip = -aを設定した透視変換行列を作成
この特殊な透視変換行列を使用することで,
仮想カメラ無しで順番が保たれるようになる。
※図は,Simon Kozlov, “Perspective Shadow Maps: Care and Feeding”, GPU Gems,
https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch14.html より引用
単位キューブクリッピング
シャドウマップに描画されない無駄な領域を無くせば,
シャドウマップのテクセルが多く割り当てることが出来るので品質が向上する
視錘台にあるシャドウを落とすオブジェクトのAABBを求めて
描画範囲を最適化する。
※図は,Simon Kozlov, “Perspective Shadow Maps: Care and Feeding”, GPU Gems, https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch14.html より引用
疑似コード
float4x4 ComputeUnitCubeClipMatrix(float3 mini, float3 maxi)
{
// 単位キューブクリップ行列を求める.
float4x4 clip;
clip.11 = 2.0f / ( maxi.x - mini.x );
clip.12 = 0.0f;
clip.13 = 0.0f;
clip.14 = 0.0f;
clip.21 = 0.0f;
clip.22 = 2.0f / ( maxi.y - mini.y );
clip.23 = 0.0f;
clip.24 = 0.0f;
clip.31 = 0.0f;
clip.32 = 0.0f;
clip.33 = 1.0f / ( maxi.z - mini.z );
clip.34 = 0.0f;
clip.41 = -( maxi.x + mini.x ) / ( maxi.x - mini.x );
clip.42 = -( maxi.y + mini.y ) / ( maxi.y - mini.y );
clip.43 = - mini.z / ( maxi.z - mini.z );
clip.44 = 1.0f;
return clip;
}
Light Space Perspective Shadow Map
PSMの欠点がなくなるように,ライトが垂直になるようにすりゃいんじゃね?
…というのがアイデア。
元々の論文通りのPSMは色々な問題を抱えていた
• 透視変換のため,ライトが変化する
• 変化しないようにカメラを後ろに下げると品質落ちる
• 遠い所がいい加減すぎる
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
Light Space Perspective Shadow Maps
• 論文中での透視エイリアシングの定義
𝑑𝑝
𝑑𝑠
=
1
𝑧
𝑑𝑧
𝑑𝑠
cos 𝛼
cos 𝛽
最適解は
𝑑𝑝
𝑑𝑠
= 1 になること
𝑑𝑝
𝑑𝑠
=
1
𝑧
𝑑𝑧
𝑑𝑠
cos 𝛼
cos 𝛽
定数扱い
𝑠 = 𝑑𝑠=
𝑑𝑧
𝑧
= log
𝑧
𝑧 𝑛
𝑧
𝑧 𝑛
𝑠
0
1 =
𝑑𝑧
𝑧𝑑𝑠
つまり,𝑑𝑠 =
𝑑𝑧
𝑧
となればよいので
対数
※図は,Michal Wimmer, Daniel Schezer, Werner Purgathofer,
“Light Space Perspective Shadow Maps”,
Eurographics Symposium on Rendering 2004 より引用
最適解
• シャドウマッピングに対する
最適なパラメータライゼーションは対数
qさんのBlog
「深度バッファのレンジと精度を最大化する」
を参照されたし!
http://qpp.bitbucket.org/translation/maximizing_depth_buffer_range_and/
Logarithmic Perspective Shadow Map
対数使ってみよう! ⇒ PSM系でずば抜けた綺麗さ!
非線形ラスタライズを採用しているため,
ゲロ重い…
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
エリアシング誤差
>107.753.251111
3.257.7510
<
>107.753.251111
3.257.7510
<
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
対数ラスタライザ
カーブしていたものは直線になり,
直線だったものはカーブする
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
対数ラスタライザ
ぐにゃっと曲がる。
※図は,D.Bradon Lloyd, “Logarithmic Perspective Shadow Maps”より引用
実装してみた。
• コンピュートシェーダで実装。
Githubでソースコード公開中。
https://github.com/ProjectAsura/LinearRasterizer
https://github.com/ProjectAsura/LogarithmicRasterizer
線形ラスタライザ 対数ラスタライザ
実装が良くなかったので,やっぱり画面を占めるピクセルの割合が多くなると,
コンピュートシェーダでもゲロ重。
論文に記載されているストリーム出力を使う方法は
まだ試していないので,後で試してみる。
とりあえず分かったこと。
(1)シャドウマップのテクセルを
いっぱいに使えれば良さげに見える
(2)最適解は何か対数らしいよ。
どのぐらい使っているか分かれば,何か役立つかも…
シャドウマップテクセル
• 2次元での話
ライト
シャドウ平面
視錘台
視点
※3次元の視錘台の側面から見ていると想定
実際の大きさが
シーン上で見えると
調整しやすい
グリッドシェーダ
による描画
グリッドシェーダ
シャドウマップテクセルの可視化
エイリアシング誤差
• テクスチャ座標の2方向について考慮すると
ピクセルシェーダで可視化
赤:ジャギーが目立つ
青:ジャギーが目立たない
エイリアシング誤差の可視化
• 実装例
float3 VisualizeError( float2 shadowCoord, float2 shadowMapSize )
{
const float3 values[] = {
float3( 0.0f, 1.0/7.75, 1.0f/7.75f ),
float3( 1.0f/7.75f, 1.0f/3.25f, 1.0f/3.25f - 1.0f/7.75f ),
float3( 1.0f/3.25f, 1.0f, 1.0f - 1.0f/3.25f ),
float3( 1.0f, 3.25f, 2.25f ),
float3( 3.25f, 7.75f, 4.5f ),
float3( 7.75f, 10.0f, 7.75f ),
};
const float3 colors[] = {
float3( 0.2f, 0.0f, 0.0f ),
float3( 1.0f, 0.2f, 0.0f ),
float3( 1.0f, 1.0f, 0.0f ),
float3( 0.0f, 1.0f, 0.0f ),
float3( 0.3f, 0.8f, 1.0f ),
float3( 0.0f, 0.0f, 1.0f ),
float3( 0.0f, 0.0f, 0.2f )
};
float2 ds = shadowMapSize.x * ddx( shadowCoord );
float2 dt = shadowMapSize.y * ddy( shadowCoord );
float error = max( length( ds + dt ), length( ds - dt ) );
float3 result = (float3)1.0f;
[unroll] for( int i=0; i<6; ++i )
{
if ( error >= values[i].x && error < values[i].y )
{
result = lerp( colors[i], colors[i+1], (error - values[i].x) / values[i].z );
break;
}
else
{ result = colors[6]; }
}
return result;
}
1次元テクスチャ化可能
1回のテクスチャフェッチに変更可能
誤差を求める計算
エイリアシング誤差の可視化
• 簡略化版の実装例
Texture1D ErrorTexture : register( t0 );
SamplerState ErrorSampler : register( s0 );
float3 VisualizeError( float2 shadowCoord, float2 shadowMapSize )
{
float2 ds = shadowMapSize.x * ddx( shadowCoord );
float2 dt = shadowMapSize.y * ddy( shadowCoord );
float error = max( length( ds + dt ), length( ds - dt ) );
return ErrorTexture.Sample( ErrorSampler, error ).rgb;
}
可視化について
• デモ作成でかなり重宝した。
– どこが悪いかが一目瞭然。
– 可視化することで調整しやすくなる
– 単なる目視だと見逃しがちな所も気を付けられる
実装も手軽なので
導入することを是非お勧めします!
その他の可視化方法については,以下を参照すると良いです。
Fan Zhang, Chong Zhao and Adrian Egli
“Visualize Your Shadow Map Techiniques”, GPU Pro, pp.15-29
Z-Partitioning Algorithm
代表例:
• Cascade Shadow Maps (CSM)
• Parallel-Split Shadow Maps (PSSM)
• Sample Distribution Shadow Maps (SDSM)
分割して,シャドウマップでかくすりゃいいんじゃね?
…というアイデア
Parallel-Split Shadow Maps
𝐶𝑖 = 𝜆𝐶𝑖
log
+ 1 − 𝜆 𝐶𝑖
uni 0 < 𝜆 < 1
対数分割スキーム 均一分割スキーム
𝐶𝑖
uni
= 𝑛 + 𝑓 − 𝑛
𝑖
𝑚𝐶𝑖
log
= 𝑛
𝑓
𝑛
𝑖
𝑚
𝑓 : ファークリップ平面までの距離
𝑛 ∶ ニアクリップ平面までの距離
𝑚 : カスケードの最大段数
𝑖 : 現在のカスケードの段数
𝐶𝑖を用いて
カスケードの分割位置を求める
問題が…
• フリッカリングが発生する。
– 単位キューブクリップのおかげで少し品質が上がる
– でも,カメラとシーンに依存するようになる。
– 結果,カスケードでフリッカリングが発生する。
安定化させる必要あり。
スイミング問題と呼ばれる
スイミング問題
• フリッカリングが発生するのは3パターン
– パターン1. スケール
次のフレーム
次のフレームでシャドウマップのテクセルサイズが変わる。
その結果,シャドウテストの結果が前フレームと異なる。
関心がある点
シャドウマップテクセル
ラスタライズされた状態の線
ライトのビューポイント
スイミング問題
• フリッカリングが発生するのは3パターン
– パターン2. オフセット
次のフレーム
浮動小数点の制度限界によるサブテクセルオフセットによって
交差した点のラスタライゼーションが異なる。
カメラが変化するときは,ほぼ毎回発生する。
スイミング問題
• フリッカリングが発生するのは3パターン
– パターン3. スケール + オフセット
視錘台
実際にはスケールとオフセットが一緒の場合が多い。
正確な解決方法
• バウンディングスフィアを利用する
– Michal Valient, “Stable Rendering of Cascade Shadow Maps”, ShaderX6 pp.231-238
– 採用例がいくつかある。[Killzone2/Final Fantasy 零式HD]
※図はMichal Valient, “Stable Rendering of Cascade Shadow Maps”, ShaderX6 pp.231-238 より引用
疑似コード
// Step1 : ライトの基底を計算
Vector3 dir = Normalize(World.GetColumn3(2)); // ライトのZ軸
Vector3 side = Normalize(World.GetColumn3(1)); // ライトのX軸
Vector3 up = Normalize(World.GetColumn3(0)); // ライトのY軸
// 全てのスプリットを更新
for(auto i=0; i<SplitCount; ++i)
{
// Step2 : 各スプリット'split[i]' のバウンディングスフィア 'bs' を計算する
Sphere bs = CalculateBoundingSphere(split[i]);
// ワールド空間におけるスフィアの中心座標を取得する
Vector3 center = InvWorldView * bs.GetCenter();
// スフィアの半径を取得する
float radius = bs.GetRadius();
// シャドウマップへの中心へとスフィアの中心を移動させ調整する
float x = ceilf( Dot(center, up) * sizeSM / raidus ) * radius / sizeSM; // 'sizeSM' はテクスチャサイズ.
float y = ceilf( Dot(center, side) * sizeSM / radius ) * radius / sizeSM;
center = up * x * side * y + dir * Dot(center, dir);
// Step3 : スプリットを指定するビュー行列'matrixView[i]'と射影行列'matrixProjection[i]'を更新する
Vector3 origin = center - dir * far; // ライトの位置を取得する.
matrixProjection[i] = MatrixOrthoProjection(-radius, radius, radius, -radius, near, far);
matrixView[i] = MatrixLookAt(origin, center, up);
}
利点と欠点
• 利点
– フリッカリングを正確に排除できる
• 欠点
– シャドウマップの解像度が無駄に使われる
=シャドウの品質が落ちる
– 均一なテクセル分布にしか使えない
=Projective Warping Algorithmと一緒に使えない
近似による解決方法
• スフィアを使わず,オフセットとスケールを回避する
– Fan Zhang, Alexander Zaprjagaev, Allan Bentham
“Practical Cascaded Shadow Maps”, ShaderX7 pp.305-329.
– オフセットを取り除くために,視錘台に相対な位置の量子化を用いる。
– スケールを取り除くために,事前定義された離散化レベルの範囲へとスケール値を量子化。
中心
スプリット
ライトの錘台
ライト
視錘台
スケールの問題
オフセットの問題
シャドウマップ シャドウマップ
回転
ライト
サイドビュー サイドビュー
スプリット
疑似コード
// スケール値を計算する.
// Notes: ライトの透視変換後の空間において,ビューポートの幅と高さは両方とも2である。
// 指定のスプリットに対するシャドウマップの大きさは,この空間におけるスプリットの角点で構成される境界の座標となる。
// 'maxX'と'minX'はそれぞれX値の最大値と最小値。
// 'maxY'と'minY'はそれぞれY値の最大値と最小値。
float scaleX = 2.0f / (maxX - minX); // X方向に対するスケール値.
float scaleY = 2.0f / (maxY - minY); // Y方向に対するスケール値.
// スケール値は64の離散レベルへと量子化する.(ShaderX7では経験的に64が良いと分かったためとの記述があります).
float scaleQuantizer = 64.0f;
// 量子化スケール
scaleX = 1.0f / ceilf(1.0f / scaleX * scaleQuantizer) * scaleQuantizer;
scaleY = 1.0f / ceilf(1.0f / scaleY * scaleQuantizer) * scaleQuantizer;
// オフセット値を計算
float offsetX = -0.5f * (maxX + minX) * scaleX; // X方向に対するオフセット.
float offsetY = -0.5f * (maxY + minY) * scaleY; // Y方向に対するオフセット.
// 量子化オフセット
float halfTextureSize = 0.5f * sizeSM;
offsetX = ceilf(offsetX * halfTextureSize) / halfTextureSize;
offsetY = ceilf(offsetY * halfTextureSize) / halfTextureSize;
ストレージ戦略
• カスケードシャドウマップをどうやって持つ?
– 別個のテクスチャ
– テクスチャアトラス
– テクスチャ配列
– キューブマップ
経験則として,
ジオメトリシェーダを
使わない方法がお勧め
v
0 1
2 3
(0, 1.0)(0, 0.5)
(1, 0.5)
(1, 0.5)(0.5, 1)
(0, 0)
(0, 1)
u
ジオメトリシェーダが走ることが遅い原因になる
http://www.gamedev.net/topic/650183-cascaded-shadows-maps-texture-atlas-or-texture-array/ より引用
1) 全部一度描画し,GSで複製して,2048 ×2048のテクスチャに1024×1024の1/4ずつ描画する → FPS = 21.1
2) 全部一度描画し,GSで複製して,1024 × 1024のテクスチャ配列を使用 → FPS = 22.4
3) インスタンス数を4にして全部一度描画し,2048 × 2048のテクスチャに1024 × 1024の1/4ずつ描画する → FPS = 42.7
4) 各カスケードに対して,カスケードごとにドローコールをサブミットして,テクスチャ配列を使用する → FPS = 42.1
自分の経験則とも合致。最適化無しのやっぱりジオメトリシェーダを使うと遅い!
スプリットをまたぐ場合は?
テクスチャアトラスを使う場合でPCFなどで境界をまたいでしまう場合の対策
→ Andrew Lauritzen,
“Parallel-Split Variance Shadow Maps”, In Proceedings of Graphics Interface 2007
でパフォーマンスを犠牲にせず,うまく解決する方法が記述されている。
スプリット境界
現在のフラグメント
隣のフラグメント
スプリット番号の計算
if Split ≠ Split∗
⇔ 2Split∗
− 2Split = 2Split > 0
⇔ 2Split ∗
− 2Split
> 0
⇔ ddx 2 𝑆𝑝𝑙𝑖𝑡 > 0
then
output Split
endif
z
矩形
TextureMatrix[split]によって変換される
u, v
u∗
, v∗
PSSM[split]についての
テクスチャ空間
𝜕u
𝜕x
= u∗
− u
PSSM[split]のミップマップチェイン
正しいLOD!
疑似コード
// 定数
const int SPLIT_COUNT = 3; //分割数.
// ピクセルシェーダ
int powerSplitIndex = pow(2, splitIndex);
int dx = abs(ddx(powerSplitIndex));
int dy = abs(ddy(powerSplitIndex));
int dxy = abs(ddx(dy));
int split = max(dxy, max(dx, dy)); //微分値の最大値を得る
if (powerIndex > 0) //ミスマッチが発生した場合
splitIndex = log(powerSplitIndex); //スプリット番号を更新
// 2SplitIndex
// 𝑑 2SplitIndex
/𝑑𝑥
// 𝑑 2SplitIndex
/𝑑𝑦
// 𝑑2
2SplitIndex
/𝑑𝑥𝑑𝑦
Sample Distribution Shadow Maps
※動画は,Andrew Lauritzen, Marco Salvi, Aaron Lefohn, “Sample Distribution Shadow Maps”,
Intel Developer Zone, https://software.intel.com/en-us/articles/sample-distribution-shadow-maps より引用
Sample Distribution Shadow Maps
適用方法:
1.深度バッファを得る
(深度プリパス or G-Bufferパスから)
2. コンピュートシェーダを用いて 深度バッファの最大・最小値を削減
(描画されない無駄な領域を削減するため)
3.削減された深度の最大・最小値から対数分割による領域を求める。
4.PSSMと同じようにライトのビュー射影行列を生成する。
5.生成した行列をシャドウマップに適用する。
Sample Distribution Shadow Maps
• メリット
– 影が凄く綺麗になる。
– カスケードのつなぎ目が滑らかになる
– 最悪のケースでもPSSMと同じ品質
– シーン依存
• デメリット
– ライト空間の分割計算をGPUでやる必要がある
– 他の手法に比べるとトリッキーな実装
– CPUによる視錐台カリングが適用できない
(GPU上で分割データが生成されるため)
• ゲームでの採用事例あり
– The Order : 1886
– Destiny
比較 SDSM off
※図は Matte Pettineo, “Rendering the Alternate History of The Order: 1886”, SIGGRAPH 2005 Advances in Real-Time Rendering in Games course より引用
比較 SDSM on
※図は Matte Pettineo, “Rendering the Alternate History of The Order: 1886”, SIGGRAPH 2005 Advances in Real-Time Rendering in Games course より引用
Adaptive Algorithm
代表例:
Adaptive Shadow Maps
Dynamic Adaptive Shadow Maps on Graphics Hardware
Rectilinear Texture Warping for Fast Adaptive Shadow Maps
※図は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, i3D 2012 より引用
Rectilinear Texture Warping
for Fast Adaptive Shadow Maps
※動画は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, http://www.cspaul.com/wordpress/publications_rosen-2012-i3d/ より引用
Rectilinear Texture Warping
for Fast Adaptive Shadow Maps
大事な所だけピクセルを多く割り当てりゃよくね?
・・・というアイデア
(a) 重要度マップを構築
(b) 2次元重要度マップを1次元のワーピングマップに変換
(1) XY方向を1次元の重要度マップへと落とし込む
(2) 重要度マップにブラーを掛ける
(3) 重要度マップからワーピングマップを構築
(c) RTWシャドウマップを描画する
(d) 要求された視点からの出力画像を描画する
※図は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, i3D 2012 より引用
重要度マップの生成
• 3つのシーンの解析手法
– Forward Analysis :ライトからみた視点で解析。
– Backward Analysis :カメラからみた視点で解析。
– Hybrid Analysis :上記2つの組み合わせ。
• 解析には重要度関数を使用
– Desired View Function
• レシーバーが見えたら1を返却,見えなかったら0を返却。
• Forward Analysis, Backward Analysisの両方で使用。
– Distance to Eye Function
• Forward Analysis ⇒ 1.0 – (ビュー空間での深度値)
• Backward Analysis ⇒ 1.0 – (深度値)
– Shadow Edge Function
• 隣接する8ピクセルに対して,2ピクセル間の差分を求めて不連続テストを行う。
• Forward Analysisに対して使用。
– Surface Normal Function
• 1 + β・saturate( dot( -normal, viewDirection ) ) ※βは付加重要度で,論文中では2.0を使用。
• 3つの解析手法すべてについて使用できる。
ワーピングマップの構築
(1) 2次元重要度マップの縦・横方向それぞれについて,最大重要度を求める。
(2) ガウシアンブラーを用いて,隣接するセルと重要度値をブレンドする。
⇒ ブラーによる2つの重要な効力
① 一貫性を保証するための,サンプリング上でのスムーズな変化を生成。
②非線形ラスタライズ化によるエラーを低減。
(3) 下記の式を用いて,変位を求めてワープマップを生成。
【不要】黒
【必要】ダークブルー
𝐼 𝑢 = max(𝐼 𝑢0, 𝐼 𝑢1, 𝐼 𝑢2, ⋯ ) 𝐼𝑣 = max(𝐼𝑣0, 𝐼𝑣1, 𝐼𝑣2, ⋯ )
𝐺𝑒𝑡𝑊𝑎𝑟𝑝 𝑘 =
𝐼𝑗
𝑘−1
𝑗=1
𝐼𝑗
𝑛
𝑗=1
−
𝑘
𝑛
※図は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, i3D 2012 より引用
シャドウマップの描画
• 各頂点に対する出力領域を計算する
• ワープを適用することによって
出力画像平面上の位置 を求める
• 最終的に三角形が
ライスタライズされる
VMP L  LM :ビュー射影行列 V :頂点
'
P
 
 yyy
xxx
PGetWarpYPP
PGetWarpXPP


'
'
はクリップ空間なので(-1.0 ~ +1.0 )yx PP ,
GetWarp メソッドはテクスチャ空間なので(0.0 ~1.0)
GetWarpYGetWarpX, はクリップ空間に変換する必要あり
※図は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, i3D 2012 より引用
出力フレーム画像を生成
• Forward Analysisの場合
ライトの視点で解析しているので,通常のシャドウマップと同じ。
シーンのジオメトリをもう一度描画する必要があり,
RTWシャドウマップで陰影づけをする。
• Backward, Hybrid Analysisの場合
カメラからの視点で解析しているので,描画イメージがある状態。
シャドウのみの計算が必要で,画像の上に合成する。
• シャドウマップのテクスチャ座標は,ワーピングによって求める。
 
 tGetWarpTtt
sGetWarpSss


'
'
※図は,Paul Rosen, “Rectilinear texture warping for fast adaptive shadow maps”, i3D 2012 より引用
制限事項
• Forward Analysisの場合
– 初期の深度バッファの解像度があまりに小さいときに,
重要なディテールが失われる可能性があり,
重要度マップから除外されてしまう。
⇒ 高解像度で深度バッファを描画することによって処理することが可能だが,
適切なサイズの見つけ方が難しい問題。
• Backward Analysisの場合
– 視点が異なる場合は,同じ重要度マップの位置に異なる重要度
で射影される可能性がある。
⇒ 高い視点を保持することで対応。(それでいいのか?)
• テッセレーションが不十分な場合にアーティファクトが発生する。
– 非線形ラスタライゼーションがサポートされていないため
⇒ 適度に細かくしようね。
Filtering Algorithm
代表例:
Percentage Closer Filter Shadow Map
Percentage Closer Soft Shadow Map
Variance Shadow Map
Summed Area Variance Shadow Map
Exponential Shadow Map
Exponential Variance Shadow Map
Moment Shadow Map
※図は,Andrew Lauritzen, “Summed-Area Variance Shadow Maps”, GPU Gems3,
https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch08.html より引用
Variance Shadow Map
影かどうかをバイナリではなくて確率的に求められればいいんじゃね?
…というアイデア
チェビシェフの不等式
𝑃 𝑥 ≥ 𝑡 ≤ 𝑝 𝑚𝑎𝑥 𝑡 ≡
𝜎2
𝜎2 + 𝑡 − 𝜇 2
𝜇 = 𝐸 𝑥 = 𝑀1
𝜎2
= 𝐸 𝑥2
− 𝐸 𝑥 2
= 𝑀2 − 𝑀1
2
平均値
分散
𝑡深度値
𝑀1 = 𝐸 𝑥 = 𝑥𝑝 𝑥 𝑑𝑥
∞
−∞
𝑀2 = 𝐸 𝑥2
= 𝑥2
𝑝 𝑥 𝑑𝑥
∞
−∞
フィルタ領域について
のモーメント
任意の確率分布について
ある値以上または以下である
確率がどれぐらいであるのか?
大体の見当をつけるのに用いる
疑似コード
float ChebyshevUpperBound(float2 Moments, float t)
{
// 片側不等式が有効なのは, t > Moments.xの場合
float p = (t <= Moments.x);
// 分散を計算
float Variance = Moments.y – (Moments.x * Moments.x);
Variance = max(Variance, g_MinVariance);
// 確率的上限の計算
float d = t – Moments.x;
float p_max = Variance / (Variance + d * d);
return max(p, p_max);
}
float ShadowContribution(float2 LightTexCoord, float DistanceToLight)
{
// 分散シャドウマップからモーメントを読み込む.
float Moments = texShadow.Sample(ShadowSampler, LightTexCoord).xy;
// チェビシェフ上限の計算
return ChebyshevUpperBound(Momemtns, DistanceToLight);
}
バイアス
• PCFはフィルタカーネルが大きくなるとシャドウアクネが出ることがある。
• VSMの第2モーメントを使ったバイアス問題の解決手法が提案されている。
𝑓 𝑥, 𝑦 = 𝜇 + 𝑥
𝜕𝑓
𝜕𝑥
+ 𝑦
𝜕𝑓
𝜕𝑦
𝑀2 = 𝐸 𝑓2
= 𝐸 𝜇2
+ 𝐸 𝑥2
𝜕𝑓
𝜕𝑥
2
+ 𝐸𝑦 𝑦2
𝜕𝑓
𝜕𝑦
2
𝐸 𝜇2 = 𝜇2
𝐸 𝑥2
= 𝐸 𝑦2
= 𝜎2
=
1
2
2
=
1
4
𝑀2 = 𝜇2
+
1
4
𝜕𝑓
𝜕𝑥
2
+
𝜕𝑓
𝜕𝑦
2
局所的に平面的な分布と考え,次の式で表現する。
次に,𝑀2
を計算する。期待値演算の線形性と𝐸 𝑥 = 𝐸 𝑦 = 𝐸 𝑥𝑦 = 0という事実より
ハーフピクセルの標準偏差を持つ対称性のあるガウス分布としてピクセルを表現するので,次を得る
これより
第2モーメントを使って1ピクセルを表現することを考える
疑似コード
// 分散シャドウマップ描画時のモーメント計算
float ComputeMoments(float Depth)
{
float2 Moments;
// 1つの目のモーメントは深度そのもの
Moments.x = Depth;
// 深度の偏微分を計算
float dx = ddx(Depth);
float dy = ddy(Depth);
// 2つ目のモーメントをピクセル範囲で計算
Moments.y = Depth * Depth + 0.25 * (dx * dx + dy * dy);
return Moments;
}
ライトブリーディング
※図はhttp://wrice.blogspot.jp/2010/04/why-does-light-leak-happens-on-soft.html より引用
オブジェクトが重なる場合に
光が漏れるようなアーティファクトが発生する
なぜ発生する?
オブジェクトA, B, Cの深度値をそれぞれ 𝑎, 𝑏, 𝑐とする。
𝑀1 =
𝑎 + 𝑏
2
𝑀2 =
𝑎2 + 𝑏2
2
𝜇 =
𝑏 + 𝑎
2
𝜎2 =
𝑏 − 𝑎 2
4
∆𝑥 = 𝑏 − 𝑎
∆𝑦 = 𝑐 − 𝑏
を不等式の右辺に代入
𝑝 ∆𝑦 =
1
4
∆𝑥2
1
4 ∆𝑥2 + ∆𝑦 +
1
2 ∆𝑥
2
=
1
4
∆𝑥2
1
2
∆𝑥2 + ∆𝑥∆𝑦 + ∆𝑦2※図は,Andrew Timothy Lauritzen,
“Rendering Antialiased Shadows using Warped Variance Shadow Maps”, より引用
なぜ発生する?
∆𝑥が与えられると,
𝑝 ∆𝑦 は𝑂
1
∆𝑦2 のようなフォールオフになる
𝑝 ∆𝑦 =
1
4
∆𝑥2
1
2
∆𝑥2 + ∆𝑥∆𝑦 + ∆𝑦2
一方,オブジェクトBよりも,
ライトから遠いオブジェクトCは
Bによって完全に遮蔽されるので,
正しい可視性は全ての∆𝑦 > 0についてゼロ
この相違がライトブリーディング
じゃ,どうする?(1)
• 単純な解決方法
ある最小強度未満の値を0にクランプして,
残りの値を0(最小強度)から1にマップされるように𝑝maxを修正する。
再マッピングする
float linstep(float mini, float maxi, float v)
{ return clamp((v – mini) / (maxi – mini), 0, 1); }
float ReduceLightBleeding(float p_max, float Amount)
{ return linstep(Amount, 1, p_max); }
※図は,Andrew Lauritzen, “Summed-Area Variance Shadow Maps”, GPU Gems3, https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch08.html より引用
じゃ,どうする?(2)
• もうちょっと違う解決方法
シャドウのエッジを検出して,
シャドウのエッジ境界部分にだけVSMを適用する。
通常のVSM エッジにVSMを適用
疑似コード(1)
float shadowEdgeDetection(float2 projTexCoord, float depth, float bias)
{
float halfTexelSize = 0.5f / shadowMapSize;
float2 offsets[4] =
{
float2(-halfTexelSize, -halfTexelSize), float2(-halfTexelSize, +halfTexelSize),
float2(+halfTexelSize, -halfTexelSize), float2(+halfTexelSize, +halfTexelSize)
};
float samplesSum = 0.0f;
for (int i = 0; i < 4; i++)
{
if (tex2D(shadowMapSampler_point, projTexCoord.xy + offsets[i]).r > depth - bias)
samplesSum += 1.0f;
}
return samplesSum;
}
疑似コード(2)
PS_OUTPUT main(PS_INPUT input)
{
PS_OUTPUT output;
input.normal = normalize(input.normal);
input.projTexCoord.x = +0.5f * input.projTexCoord.x + 0.5f;
input.projTexCoord.y = -0.5f * input.projTexCoord.y + 0.5f;
float depth = input.projTexCoord.z;
float4 ambient = g_Ambient;
float4 diffuse = max(dot(input.normal, -lightDirection), 0.0f);
float bias = g_Bias;
float samplesSum = shadowEdgeDetection(input.projTexCoord.xy, depth, bias);
if (samplesSum < g_Threshold1)
output.color = ambient;
else if (samplesSum > g_Threshold2)
output.color = ambient + diffuse;
else
output.color = ambient + diffuse * VSM(input.projTexCoord.xy, depth, bias, VSM_tailCutOff);
return output;
}
Layered Variance Shadow Map
VSM LVSM
深度を複数のレイヤーに分割してしまって
異なるレイヤー間でのライトブリーディングを排除すればよくね?
…というアイデア。
標準のVSMよりは良い結果が得られるが,
ライトブリーディングを完全に避けるためには,多くレイヤーが必要。
※図は,Andrew Timothy Lauritzen, “Rendering Antialiased Shadows using Warped Variance Shadow Maps”, より引用
Convolution Shadow Maps
田村尚希,
“レンダリスト養成講座 2.0 ~Real-Time, All-Frequency Shadows in Dynamic Scenes~”,
CEDEC 2008
を参照されたし。
Exponential Shadow Map
影かどうかを0か1ではなく,
指数関数で滑らかにつなげばいいんじゃね?
…というアイデア
※図は,Louis Bavoil, “Advanced Soft Shadow Mapping Techniques”, Game Developers Conference 2008 より引用
疑似コード
// ESMキャスタ描画
float4 ESM_Caster( const VS_OUTPUT v ) : COLOR
{
float4 ret = exp( (v.vTexPos.w + fOffset) * fLargeConstant );
return ret;
}
// ESMレシーバ描画
float4 ESM_Receiver( const VS_OUTPUT v ) : COLOR
{
float ez = tex2Dproj( s1, v.vTexPos ).x;
float ed = exp( -v.vTexPos.z * fLargeConstant );
float4 col = v.vColor;
col.rgb *= saturate( ed * ez - fThreshold );
return col;
}
アーティファクト
• シャドウが欠損する問題が発生する
※図は,Louis Bavoil, “Advanced Soft Shadow Mapping Techniques”, Game Developers Conference 2008 より引用
Exponential Variance Shadow Map
分散シャドウマップと指数シャドウマップ
両方を組み合わせてみるといいんじゃね?
・・・というアイデア
※図は,Andrew Timothy Lauritzen, “Rendering Antialiased Shadows using Warped Variance Shadow Maps”, より引用
Exponential Variance Shadow Maps
• 深度値と深度値の2乗を格納する代わりに,
指数深度と指数深度値の2乗を格納する。
• 指数関数は
∆𝑥
∆𝑦
の比率を減らす効果がある。
従って,VSMのようなライトブリーディングを低減できる。
• EVSMはVSMとESMの両方が失敗する場合のみ
ライトブリーディングの影響を受ける。
• VSMの再マッピングとESMの定数𝑘の2つの要素による
ライトブリーディング制御ができる。
疑似コード
float EVSM
(
float2 projTexCoord,
float depth,
float bias,
float tailCutoff,
float k
)
{
float2 moments = tex2D(shadowMapSampler_linear, projTexCoord).rg;
if (moments.x >= exp(k * (depth - bias)))
return 1.0f;
float variance = moments.y - moments.x*moments.x;
float delta = exp(ESM_k * depth) - moments.x;
float p_max = variance / (variance + delta*delta) - tailCutoff;
return saturate(p_max);
}
Moment Shadow Map
VSMは2次までのモーメントを使用。
じゃ,もっと高次のモーメント使えばいいんじゃね?
…というアイデア。
※理論が難しくて良く理解できなかったので,詳細は論文(+Appendix)を参照してください。
モーメント問題に対して仮説を立てて条件付けをして,うまく解いているようです。
※図は,Christoph Peter and Reinhard Klein, “Moment Shadow Mapping”, i3D 2015 より引用
Moment Shadow Map
• 4つのモーメントを使用(𝑧, 𝑧2
, 𝑧3
, 𝑧4
)
• VSMのように2段階で生成
(1) シーンを描画し,4つのモーメントをシャドウマップに格納。
(2) フィルタを掛ける(ガウスブラーまたはミップマップ生成)
• 次の手順によりシャドウ強度を求める。
1. 𝑏 ≔ 1 − 𝛼 ∙ 𝑏 + 𝛼 ∙ 0.5, 0.5, 0.5, 0.5 ⊺
2. 𝑐 ∈ ℝ3
について解くためにコレスキー分解を使用する:
1 𝑏1′ 𝑏2′
𝑏1′ 𝑏2′ 𝑏3′
𝑏2′ 𝑏3′ 𝑏4′
∙ 𝑐 =
1
𝑧𝑓
𝑧𝑓
2
3. 2次方程式の解の公式を用いて𝑧について𝑐3 ∙ 𝑧2
+ 𝑐2 ∙ 𝑧 + 𝑐1 = 0を解く。
𝑧2 ≤ 𝑧3である𝑧2, 𝑧3 ∈ ℝも同様にして解く。
4. if 𝑧𝑓 ≤ 𝑧3:return 𝐺 ≔ 0
5. else if 𝑧𝑓 ≤ 𝑧3 : return 𝐺 ≔
𝑧 𝑓∙𝑧3−𝑏1
′
∙ 𝑧 𝑓+𝑧3 +𝑏2
′
𝑧3−𝑧2 ∙ 𝑧 𝑓−𝑧2
6. else : return 𝐺 ≔ 1 −
𝑧2∙𝑧3−𝑏1
′
∙ 𝑧2+𝑧3 +𝑏2
′
𝑧 𝑓−𝑧2 ∙ 𝑧 𝑓−𝑧3
疑似コード
float ComputeMSMHamburger(float4 moments, float fragmentDepth , float depthBias, float momentBias)
{
float4 b = lerp(moments, float4(0.5f, 0.5f, 0.5f, 0.5f), momentBias);
float3 z;
z[0] = fragmentDepth - depthBias;
float L32D22 = mad(-b[0], b[1], b[2]);
float D22 = mad(-b[0], b[0], b[1]);
float squaredDepthVariance = mad(-b[1], b[1], b[3]);
float D33D22 = dot(float2(squaredDepthVariance, -L32D22), float2(D22, L32D22));
float InvD22 = 1.0f / D22;
float L32 = L32D22 * InvD22;
float3 c = float3(1.0f, z[0], z[0] * z[0]);
c[1] -= b.x;
c[2] -= b.y + L32 * c[1];
c[1] *= InvD22;
c[2] *= D22 / D33D22;
c[1] -= L32 * c[2];
c[0] -= dot(c.yz, b.xy);
float p = c[1] / c[2];
float q = c[0] / c[2];
float D = (p * p * 0.25f) - q;
float r = sqrt(D);
z[1] =- p * 0.5f - r;
z[2] =- p * 0.5f + r;
float4 switchVal = (z[2] < z[0]) ? float4(z[1], z[0], 1.0f, 1.0f) :
((z[1] < z[0]) ? float4(z[0], z[1], 0.0f, 1.0f) : float4(0.0f,0.0f,0.0f,0.0f));
float quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1])/((z[2] - switchVal[1]) * (z[0] - z[1]));
float shadowIntensity = switchVal[2] + switchVal[3] * quotient;
return 1.0f - saturate(shadowIntensity);
}
比較結果
https://youtu.be/ThyWHCrYniA?t=59s
※図は,Christoph Peter and Reinhard Klein, “Moment Shadow Mapping”, http://cg.cs.uni-bonn.de/en/publications/paper-details/peters-2015-msm/より引用
比較結果
https://youtu.be/ThyWHCrYniA?t=59s
※図は,Christoph Peter and Reinhard Klein, “Moment Shadow Mapping”, http://cg.cs.uni-bonn.de/en/publications/paper-details/peters-2015-msm/より引用
比較結果
https://youtu.be/ThyWHCrYniA?t=59s
※図は,Christoph Peter and Reinhard Klein, “Moment Shadow Mapping”, http://cg.cs.uni-bonn.de/en/publications/paper-details/peters-2015-msm/より引用
Percentage Closer Soft Shadow
ライトから遠いところ大きくぼかせば,よりそれらしく見えるんじゃね?
…というアイデア。
※図は,Louis Bavoil, “Percentage-Closer Soft Shadows”,
http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/PercentageCloserSoftShadows/doc/PercentageCloserSoftShadows.pdf より引用
Percentage Closer Soft Shadow
• 3ステップでシャドウイングする
– Step1.ブロッカー探索
• シャドウマップを探索し,シェーディング点よりライトに近い方向に
ブロッカーがある場合は,ブロッカーの深度値の合計値を計算し,
ブロッカー数で合計値を割り,深度平均を求める。
– Step2.半影推定
• ブロッカー/レシーバーのライトからの距離とライトサイズに基づき,
次式により半影を推定する。
𝑤 𝑃𝑒𝑛𝑢𝑚𝑏𝑟𝑎 =
𝑑 𝑅𝑒𝑐𝑒𝑖𝑣𝑒𝑟 − 𝑑 𝐵𝑙𝑜𝑐𝑘𝑒𝑟 ∙ 𝑤 𝐿𝑖𝑔ℎ𝑡
𝑑 𝐵𝑙𝑜𝑐𝑘𝑒𝑟
– Step3.フィルタリング
• Step2.で計算した半影推定に比例したカーネルサイズを用いて,
PCFフィルタリングを実行する。
[ゲームでの採用事例あり] FAR CRY4 / Assassin’s Creed Unity / GTA5
その他
• Subpixel Shadow Mapping
• Efficient Virtual Shadow Maps for Many Lights
• Adaptive Depth Bias for Shadow Map
Subpixel Shadow Mapping
境界付近が汚くなるので,
境界部分だけレイトレしよう
…というアイデア
• Conservative Rasterizationと128bitRGBAに格納したジオメトリデータを使って,
レイと三角形の交差判定を行う。
※図は,Pascal Lecocq, Jean-Ecudes Marvie et. al, “Sub-Pixel Shadow Mapping”, i3D 2014 より引用
Subpixel Shadow Mapping
Efficient Virtual Shadow Maps for Many Lights
• お餅さんの解説を参照。
“輪読発表資料:Efficient Virtual Shadow Maps for Many Lights”
http://www.slideshare.net/omochi64/ss-47145338?qid=bd52bda4-2f71-4290-90ae-51d5ce6cab94&v=&b=&from_search=1
※図は,Ola Olsson, Erik Sintorn, et.al, “Efficient Virtual Shadow Maps for Many Lights”, i3D 2014より引用
Adaptive Depth Bias for Shadow Map
𝑎𝑑𝑎𝑝𝑡𝑖𝑣𝑒𝐷𝑒𝑝𝑡ℎ𝐵𝑖𝑎𝑠 = 𝑜𝑝𝑡𝑖𝑚𝑎𝑙𝐷𝑒𝑝𝑡ℎ𝐵𝑖𝑎𝑠 + 𝑎𝑑𝑎𝑝𝑡𝑖𝑣𝑒𝐸𝑝𝑠𝑖𝑙𝑜𝑛
𝜖 = 𝑓′ 𝑥 ∆𝑥
∆𝑥 = 𝑠𝑐𝑒𝑛𝑒𝑆𝑐𝑎𝑙𝑒 × 𝐾Depth compression
𝜖 =
𝑙𝑓 − 𝑑𝑒𝑝𝑡ℎ × 𝑙𝑓 − 𝑙𝑛 2
𝑙𝑓 × 𝑙𝑛 × 𝑙𝑓 − 𝑙𝑛
× 𝑠𝑐𝑒𝑛𝑒𝑆𝑐𝑎𝑙𝑒 × 𝐾
OpenGL
論文では 0.0001を設定
AABBの対角線
の長さ
※図は,Hang Dou, Yajie Yan, et.al, “Adaptive depth bias for shadow maps”, Journal of Compute Graphics Technique, Vol3, No.4, 2014より引用
アルゴリズム
※図は,Hang Dou, Yajie Yan, et.al, “Adaptive depth bias for shadow maps”, Journal of Compute Graphics Technique, Vol3, No.4, 2014より引用
適用例
※図は,Hang Dou, Yajie Yan, et.al, “Adaptive depth bias for shadow maps”, Journal of Compute Graphics Technique, Vol3, No.4, 2014より引用
実行時間
※DualはWEISKOPF, D., AND ERTL, T. 2003. “Shadow mapping based on dual depth layers”. In Proceedings of Eurographics, vol. 3, 53–60.の手法
※図は,Hang Dou, Yajie Yan, et.al, “Adaptive depth bias for shadow maps”, Journal of Compute Graphics Technique, Vol3, No.4, 2014より引用
まだ,確認していない論文
• “4D-rasterization for Fast Soft Shadow Rendering”, ESGR 2016
This paper describes an algorithm for rendering soft shadows efficiently by generalizing conventional triangle
projection and rasterization from 2D to 4D. The rectangular area light source is modeled with a point light source that
translates with two degrees of freedom. This generalizes the projection of triangles and of output image samples, as
seen from the light, to the locus of projections as the light translates. The generalized projections are rasterized to
determine a conservative set of sample/ triangle pairs, which are then examined to derive light occlusion masks for
each sample. The algorithm is exact in the sense that each element of the occlusion mask of a sample is computed
accurately by considering all potentially blocking triangles. The algorithm does not require any type of
precomputation so it supports fully dynamic scenes. We have tested our algorithm on several scenes to render
complex soft shadows accurately at interactive rates.
• “Fast Shadow Map Rendering for Many Lights Settings”, ESGR 2016
In this paper we present a method to efficiently cull large parts of a scene prior to shadow map computations for many-
lights settings. Our method is agnostic to how the light sources are generated and thus works with any method of light
distribution. Our approach is based on previous work in culling for ray traversal to speed up area light sampling.
• “Filtering Multilayer Shadow Maps for Accurate Soft Shadows”, EG 2016
In this paper, we introduce a novel technique for pre-filtering multi-layer shadow maps. The occluders in the scene
are stored as variable-length lists of fragments for each texel. We show how this representation can be filtered by
progressively merging these lists. In contrast to previous pre-filtering techniques, our method better captures the
distribution of depth values, resulting in a much higher shadow quality for overlapping occluders and occluders with
different depths. The pre-filtered maps are generated and evaluated directly on the GPU, and provide efficient
queries for shadow tests with arbitrary filter sizes. Accurate soft shadows are rendered in real-time even for complex
scenes and difficult setups. Our results demonstrate that our pre-filtered maps are general and particularly scalable.
“CG技術の実装と数理2016”(http://ime.ist.hokudai.ac.jp/~mcg/2016/program.html)
で持田恵祐さん(早稲田大学)が
説明しているようなので,資料が上がったらそちらを見ましょう。
まとめ
• 興味があるもの・説明しやすいものだけをピックアップ
(時間の都合上)
• ライティングを頑張るなら,シャドウも頑張りましょう。
ライティングが良くてもシャドウが超へぼいと台無しです。
• デバッグ機能があると調整しやすい。
積極的に使えるものは取り入れましょう。
• アルゴリズムはアプリを考えて選択しよう。
SDSM+(EVSM/MSM) なら実用しやすい。
• 新しい手法にはアンテナを張っておきましょう。
論文はしっかり読めるようになりましょう(自分も含めて)
• レイトレできるならレイトレが最強。
みなさん,レイトレしましょう。
最後に…
• 貴重な時間をわざわざいただきありがとうございました。
• このセミナーで何か得られるものがあったなら幸いです。
• もっといい手法知っていたら,後でこっそり教えてください。
私事ですが…
• この度,本を出版する機会を頂きました!
• 現在,鋭意執筆中。
• 書籍についての詳細な情報は
今後,TwitterやBlogを通じて告知する予定です。
• 長い目で生暖かく見守ってください。
以上!

More Related Content

What's hot

【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』
【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』
【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』Unity Technologies Japan K.K.
 
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...KLab Inc. / Tech
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!Unity Technologies Japan K.K.
 
Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_
 Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_ Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_
Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_Unity Technologies Japan K.K.
 
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~エピック・ゲームズ・ジャパン Epic Games Japan
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作るtorisoup
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~UnityTechnologiesJapan002
 
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術 次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術 Masafumi Takahashi
 
UE4 LODs for Optimization -Beginner-
UE4 LODs for Optimization -Beginner-UE4 LODs for Optimization -Beginner-
UE4 LODs for Optimization -Beginner-com044
 
Unityではじめるオープンワールド制作 エンジニア編
Unityではじめるオープンワールド制作 エンジニア編Unityではじめるオープンワールド制作 エンジニア編
Unityではじめるオープンワールド制作 エンジニア編Unity Technologies Japan K.K.
 

What's hot (20)

【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』
【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』
【Unite Tokyo 2018】トゥーンシェーダートークセッション#1『リアルタイムトゥーンシェーダー徹底トーク』
 
UE4のスレッドの流れと Input Latency改善の仕組み
UE4のスレッドの流れとInput Latency改善の仕組みUE4のスレッドの流れとInput Latency改善の仕組み
UE4のスレッドの流れと Input Latency改善の仕組み
 
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...
CEDEC 2020 - 高品質かつ低負荷な3Dライブを実現するシェーダー開発 ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スク...
 
60fpsアクションを実現する秘訣を伝授 基礎編
60fpsアクションを実現する秘訣を伝授 基礎編60fpsアクションを実現する秘訣を伝授 基礎編
60fpsアクションを実現する秘訣を伝授 基礎編
 
猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021
猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021
猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
 
Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_
 Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_ Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_
Unity道場京都スペシャル トゥーンシェーディングとノンフォトリアリスティック風絵づくり入門_
 
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
 
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~
UE4のライティング解体新書~効果的なNPRのためにライティングの仕組みを理解しよう~
 
猫でも分かるUMG
猫でも分かるUMG猫でも分かるUMG
猫でも分かるUMG
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
 
UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法
 
Mask Material only in Early Z-passの効果と仕組み
Mask Material only in Early Z-passの効果と仕組みMask Material only in Early Z-passの効果と仕組み
Mask Material only in Early Z-passの効果と仕組み
 
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術 次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術
次の世代のインタラクティブレンダリング5つの挑戦と10の滅ぶべき技術
 
Lightmassの仕組み ~Lightmap編~ (Epic Games Japan: 篠山範明)
Lightmassの仕組み ~Lightmap編~ (Epic Games Japan: 篠山範明)Lightmassの仕組み ~Lightmap編~ (Epic Games Japan: 篠山範明)
Lightmassの仕組み ~Lightmap編~ (Epic Games Japan: 篠山範明)
 
UE4 LODs for Optimization -Beginner-
UE4 LODs for Optimization -Beginner-UE4 LODs for Optimization -Beginner-
UE4 LODs for Optimization -Beginner-
 
Unityではじめるオープンワールド制作 エンジニア編
Unityではじめるオープンワールド制作 エンジニア編Unityではじめるオープンワールド制作 エンジニア編
Unityではじめるオープンワールド制作 エンジニア編
 

Viewers also liked

Aiming 開発ゲームの裏側
Aiming 開発ゲームの裏側Aiming 開発ゲームの裏側
Aiming 開発ゲームの裏側Katsutoshi Makino
 
Tabc vol3 テクニカルアーティストを始めるにあたって
Tabc vol3 テクニカルアーティストを始めるにあたってTabc vol3 テクニカルアーティストを始めるにあたって
Tabc vol3 テクニカルアーティストを始めるにあたってfumoto kazuhiro
 
Application parallelisation Android - Klaas Vangend
Application parallelisation Android - Klaas VangendApplication parallelisation Android - Klaas Vangend
Application parallelisation Android - Klaas Vangendナム-Nam Nguyễn
 
Unityのポストエフェクトで遊ぶ!
Unityのポストエフェクトで遊ぶ!Unityのポストエフェクトで遊ぶ!
Unityのポストエフェクトで遊ぶ!Yamato Honda
 
Weighted Blended Order Independent Transparency
Weighted Blended Order Independent TransparencyWeighted Blended Order Independent Transparency
Weighted Blended Order Independent Transparencyzokweiron
 
レイトレ合宿3!!! 5分間アピールプレゼン―Pocol
レイトレ合宿3!!! 5分間アピールプレゼン―Pocolレイトレ合宿3!!! 5分間アピールプレゼン―Pocol
レイトレ合宿3!!! 5分間アピールプレゼン―PocolProjectAsura
 
Unity & VR (Unity Roadshow 2016)
Unity & VR (Unity Roadshow 2016)Unity & VR (Unity Roadshow 2016)
Unity & VR (Unity Roadshow 2016)ozlael ozlael
 
Unity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことUnity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことKatsutoshi Makino
 
ACES 1.0 OpenColorIO config - Siggraph 2015
ACES 1.0 OpenColorIO config - Siggraph 2015ACES 1.0 OpenColorIO config - Siggraph 2015
ACES 1.0 OpenColorIO config - Siggraph 2015hpduiker
 
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜Drecom Co., Ltd.
 
レイトレ合宿2!! 3分間アピールプレゼン―Pocol
レイトレ合宿2!! 3分間アピールプレゼン―Pocolレイトレ合宿2!! 3分間アピールプレゼン―Pocol
レイトレ合宿2!! 3分間アピールプレゼン―PocolProjectAsura
 
Q(キュー)サイトに学ぶ、 演出のためのHTML5
Q(キュー)サイトに学ぶ、 演出のためのHTML5Q(キュー)サイトに学ぶ、 演出のためのHTML5
Q(キュー)サイトに学ぶ、 演出のためのHTML5Yamato Honda
 
Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化Katsutoshi Makino
 
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…Drecom Co., Ltd.
 
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)ozlael ozlael
 
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015hpduiker
 
マシな画面を作る
マシな画面を作るマシな画面を作る
マシな画面を作るokumasama
 
声の実体化体験 - HTML5でつくるデジタルインスタレーション -
声の実体化体験 - HTML5でつくるデジタルインスタレーション -声の実体化体験 - HTML5でつくるデジタルインスタレーション -
声の実体化体験 - HTML5でつくるデジタルインスタレーション -Yamato Honda
 
Kansai cedec 2015_fumoto
Kansai cedec 2015_fumotoKansai cedec 2015_fumoto
Kansai cedec 2015_fumotofumoto kazuhiro
 

Viewers also liked (20)

Aiming 開発ゲームの裏側
Aiming 開発ゲームの裏側Aiming 開発ゲームの裏側
Aiming 開発ゲームの裏側
 
Tabc vol3 テクニカルアーティストを始めるにあたって
Tabc vol3 テクニカルアーティストを始めるにあたってTabc vol3 テクニカルアーティストを始めるにあたって
Tabc vol3 テクニカルアーティストを始めるにあたって
 
Application parallelisation Android - Klaas Vangend
Application parallelisation Android - Klaas VangendApplication parallelisation Android - Klaas Vangend
Application parallelisation Android - Klaas Vangend
 
Unityのポストエフェクトで遊ぶ!
Unityのポストエフェクトで遊ぶ!Unityのポストエフェクトで遊ぶ!
Unityのポストエフェクトで遊ぶ!
 
Weighted Blended Order Independent Transparency
Weighted Blended Order Independent TransparencyWeighted Blended Order Independent Transparency
Weighted Blended Order Independent Transparency
 
レイトレ合宿3!!! 5分間アピールプレゼン―Pocol
レイトレ合宿3!!! 5分間アピールプレゼン―Pocolレイトレ合宿3!!! 5分間アピールプレゼン―Pocol
レイトレ合宿3!!! 5分間アピールプレゼン―Pocol
 
Unity & VR (Unity Roadshow 2016)
Unity & VR (Unity Roadshow 2016)Unity & VR (Unity Roadshow 2016)
Unity & VR (Unity Roadshow 2016)
 
Unity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことUnity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだこと
 
ACES 1.0 OpenColorIO config - Siggraph 2015
ACES 1.0 OpenColorIO config - Siggraph 2015ACES 1.0 OpenColorIO config - Siggraph 2015
ACES 1.0 OpenColorIO config - Siggraph 2015
 
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜
CEDEC 2015 Cocos2d-x と社内基盤の付き合い方 〜アップストリームファーストを目指して〜
 
レイトレ合宿2!! 3分間アピールプレゼン―Pocol
レイトレ合宿2!! 3分間アピールプレゼン―Pocolレイトレ合宿2!! 3分間アピールプレゼン―Pocol
レイトレ合宿2!! 3分間アピールプレゼン―Pocol
 
Q(キュー)サイトに学ぶ、 演出のためのHTML5
Q(キュー)サイトに学ぶ、 演出のためのHTML5Q(キュー)サイトに学ぶ、 演出のためのHTML5
Q(キュー)サイトに学ぶ、 演出のためのHTML5
 
Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化Shadow gunのサンプルから学べるモバイル最適化
Shadow gunのサンプルから学べるモバイル最適化
 
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…
CEDEC 2015 IoT向け汎用protocol MQTTのリアルタイムゲーム通信利用と実装、そして未来へ…
 
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)
뭣이 중헌디? 성능 프로파일링도 모름서 - 유니티 성능 프로파일링 가이드 (IGC16)
 
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015
ACEScg: A Common Color Encoding for Visual Effects Applications - DigiPro 2015
 
マシな画面を作る
マシな画面を作るマシな画面を作る
マシな画面を作る
 
Aclt1
Aclt1Aclt1
Aclt1
 
声の実体化体験 - HTML5でつくるデジタルインスタレーション -
声の実体化体験 - HTML5でつくるデジタルインスタレーション -声の実体化体験 - HTML5でつくるデジタルインスタレーション -
声の実体化体験 - HTML5でつくるデジタルインスタレーション -
 
Kansai cedec 2015_fumoto
Kansai cedec 2015_fumotoKansai cedec 2015_fumoto
Kansai cedec 2015_fumoto
 

Similar to 中級グラフィックス入門~シャドウマッピング総まとめ~

ICCV2019読み会「Learning Meshes for Dense Visual SLAM」
ICCV2019読み会「Learning Meshes for Dense Visual SLAM」ICCV2019読み会「Learning Meshes for Dense Visual SLAM」
ICCV2019読み会「Learning Meshes for Dense Visual SLAM」Sho Kagami
 
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19Deep Learning JP
 
Unity名古屋セミナー [Shadowgun]
Unity名古屋セミナー [Shadowgun]Unity名古屋セミナー [Shadowgun]
Unity名古屋セミナー [Shadowgun]MakotoItoh
 
CVPR2018 参加報告(速報版)初日
CVPR2018 参加報告(速報版)初日CVPR2018 参加報告(速報版)初日
CVPR2018 参加報告(速報版)初日Atsushi Hashimoto
 
Soft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning
Soft Rasterizer: A Differentiable Renderer for Image-based 3D ReasoningSoft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning
Soft Rasterizer: A Differentiable Renderer for Image-based 3D ReasoningKohei Nishimura
 
GLSLtech2018 レイマーチングで半歩差のつく小技集
GLSLtech2018 レイマーチングで半歩差のつく小技集GLSLtech2018 レイマーチングで半歩差のつく小技集
GLSLtech2018 レイマーチングで半歩差のつく小技集Kei Mesuda
 
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)kanejaki
 
Flashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3DFlashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3DKatsushi Suzuki
 
3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!vi-iv
 
3Dマップを活用したVisual Localization
3Dマップを活用したVisual Localization3Dマップを活用したVisual Localization
3Dマップを活用したVisual LocalizationHajime Taira
 
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...Sho Kagami
 
Neural scene representation and rendering の解説(第3回3D勉強会@関東)
Neural scene representation and rendering の解説(第3回3D勉強会@関東)Neural scene representation and rendering の解説(第3回3D勉強会@関東)
Neural scene representation and rendering の解説(第3回3D勉強会@関東)Masaya Kaneko
 
Cocos2d x-sprite3d
Cocos2d x-sprite3dCocos2d x-sprite3d
Cocos2d x-sprite3daktsk
 
第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習Naoya Chiba
 
論文読み会2018 (CodeSLAM)
論文読み会2018 (CodeSLAM)論文読み会2018 (CodeSLAM)
論文読み会2018 (CodeSLAM)Masaya Kaneko
 
SDSoC でストリーム
SDSoC でストリームSDSoC でストリーム
SDSoC でストリームryos36
 
SSII2020 [O3-01] Extreme 3D センシング
SSII2020 [O3-01]  Extreme 3D センシングSSII2020 [O3-01]  Extreme 3D センシング
SSII2020 [O3-01] Extreme 3D センシングSSII
 
論文読み会(DeMoN;CVPR2017)
論文読み会(DeMoN;CVPR2017)論文読み会(DeMoN;CVPR2017)
論文読み会(DeMoN;CVPR2017)Masaya Kaneko
 
WWW2017論文読み会 Information Cascades と Graph Algorithms
WWW2017論文読み会 Information Cascades と Graph AlgorithmsWWW2017論文読み会 Information Cascades と Graph Algorithms
WWW2017論文読み会 Information Cascades と Graph Algorithmscyberagent
 
Learning Spatial Common Sense with Geometry-Aware Recurrent Networks
Learning Spatial Common Sense with Geometry-Aware Recurrent NetworksLearning Spatial Common Sense with Geometry-Aware Recurrent Networks
Learning Spatial Common Sense with Geometry-Aware Recurrent NetworksKento Doi
 

Similar to 中級グラフィックス入門~シャドウマッピング総まとめ~ (20)

ICCV2019読み会「Learning Meshes for Dense Visual SLAM」
ICCV2019読み会「Learning Meshes for Dense Visual SLAM」ICCV2019読み会「Learning Meshes for Dense Visual SLAM」
ICCV2019読み会「Learning Meshes for Dense Visual SLAM」
 
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19
[DL輪読会]3D Human Pose Estimation @ CVPR’19 / ICCV’19
 
Unity名古屋セミナー [Shadowgun]
Unity名古屋セミナー [Shadowgun]Unity名古屋セミナー [Shadowgun]
Unity名古屋セミナー [Shadowgun]
 
CVPR2018 参加報告(速報版)初日
CVPR2018 参加報告(速報版)初日CVPR2018 参加報告(速報版)初日
CVPR2018 参加報告(速報版)初日
 
Soft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning
Soft Rasterizer: A Differentiable Renderer for Image-based 3D ReasoningSoft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning
Soft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning
 
GLSLtech2018 レイマーチングで半歩差のつく小技集
GLSLtech2018 レイマーチングで半歩差のつく小技集GLSLtech2018 レイマーチングで半歩差のつく小技集
GLSLtech2018 レイマーチングで半歩差のつく小技集
 
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)
第18回コンピュータビジョン勉強会@関東「ICCV祭り」発表資料(kanejaki)
 
Flashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3DFlashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3D
 
3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!
 
3Dマップを活用したVisual Localization
3Dマップを活用したVisual Localization3Dマップを活用したVisual Localization
3Dマップを活用したVisual Localization
 
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...
CVPR2019 読み会「Understanding the Limitations of CNN-based Absolute Camera Pose ...
 
Neural scene representation and rendering の解説(第3回3D勉強会@関東)
Neural scene representation and rendering の解説(第3回3D勉強会@関東)Neural scene representation and rendering の解説(第3回3D勉強会@関東)
Neural scene representation and rendering の解説(第3回3D勉強会@関東)
 
Cocos2d x-sprite3d
Cocos2d x-sprite3dCocos2d x-sprite3d
Cocos2d x-sprite3d
 
第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習
 
論文読み会2018 (CodeSLAM)
論文読み会2018 (CodeSLAM)論文読み会2018 (CodeSLAM)
論文読み会2018 (CodeSLAM)
 
SDSoC でストリーム
SDSoC でストリームSDSoC でストリーム
SDSoC でストリーム
 
SSII2020 [O3-01] Extreme 3D センシング
SSII2020 [O3-01]  Extreme 3D センシングSSII2020 [O3-01]  Extreme 3D センシング
SSII2020 [O3-01] Extreme 3D センシング
 
論文読み会(DeMoN;CVPR2017)
論文読み会(DeMoN;CVPR2017)論文読み会(DeMoN;CVPR2017)
論文読み会(DeMoN;CVPR2017)
 
WWW2017論文読み会 Information Cascades と Graph Algorithms
WWW2017論文読み会 Information Cascades と Graph AlgorithmsWWW2017論文読み会 Information Cascades と Graph Algorithms
WWW2017論文読み会 Information Cascades と Graph Algorithms
 
Learning Spatial Common Sense with Geometry-Aware Recurrent Networks
Learning Spatial Common Sense with Geometry-Aware Recurrent NetworksLearning Spatial Common Sense with Geometry-Aware Recurrent Networks
Learning Spatial Common Sense with Geometry-Aware Recurrent Networks
 

中級グラフィックス入門~シャドウマッピング総まとめ~