ç§ãçŽæããããã«ãç§ã¯ã²ãŒã éçºã®ããã€ãã®åŽé¢ã«é¢ãã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() {
ãµãŒãã§ã¹ã®ãã©ãŒããã
-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) {
ã°ãé² 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);
ããŠã次ã®ã¹ãããã¯
ãã«ãŒã ïŒ
ããã§éšåçã«èª¬æã
ãŸãã ïŒãš
ã«ã©ãŒã°ã¬ãŒãã£ã³ã°ã§ãïŒ
ã«ã©ãŒã°ã¬ãŒãã£ã³ã°ã®äœ¿çšïŒ
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ç§ãã¡ã¯ãã¹ãŠäººéã§ãããééããç¯ããŸãããããã£ãŠãããã¹ãã«ééããèŠã€ããå Žåã¯ãç§ã«å人çãªã¡ãã»ãŒãžãæžããæãã®ã³ã¡ã³ããæ¥ãã§æžããŠã¯ãããŸããïŒ