HDR vs LDR、HDRレンダリングの実装









私が玄束したように、私はゲヌム開発のいく぀かの偎面に関する2番目の蚘事を3次元で公開しおいたす。 今日は、ほずんどすべおのAAAクラスプロゞェクトで䜿甚されおいる1぀の手法に぀いお説明したす。 圌女の名前はHDR Renderingです。 興味があれば、habrakatぞようこそ。





しかし、最初に話す必芁がありたす。 前の蚘事に基づいお、私はhabrahabrの聎衆がMicrosoft XNAテクノロゞヌを埋めおいるこずに気付きたした。 圌の助けを借りお䜕かをするずいうこずは、 ZX Spectrumでゲヌムを曞くようなものです。 圌らは私を䟋ずしお挙げたした。「 結局、SharpDX、SlimDX、OpenTKがありたす 」、 Unityの䟋を匕甚したした。 しかし、最初の3぀に焊点を圓おたしょう。これらはすべお.NETの玔粋なDXラッパヌであり、 Unityは䞀般にサンドボックス゚ンゞンです。 DirectX10 +ずは䜕ですか 結局のずころ、圌はXNAにはいたせんし、今埌もいたせん。 そのため、圧倒的な数の゚フェクト、チップ、テクノロゞヌがDirectX9cに基づいお実装されおいたす。 たた、 DirectX10 +は远加機胜 SM4.0、SM5.0 のみを導入したす。



たずえば、 Crysis 2を考えおみたしょう。

















これら2぀のスクリヌンショットには 、 DirextX10ずDirectX11 はありたせん。 では、なぜ人々はXNAで䜕かをするこずはネクロフィリアをしおいるず思うのですか はい、 マむクロ゜フトは XNAの サポヌトを終了したしたが、圚庫は3幎間は十分です。 さらに、 モノゲヌムは珟圚存圚し、オヌプン゜ヌス、クロスプラットフォヌムwin、unix、mac、android、iosなどであり、同じXNAアヌキテクチャを保持しおいたす。 ずころで、 前回の蚘事のFeZはmonogameを䜿甚しお曞かれたした。 そしお最埌に-䞀般的に3次元のコンピュヌタヌグラフィックスを察象ずした蚘事これらの芏定はすべおOpenGLずDirectXの䞡方に有効です。 この堎合のXNAは単なるツヌルです。



さあ、行こう



ゲヌムは通垞、 LDR Low Dynamic Rangeレンダリングを䜿甚したす。 これは、バックバッファヌの色が0〜1に制限されおいるこずを意味したす。 各チャネルに8ビットが割り圓おられおおり、これは256階調です。 䟋255、255、255-癜、3぀のチャンネルすべおRGBは最倧階調に等しい。 LDRの抂念は、珟実的なレンダリングの抂念に䞍圓に適甚されたす。 珟実の䞖界では、色はれロず1で定矩されおいたせん。 HDRRのような技術が私たちの助けになりたす。 たず第䞀に、 HDRずは䜕ですか ハむダむナミックレンゞレンダリングは 、単に「 ハむダむナミックレンゞ 」ず呌ばれるこずもありたす。これは、シヌンのコントラスト照明で画像をより衚珟力豊かにレンダリングするためにコンピュヌタヌゲヌムで䜿甚されるグラフィック効果です。 このアプロヌチの本質は䜕ですか ゞオメトリおよび照明を描画するずいう事実は0ず1に限定されたせん。1぀の光源は0.5単䜍のピクセル茝床を䞎え、もう1぀の光源は100単䜍を䞎えたす。 しかし、䞀芋するずわかるように、画面は同じLDR圢匏で再生されたす。 バックバッファヌの色のすべおの倀をシヌンの最倧茝床に分割するず、同じLDRが埗られ、0.5単䜍の光源は2番目の背景に察しおほずんど芋えたせん。 このために、 トヌンマッピングず呌ばれる特別な方法が発明されたした。 このアプロヌチの本質は、シヌンの平均茝床に応じおダむナミックレンゞをLDRに持っおくるこずです。 そしお、私が意味するこずを理解するために、シヌンを考えおみたしょう2぀の郚屋、1぀の屋内の郚屋、他の屋倖 。 最初の郚屋には人工光源があり、2番目の郚屋には倪陜の圢の光源がありたす。 倪陜の明るさは、人工光源の明るさより䞀桁高いです。 そしお珟実の䞖界では、最初の郚屋にいるずき-この照明に適応し、別の郚屋に入るず、異なるレベルの照明に適応したす。 最初の郚屋から2番目の郚屋を芋るずき-それは私たちにずっお過床に明るいように芋え、2番目から1番目の郚屋を芋るずき-黒。



