カリング手法とZTestについて
背面カリング・PreZ・PostZ・ZprepassRendering・HiZ・オクルージョンカリング・ポータルカリング
などなどの情報を自分用のメモとしても技術をまとめておきます。
PreZとPostZ
PreZ(EarlyZ)
PixcelShaderが実行されるより前にZTestをする。Testした結果既に描かれているDepthより奥側だった場合はそれ以降の描画は行わない。
PreZを有効にするにはいくつか注意するポイントがあります
・PicxelShaderの出力にSV_Depthを含めてはいけない。
・PixcelShader内でdiscardやclipのような棄却処理を行ってはいけない 。
PostZ
PreZが効かなかった場合にPixcelShader実行後にZTestされる。なるべくPreZが使えるほうが良い。
ZprepassRendering
モデルを描画するまえに先にDepthMapを作っておく手法
こうすることにより、
既にDepthが描かれているのでモデルの描画順を順不同で描画しても問題ない。
ZprepassRenderingではない場合は、手前から描画したほうがDepthTestに成功する確率が高いのでカメラに近い順でモデルをソートして描画する手法がいい。
HiZ(階層型Zバッファ)
DepthMapにミップマップがあります。CPUから境界球(x,y,z,radius)をGPUに転送し、GPUはMipが高い順に可視判定を行う。その後CPUで読み取る。
Hierarchical Z-Buffer Occlusion Culling
ZCompression
読んでも全てを理解できなかった。こちら参照
http://fileadmin.cs.lth.se/graphics/research/papers/depth2006/dbc.pdf
Fast Z Clear
バッファ全体をクリアするのではなく、クリアしたことにするタグを付ける。
HyperZ
PreZ+ZCompression + FastZClear + HiZ これらが実現されているとHyperZと言う。
カリング手法
背面カリング
頂点の並びが時計回りのときは前面で反時計回りのときは背面になります。
時計回りを英語でClockWiseと言い、反時計回りはCounterclockwiseと言います。
DirectX11で背面カリングする場合はD3D11_RASTERIZER_DESC構造体のCullModeにD3D11_CULL_BACKを入れます。
視錐台カリング
カメラの領域外のモデルを描画しない技術です。
near-farの判定と上下左右のプレーンより内側にある判定をする技術です。
ポータルカリング
インドアな環境でよく用いられる手法です。
A,B,C,Dという部屋がドアによってつながっている時に、ドアを視錐台カリングしてその部屋の可視判定をします。
オクルージョンカリング
オクルージョンカリングとはあるモデルが他のモデルによって隠されていて、カメラに映らない時に描画を実行しないようにする技術です。オクルージョンカリングにも様々な手法があるので知っている限りで列挙しておきます。
オクルージョンカリングで以下2つはよく使われる用語です。
オクルーダー:他モデルを隠すモデル。大きいほうがいい。
オクルーディー:他モデルによって隠されるモデル。
・Hizを用いたオクルージョンカリング(前述のHizで説明済み)
・CPUでオクルージョンカリング(ソフトウェアによるオクルージョン・カリング | iSUS)
CPUでDepthMapを用意して、CPUでラスタライズをする手法。
・OcclusionQueryを発行して描画したモデルのピクセル数を取得
オクルージョンカリングのミドルウェア
・Umbra(Umbra Support)
オクルージョンカリングのゲームでの実例
GRAVITY DAZE:4Gamer.net ― [GTMF 2012]「GRAVITY DAZE」開発スタッフが語る,アートコンセプトをPS Vita上で実現した手法の実際
BattleField3:http://twvideo01.ubm-us.net/o1/vault/gdc2011/slides/Daniel_Collin_Programming_Culling_The_Battlefield.pdf.pdf
KillZone3:Practical Occlusion Culling on PS3
参考リンク:
CEDEC2016: Unreal Engine 4 のレンダリングフロー総おさらい
なにか間違えやアドバイスなどあればご指摘願います。
3.GLSL 2D螺旋構造虹の解析
http://glslsandbox.com/e#41999.0
2つの円が色を変えながらくるくる回っています。
どうやって作ってるんだろう...
ということで解析してみました。(最後の一行は理解出来なかった)
void main()
{
vec2 r = resolution;
// 現在のピクセル位置(0~横解像度,0~縦解像度)
vec2 o = gl_FragCoord.xy - r/2.;
// (-横解像度*0.5 ~ +横解像度*0.5,-縦解像度*0.5 ~ +縦解像度*0.5)
o = vec2(length(o) / r.y - .3, atan(o.y,o.x));
// 極座標系に変換 ".3"=円の半径 o.xは外にかけて増えるmaxで0.62ぐらい o.yはぐるっと回っている-3.14 ~ 0 ~ +3.14
// oを表示するとこうなる
vec4 s = .07*cos(1.5*vec4(0,1,2,3) + time + o.y + cos(o.y) * cos(time));
// sがなにやってるかひと目では分かりません。こういうときはsを表示してみます。
// gl_FragColor=s*(1./0.07).;return;
// sの画像です。画像なので動いていないが、極座標系がくるくる回っています。
// cosの中にcosがある..ややこしいです。括弧内の2つのcosを消してみると...
// .07*cos(1.5*vec4(0,1,2,3) + time + o.y);
// すると2つの円が同じ速度で回転しています
//vec4(0,1,2,3)にtimeを足すことで各要素のxyzwが増えていきます。
// そこに、o.yを足すことで極座標系なので回ります。
// 最後にcosと*0.07をすることで-0.07~+0.07になります。
vec4 e = s.yzwx;
//eはsの要素を並び替えたものです。
vec4 f = max(o.x-s,e-o.x);
//o.x-s はo.xで作られる円を-sして円の中心の場所を±0.07ずらしています。中心が黒で外が白。
// e-o.xも同じで円の中心をずらしていますが、e-o.xで中心が白く外が黒。
//vec4 f = max(o.x-s.x,e.x-o.x); x成分だけ表示した時のfは以下の画像になります。
// もとのvec4 f = max(o.x-s,e-o.x);に大きい値(10)をかけて表示すると以下のようになります。
gl_FragColor = dot( clamp(f*r.y,0.,1.) , 72.*(s-e)) * (s-.1) + f;
// fをコメントアウトすると背景が真っ黒になります。
// 最後が分からない...............参考になる情報などあれば欲しいです
}
2GLSL レイマーチで山を描く
最近はShadertoyで遊んでいます。
とてもわかりやすい山のシェーダがありましたので、自分用のメモのためにすべての行の意味を日本語でコメントを追記しました。
山を描く学習をするときに誰かの助けになればと思って公開していますので、よかったら見てみてください
1GLSL 初めてのWebGL
以前より、shaderを手軽に書きたいと思っていた。
そこで、ShaderToyを利用した。
ShaderToyはwebglを投稿するサイトです。pixivのglslバージョンです。
投稿されているものは、煙の表現、水の流れる表現、水の屈折、月日に照らされた水面などコードだけでこんなにきれいな表現が出来ているのかと驚かされます。
コードだけでモデルを表示されている方もいます。
私もshadertoy始めました。
ドラッグすると青い●がくっついてきます。
https://www.shadertoy.com/view/lsjyDz
続きを読む