こんねねー。Pocolです。
ハーフベクトルのヤコビアンが良く分かりません。
shikihuikuさんの記事を見れば済むことなんですが,せっかくなのでメモっておこうと思います。
カテゴリー: Program
Program関係のお話
超雑訳 Rearchitecting Spatiotemporal Resampling for Production
こんらみ,Pocolです。
今日は,
[Wyman 2021] Chris Wyman, Alexey Panteleev, “Rearchitecting Spatiotemporal Resampling for Production”, High-Performance Graphics 2021.
を読んでみようと思います。
いつもながら誤字・誤訳があるかと思いますので,ご指摘頂ける場合は正しい翻訳例と共に指摘して頂けると有難いです。
超雑訳 Importance Resampling for Global Illumination
こんにちわ,Pocolです。
今日は,
[Talbot 2005] Justin F. Talbot, Davit Cline, Parris Egbert, “Importance Resampling for Global Illumination”, EGSR’05, pp.139-146, 2005.
を読んでみようと思います。
いつもながら誤字・誤訳があるかと思いますので,ご指摘頂ける場合は正しい翻訳例と共に指摘して頂けると有難いです。
Bilateral Upsampling
こんにちわ,Pocolです。
今日はバイラテラルアップサンプリングについてメモをしておこうと思います。
パフォーマンスを稼ぐために,低解像度で描画しておき,それを元解像度に戻したいという場面が,ゲームグラフィックスでは多々出てきます。具体的には,SSAOやSSRなどの計算です。
ただ単にバイリニア補間で元解像度に戻してしまうとエッジ部分などでアーティファクトが発生してしまうことがあります。
こうしたアーティファクトを避けるために使われる手法の中の一つとして,Bilateral Upsamplingがあります。
バイラテラルアップサンプリングは,法線と深度によってバイリニアウェイトを修正します。サンプルは以下のように,バイリニアの重み,法線の類似度による重み,深度の類似度による重みの3つによって重みづけされます。
以上から求められた重みを使ってサンプルを重みづけします。下図の通りです。
実装例ですが,もんしょさんが「DirectXの話 第121回 Bilateral Upsampling」の記事にてサンプルコードをアップしてくださっています。有難いです。
シェーダコードを抜粋すると下記の通りです。
float4 RenderUpsamplingPS( OutputVS inPixel ) : SV_TARGET { const float2 kScreenSize = g_ScreenParam.xy * 2.0; const float2 kScreenHalfSize = g_ScreenParam.xy; const float4 kBilinearWeights[4] = { float4( 9.0/16.0, 3.0/16.0, 3.0/16.0, 1.0/16.0 ), float4( 3.0/16.0, 9.0/16.0, 1.0/16.0, 3.0/16.0 ), float4( 3.0/16.0, 1.0/16.0, 9.0/16.0, 3.0/16.0 ), float4( 1.0/16.0, 3.0/16.0, 3.0/16.0, 9.0/16.0 ) }; // Hi-Resピクセルのインデックスを求める int2 hiResUV = (int2)(inPixel.texCoord0 * kScreenSize + float2(0.1, 0.1)); int hiResIndex = (1 - (hiResUV.y & 0x01)) * 2 + (1 - (hiResUV.x & 0x01)); float4 hiResND = texNormalDepth.Load( int3(hiResUV, 0), int2(0, 0) ); // Low-Resから4ピクセルの法線・深度を求める int2 lowResUV = (int2)(inPixel.texCoord0 * kScreenHalfSize.xy + float2(0.1, 0.1)); float4 lowResND[4]; float lowResAO[4]; switch (hiResIndex) { case 0: lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) ); lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 0) ); lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 1) ); lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 1) ); lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r; lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(1, 0) ).r; lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(0, 1) ).r; lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(1, 1) ).r; break; case 1: lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 0) ); lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) ); lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 1) ); lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 1) ); lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 0) ).r; lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r; lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 1) ).r; lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(0, 1) ).r; break; case 2: lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, -1) ); lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, -1) ); lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) ); lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 0) ); lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(0, -1) ).r; lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(1, -1) ).r; lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r; lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(1, 0) ).r; break; case 3: lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, -1) ); lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, -1) ); lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 0) ); lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) ); lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(-1, -1) ).r; lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(0, -1) ).r; lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 0) ).r; lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r; break; } // 法線のウェイトを求める float totalWeight = 0.0; float ao = 0.0; for( int i = 0; i < 4; ++i ) { // 法線のウェイトを求める float normalWeight = dot( lowResND[i].xyz, hiResND.xyz ); normalWeight = pow( saturate(normalWeight), 32.0 ); // 深度のウェイトを求める float depthDiff = hiResND.w - lowResND[i].w; float depthWeight = 1.0 / (1.0 + abs(depthDiff)); // 総合する float weight = normalWeight * depthWeight * kBilinearWeights[hiResIndex][i]; totalWeight += weight; ao += lowResAO[i] * weight; } ao /= totalWeight; return float4(ao, ao, ao, 1); }
…ということで,Bilateral Upsamplingの話でした。
もしかしたら,Quad系のWaveIntrinsics使って実装した方がナウいかもしれないですね(※試してないので,出来なかったらごめんなさい)。
※追記
Quad Intrinsics使って実装できました。
WaveGetLaneIndex() % 4でhiResIndexを算出します。一度現在位置での,lowResNDとlowResAOを先頭の方でサンプリングしておき,あとはループでQuadReadLaneAt(lowResND, i)と QuadReadLaneAt(lowResAO, i)で,処理対象を持ってきます。これでswitchケース分が丸っとなくせるのと,テクスチャフェッチ回数が減らせます。
GPU Architecture & Compute Shader
いつもメモし忘れて,ツイートを見失うのでメモ。
Carlos Fuentes 氏によるGPU Architecture & Compute Shaderというスライドが非常にわかりやすくておススメです。
Here is a new lecture I added to my game programming classes at the university. Actually is a collection of different resources/articles students can find on the internet about compute shaders and an introduction to GPU architectures. https://t.co/MDRAHcflcM
— Carlos Fuentes (@CharlieCoding) February 26, 2023
超雑訳 An analytic BRDF for materials with spherical Lambertian scatters
こんらみ。Pocolです。
今日は,
[d’Eon 2021] Eugene d’Eon, “An analytic BRDF for materials with spherical Lambertian scatters”, Eurographics Symposium on Rendering 2021.
を読んでみようと思います。
いつもながら,誤字・誤訳があるかと思いますので,ご指摘頂ける場合は正しい翻訳と共に指摘して頂けると有難いです。
超雑訳 Cache and Bandwidth Aware Real-Time Subsurface Scattering (3)
こんにちわ、Pocolです。
前回に引き続き5章を見ていくことにします。
前回までの内容は下記を参照してください。
- 超雑訳 Cache and Bandwidth Aware Real-Time Subsurface Scattering (1)
- 超雑訳 Cache and Bandwidth Aware Real-Time Subsurface Scattering (2)
超雑訳 Cache and Bandwidth Aware Real-Time Subsurface Scattering (1)
こんにちわ、Pocolです。
今日は…
[Xie 2021] Tiantian Xie, “Cache and Bandwidth Aware Real-Time Subsurface Scattering”, University of Maryland, 2021.
を読んでみようと思います。
いつもながら誤字・誤訳があるかと思いますので,ご指摘頂ける場合は正しい翻訳と共に指摘していただけると幸いです。
タイルシェーディングについて
こんにちわ。Pocolです。
今日は,タイルシェーディングについての実装メモを書くことにします。