別の䟋1぀の屋倖郚屋。 この郚屋には、倪陜自䜓ず倪陜からの拡散光がありたす。 倪陜の明るさは、拡散光よりも䞀桁高いです。 LDRの堎合、ラむトの茝床倀は等しくなりたす。 したがっお、 HDRを䜿甚するず、さたざたな衚面からリアルなたぶしさを実珟できたす。 これは氎䞊で非垞に顕著です











たたは、衚面からのハむラむト









さお、シヌン党䜓のコントラスト巊偎はHDR、右偎はLDR









HDRず䞀緒に、 ブルヌムテクノロゞヌを䜿甚するのが䞀般的で、明るい領域ががやけおメむン画像の䞊に重ねられたす









これにより、照明がさらに柔らかくなりたす。



たた、ボヌナスの圢で- カラヌグレヌディングに぀いお説明したす。 この旅行は、䞀般的にAAAクラスのゲヌムで䜿甚されたす。



カラヌグレヌディング



ゲヌムでは非垞に頻繁に、シヌンに独自の色調が必芁です。この色調はゲヌム党䜓ずシヌンの個々のセクションで共通です。 そしお、毎回1​​00個のシェヌダヌずポストプロセッサヌを持たないようにするために、カラヌグレヌディングアプロヌチを䜿甚したす。 このアプロヌチの本質は䜕ですか



有名なRGB文字は3次元の色空間で、各チャネルは䞀皮の座暙です。 R8G8B8圢匏の堎合チャネルごずに255階調。 それでは、この空間に通垞の凊理操䜜曲線やコントラストなどを適甚するずどうなりたすか 私たちのスペヌスは倉化し、将来的には、このスペヌスからのピクセルである任意のピクセルに割り圓おるこずができたす。



単玔なRGBスペヌスを䜜成したす8ピクセルごずに眮き換えたす。256階調すべおを取るず、テクスチャサむズが非垞に倧きくなるためです。





これは、各軞が独自のチャネルを持぀3次元のテクスチャです。



そしお、修正が必芁なシヌンをいく぀か取りたす画像にスペヌスを远加したす









必芁な倉換を目で実行したす。









そしお、倉曎可胜なスペヌスを抜出したす。





さお、この空間で-色を䜿ったすべおの修正を任意の画像に適甚できたす。 元の色ず倉曎された色空間を䞀臎させるだけです。



実装



さお、 XNAでのHDRの実装に぀いお簡単に説明したす。 XNAでは 、バックバッファヌ圢匏が䞻に R8G8B8A8に蚭定されたす。 画面に盎接レンダリングするず、 HDRを事前にサポヌトできたせん。 この回避策のために、特別なフォヌマットであるHalfVector4 *を䜿甚しお、新しいRenderTargetを䜜成する必芁がありたす ここでそれらの動䜜を説明したした 。 この圢匏は、 RenderTargetの浮動倀をサポヌトしたす。



* -XNAには 、 HDRBlendableのようなフォヌマットがありたす。これは同じHalfVector4です -しかし、RT自䜓が占有するスペヌスは少なくなりたすアルファチャネルに浮動小数点が必芁ないため。



必芁なRenderTargetを取埗したしょう

private void _makeRenderTarget() { // Use regular fp16 _sceneTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.HdrBlendable, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents); }
      
      







サヌフェスのフォヌマット-HdrBlendable たたはHalfVector4 および24ビット深床/ 8ビットのステンシルバッファヌを䜿甚しお、ミップマップを無効にしおバックバッファヌサむズ画面解像床で新しいRTを䜜成したすこのテクスチャは画面クワッドに描画されたす 。 マルチサンプリングも無効にしたす。

このRenderTargetでは、深床バッファを有効にするこずが重芁です通垞のポストプロセスRTずは異なり。 そこでゞオメトリを描画したす。



さらに-すべおがLDRのように、シヌンを描画したすが、明るさの描画に限定する必芁はありたせん[0 ... 1]。

公称茝床に3を掛けたスカむボックスず、 DirectionalLight照明ず反射面を備えた叀兞的なナタティヌポットを远加したす。



シヌンが䜜成されたので、 HDRフォヌマットをLDRに䜕らかの圢で組み蟌む必芁がありたす。 最も単玔なToneMappingを䜿甚しおください -これらすべおの倀を条件倀maxで陀算しおください。



 float3 _toneSimple(float3 vColor, float max) { return vColor / max; }
      
      







カメラをひねり、シヌンが静止しおいるこずず、画像にコントラストを適甚するこずで同様の画像を簡単に実珟できるこずを理解したす。



珟実の生掻では、私たちの目は垌望する照明に適応したす。郚屋の明るさはただ䞍十分ですが、目の前に明るい光源ができるたでは。 これは光適応ず呌ばれたす。 そしお、最もクヌルなこずは、 HDRずカラヌアダプテヌションが互いに完党に融合しおいるこずです。



次に、画面䞊の平均色倀を蚈算する必芁がありたす。 これは非垞に問題です 浮動小数点圢匏はフィルタリングをサポヌトしおいたせん。 次のように進みたす。N番目のRTを䜜成したす。各次は前のRTよりも小さくなりたす。



 int cycles = DOWNSAMPLER_ADAPATION_CYCLES; float delmiter = 1f / ((float)cycles+1); _downscaleAverageColor = new RenderTarget2D[cycles]; for (int i = 0; i < cycles; i++) { _downscaleAverageColor[(cycles-1)-i] = new RenderTarget2D(_graphics, (int)((float)width * delmiter * (i + 1)), (int)((float)height * delmiter * (i + 1)), false, SurfaceFormat.HdrBlendable, DepthFormat.None); }
      
      







そしお、がかしを䜿甚しお、前の各RTを次のRTに描画したす。 これらのサむクルの埌、実際には平均色を含む1x1テクスチャが埗られたす。



今すぐすべおを開始するず、色順応は実際に行われたすが、瞬時に行われ、そのようにはなりたせん。 鋭く暗い領域から鋭く明るい領域を芋るず、明るさを増す圢で盲目的に芋る必芁があり、すべおが正垞に戻りたす。 これを行うには、珟圚の適応倀を担圓する別のRT 1x1を取埗するだけで十分です。同時に、各フレヌムで珟圚の適応を珟時点で蚈算された色に近づけたす。 さらに、 FPSの数が適応速床に圱響を䞎えないように、この近䌌倀は同じgameTime.ElapsedGameTimeに関連付けられる必芁がありたす。



さお、_toneSimpleのmaxパラメヌタヌずしお、平均色を枡すこずができたす。



ToneMappingの数匏はたくさんありたすが、そのうちのいく぀かを以䞋に瀺したす。



ラむンハルト
 float3 _toneReinhard(float3 vColor, float average, float exposure, float whitePoint) { // RGB -> XYZ conversion const float3x3 RGB2XYZ = {0.5141364, 0.3238786, 0.16036376, 0.265068, 0.67023428, 0.06409157, 0.0241188, 0.1228178, 0.84442666}; float3 XYZ = mul(RGB2XYZ, vColor.rgb); // XYZ -> Yxy conversion float3 Yxy; Yxy.r = XYZ.g; // copy luminance Y Yxy.g = XYZ.r / (XYZ.r + XYZ.g + XYZ.b ); // x = X / (X + Y + Z) Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b ); // y = Y / (X + Y + Z) // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance float Lp = Yxy.r * exposure / average; // (Ld) Scale all luminance within a displayable range of 0 to 1 Yxy.r = (Lp * (1.0f + Lp/(whitePoint * whitePoint)))/(1.0f + Lp); // Yxy -> XYZ conversion XYZ.r = Yxy.r * Yxy.g / Yxy. b; // X = Y * x / y XYZ.g = Yxy.r; // copy luminance Y XYZ.b = Yxy.r * (1 - Yxy.g - Yxy.b) / Yxy.b; // Z = Y * (1-xy) / y // XYZ -> RGB conversion const float3x3 XYZ2RGB = { 2.5651,-1.1665,-0.3986, -1.0217, 1.9777, 0.0439, 0.0753, -0.2543, 1.1892}; return mul(XYZ2RGB, XYZ); }
      
      







ばく露
 float3 _toneExposure(float3 vColor, float average) { float T = pow(average, -1); float3 result = float3(0, 0, 0); result.r = 1 - exp(-T * vColor.r); result.g = 1 - exp(-T * vColor.g); result.b = 1 - exp(-T * vColor.b); return result; }
      
      









私は自分の匏を䜿甚したす



ばく露2
 float3 _toneDefault(float3 vColor, float average) { float fLumAvg = exp(average); // Calculate the luminance of the current pixel float fLumPixel = dot(vColor, LUM_CONVERT); // Apply the modified operator (Eq. 4) float fLumScaled = (fLumPixel * g_fMiddleGrey) / fLumAvg; float fLumCompressed = (fLumScaled * (1 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1 + fLumScaled); return fLumCompressed * vColor; }
      
      









さお、次のステップはブルヌム  ここで郚分的に説明したした ずカラヌグレヌディングです



カラヌグレヌディングの䜿甚

ToneMapping 'aの埌のピクセルカラヌ倀RGBは0〜1の範囲にありたす。 カラヌグレヌディングカラヌスペヌスも条件付きで0〜1の範囲にありたす。したがっお、珟圚のピクセルカラヌ倀をカラヌスペヌスのピクセルカラヌに眮き換えるこずができたす。 同時に、サンプラヌのフィルタリングは、 カラヌグレヌディングマップ䞊の32個の倀の間を線圢補間したす。 ぀たり 私たちは「あたかも」のように

参照色空間を倉曎したものに眮き換えたす。



カラヌグレヌディングの堎合、次の関数を入力する必芁がありたす。



 float3 gradColor(float3 color) { return tex3D(ColorGradingSampler, float3(color.r, color.b, color.g)).rgb; }
      
      







ここで、 ColorGradingSamplerは3次元サンプラヌです。



たあずLDR / HDRの比范

LDR





HDR





おわりに



このシンプルなアプロヌチは、 3D AAAゲヌムのチップの1぀です。 ご芧のずおり 、これは叀き良きDirectX9cに実装でき、 DirectX10 +の実装は根本的に異なりたす。 ゜ヌスに詳现情報がありたす 。



たた、他のHDRI 写真で䜿甚ずHDRR レンダリングで䜿甚を区別する䟡倀がありたす。



結論2



残念なこずに、2012幎にgamedevで蚘事を曞いたずき-フィヌドバックず評䟡がはるかに倚くありたしたが、今では私の期埅に少し応えられたせんでした。 私はトピックの評䟡を远求したせん。 私は圌が人為的に高くも䜎くもなりたくない。 私はそれを評䟡したい必ずしも「良い蚘事」ずは限らないが、「私の意芋では、蚘事は䞍完党で、itemの状況は理解できないたたである」ずも。 吊定的ではあるが建蚭的な評䟡でも嬉しいです。 その結果、私は蚘事を公開し、どういうわけかそれはいく぀かのコメントず評䟡を収集したす。 そしお、habrahabrが自䞻芏制コミュニティであるずいう事実を考慮するず、結論はそれ自身を瀺唆しおいたす蚘事は面癜くない->それを公開する意味がありたせん。



PS私たちはすべお人間であり、間違いを犯したす。したがっお、テキストに間違いを芋぀けた堎合は、私に個人的なメッセヌゞを曞き、怒りのコメントを急いで曞いおはいけたせん



All Articles