次ã«ãDirectX11 APIã䜿çšããŠãC ++ããã°ã©ãã³ã°èšèªã§ã¹ã¯ãªãŒã³ã¹ããŒã¹ã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ã®æ¡æ£ç
§æèšç®æ¹æ³ãå®è£
ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
ããšãã°ãå¹³è¡å
æºã䜿çšããå Žåãç»é¢äžã®ãã¯ã»ã«ã®è²ãèšç®ããåŒãæ€èšããŠãã ããã
LitColor =ã¢ã³ããšã³ã+æ¡æ£+é¡é¢åå°
ãŸãã¯ãããæ£åŒã«ã¯ãæ¡æ£ç
§æãåžåç
§æãé¡é¢ç
§æã®åèšã ãããã¯ãããã次ã®ããã«èšç®ãããŸãã
ïŒçŽ æã®è²ïŒ*ïŒãœãŒã¹ã®è²ïŒ*ïŒåŒ·åºŠä¿æ°ïŒ
ã€ã³ã¿ã©ã¯ãã£ãã°ã©ãã£ãã¯ã¹ã¢ããªã±ãŒã·ã§ã³ã§ã¯é·ãéãç°å¢åŒ·åºŠä¿æ°ã¯äžå®ã§ããããä»ã§ã¯ãªã¢ã«ã¿ã€ã ã§èšç®ã§ããŸãã ãã®ãããªæ¹æ³ã®1ã€-ã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ããŸãã¯ããããã®æé©å-ã¹ã¯ãªãŒã³ã¹ããŒã¹ã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ã«ã€ããŠã話ããããšæããŸãã æåã«ã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ã¡ãœããã«ã€ããŠèª¬æããŸãããã ãã®æ¬è³ªã¯æ¬¡ã®ãšããã§ã-ã·ãŒã³ã®åé ç¹ããã·ãŒã³ã®æ®ãã®éšåã®ãå¯èŠæ§ãã®åºŠåãã決å®ããç¹å®ã®èŠå ã圢æããŸãã
å³1-éšå±ãš2ã€ã®ãã€ã³ããå«ãå³é¢ãåãã€ã³ãã®ãå¯èŠæ§ãã¯çãšããŠæãããŠããŸããããã£ãŠãã©ã³ãã ãªæ¹åã®åé ç¹ã«ã€ããŠãå
ç·ãé¢ããã·ãŒã³ã®ãžãªã¡ããªãšã®äº€å·®ç¹ãèŠã€ããŸãã 次ã«ãçµæã®ã©ã€ã³ã®é·ããèšç®ãïŒäº€å·®ãèŠã€ãããªãã£ãå Žåãæå®ãããã·ãŒã³ã§ããŒã ã«ç¹å®ã®æ倧é·ããããšä»®å®ããŸãïŒãããããããå€ãšæ¯èŒããŸãã é·ãããããå€ãè¶
ããå ŽåãããŒã ã¯ãå¯èŠæ§ãã®ãã¹ãã«åæ ŒããŸããåæ Œãããã¹ãã®æ°ãçºå°ãããå
ç·ã®æ°ã§å²ã£ããã®ããå¯èŠæ§ãã®èŠå ã«ãªããŸãã
æããã«ãã¢ã«ãŽãªãºã ã®èšç®ã®è€éæ§ãé«ãããããªã¢ã«ã¿ã€ã ãŸãã¯ãªããžã§ã¯ãã®ãã€ããã¯ã¹ãé«ãã·ãŒã³ã«ã¯é©çšã§ããŸããã ãŸãããã®æ¹æ³ã®æå¹æ§ã¯ãã·ãŒã³ã®å€è§åœ¢ã®è€éãã«å€§ããäŸåããŸãã äºåã«ãå¯èŠæ§ããèšç®ããé ç¹ããŒã¿ã®äžéšãšããŠããŸãã¯ãã¯ã¹ãã£ã«ä¿åã§ããå Žåã¯ããã®ã¢ãããŒããé©çšããã®ã劥åœã§ãã
幞ããªããšã«ãCryTeckã®æ
åœè
ïŒå°ãªããšãç§ã圌ããæåã ãšèããïŒã¯ããªã¢ã«ã¿ã€ã ã§ä¿æ°ãèšç®ããæ¹æ³ãæãã€ããŸããã ããã¯ãã¹ã¯ãªãŒã³ã¹ããŒã¹ã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ãšåŒã°ããŸãã
ç§ã®å®è£
ã®ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
- 1. NDCïŒæ£èŠåãããããã€ã¹åº§æšïŒãŸãã¯ãã¯ã»ã«ã®ãã¯ã¹ãã£åº§æšãååŸãã深床ããŒã¿ã䜿çšããŠã«ã¡ã©ç©ºéã®ãã€ã³ãã«å€æããŸãã
- 2.ãã®ãã€ã³ãããã©ã³ãã ãªæ¹åã«ãNæ¬ã®å
ç·ãéå§ããŸãã
- 3. Nåã®å
ç·ã®ããããã«ã€ããŠïŒ
- 3-aã ã¬ã€ïŒãã¯ãã«ïŒã«ç¹å®ã®æ°ïŒã¹ã«ã©ãŒïŒãä¹ç®ïŒã¹ã±ãŒãªã³ã°ïŒããã¢ã€ãã 1ã®ãã€ã³ãã«è¿œå ããŸãã
- 3-bã çµæã®ãã€ã³ããNDC空éã«å€æãã次ã«ãã¯ã¹ãã£åº§æšã«å€æããŸãã
- 3-cã ãã¯ã¹ãã£ããããã®ãã€ã³ãã®æ·±åºŠå€ãååŸããŸãã
- 3çªç®ã ååŸããå€ãé
ç®3-aã§ååŸãããã€ã³ãã®æ·±ããããå°ããå ŽåãããªãŒããŒã©ãããããããŸãïŒå³2ãåç
§ïŒã ãããã®å€ãåã座æšç³»ã«å±ããŠããããšãèæ
®ã«å
¥ããå¿
èŠããããŸãã
- 3-fã ãã¢ã€ãã 3aããã®ãã€ã³ããã¢ã€ãã 1ããã®ãã€ã³ãããé ãã»ã©ããã®ãã€ã³ãããã®ãªãŒããŒã©ããã®å¯èœæ§ã¯äœããªããŸãããšããäŸåé¢ä¿ã«åºã¥ããŠãããªãŒããŒã©ãããä¿æ°ãååŸããŸãã ãã®äŸ¡å€ãèç©ããŸãã
- 4. ããªãŒããŒã©ããããšããå
±éã®ä¿æ°ãååŸããŸããããã¯ãç·ãªãŒããŒã©ããåèš/ Nå
ç·ã«çãããªããŸãã å
±éå åã¯[0,1]ã«å±ããå¯èŠæ§ã¯ãªãŒããŒã©ããã«åæ¯äŸããããã1-ãªãŒããŒã©ããã«çãããªããŸãã

å³2-æ³ç·ãã¯ãã«ã¯éã§è¡šç€ºãããã¢ã€ãã 3-aã§ååŸããããã¯ãã«ã¯èµ€ã§è¡šç€ºãããŸãã èç·è²ã®ãã¯ãã«ã¯Z軞ã®æ¹åã§ããããã€ã³ãAã®æ·±ãããã€ã³ãBã®æ·±ãããã倧ããå Žåãããã¯ãªãŒããŒã©ããã§ãã ããããããããããã«ãå³ã§ã¯æ£å°åœ±ã䜿çšããŠããŸãïŒãããã£ãŠãç·ABã¯çŽç·ã§ãïŒãã¯ã»ã«ã·ã§ãŒããŒã§ãã®ã¢ã«ãŽãªãºã ã䜿çšãããšãã¬ã³ããªã³ã°çµæããã¯ã¹ãã£ã«æžã蟌ããšãå¯èŠæ§ããŒã¿ãååŸã§ããŸãã ãã®ãã¯ã¹ãã£ããã®ããŒã¿ã¯ãã·ãŒã³ã®ç
§æã®èšç®ã«ããã«äœ¿çšã§ããŸãã
ããã§ã¯å§ããŸãããã
1.ã³ã³ããŒãžã§ã³
3次å
座æšããç»é¢åº§æšãååŸããã«ã¯ãäžé£ã®ãããªãã¯ã¹å€æãè¡ãå¿
èŠããããŸãã
äžè¬çã«ã¯ã次ã®3ã€ã®å€æããããŸãã
- 1.ããŒã«ã«åº§æšããã¯ãŒã«ã座æšãž-ãã¹ãŠã®ãªããžã§ã¯ããå
±éã®åº§æšç³»ã«è»¢éããŸã
- 2.ã¯ãŒã«ã座æšãããã¥ãŒåº§æšãŸã§-ãã«ã¡ã©ããåºæºã«ããŠãã¹ãŠã®ãªããžã§ã¯ããæ¹åä»ããŸã
- 3.ãã¥ãŒåº§æšããæ圱座æšãŸã§-ãªããžã§ã¯ãã®é ç¹ãå¹³é¢ã«æ圱ããŸãã éèŠæ圱æ³ã䜿çšããŸããããã¯ãããããå次é€æ³-ã³ã³ããŒãã³ãxã®åå²ãšãæ·±ãã«ããé ç¹-ã³ã³ããŒãã³ãzãæå³ããŸãã
ãã©ã°ã©ã1ãš2ã¯éèŠã§ã¯ãªãããããã©ã°ã©ã3ã«é²ã¿ãŸãã å°åœ±è¡åãèŠãŠã¿ãŸãããïŒ
ãã®è¡åãä¹ç®ããåŸãã«ã¡ã©ç©ºéããã®åº§æšã¯æ圱空éã«å
¥ããŸã
åçš®ã®åå²ãç¶ããŸãããã®çµæãNDCã¹ããŒã¹ã«ç§»åããŸã
次ã«ãéå€æãå®è£
ããæ¹æ³ãèŠãŠã¿ãŸãããã æããã«ãæåã«ã·ã§ãŒããŒã®ãã¯ã»ã«åº§æšãå¿
èŠã§ãã ãã¯ã¹ãã£åº§æšãïŒ0,0ïŒããïŒ1,1ïŒã®NDC空éã®ç»é¢é åå
šäœãã«ããŒããæ£æ¹åœ¢ã䜿çšãããšæã䟿å©ã§ãã é ç¹ããŒã¿ã¯æ¬¡ã®ãšããã§ãã
struct ScreenQuadVertex { D3DXVECTOR3 pos = {0.0f, 0.0f, 0.0f}; D3DXVECTOR2 tc = {0.0f, 0.0f}; ScreenQuadVertex(){} ScreenQuadVertex(const D3DXVECTOR3 &Pos, const D3DXVECTOR2 &Tc) : pos(Pos), tc(Tc){} }; std::vector<ScreenQuadVertex> vertices = { {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}}, {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}}, {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}}, {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}}, };
ãŸããD3D11_FILTER_MIN_MAG_MIP_POINTãªã©ããã¯ã¹ãã£ããŒã¿ã®ãã€ã³ãè£éãèšå®ããå¿
èŠããããŸãã ãã®æ£æ¹åœ¢ãæç»ããããšã§ã次ã®æ¹æ³ã§é ç¹ããŒã¿ããã¯ã»ã«ã·ã§ãŒããŒã«ã転éãã§ããŸãã
VOut output; output.posN = float4(input.posN, 1.0f); output.tex = input.tex; output.eyeRayN = float4(output.posN.xy, 1.0f, 1.0f);
ãŸãã¯ããã¯ã»ã«ã·ã§ãŒããŒã§çŽæ¥ãè£éããããã¯ã¹ãã£åº§æšã次ã®ããã«NDC空éã«å€æããŸãïŒãã®å€æã®è©³çŽ°ã«ã€ããŠã¯ã第3ç« ãåç
§ããŠãã ããïŒã
float4 posN; posN.x = (Input.tex.x * 2.0f) - 1.0f; posN.y = (Input.tex.y * -2.0f) + 1.0f;
NDC空éã«ãã¯ã»ã«ã®åº§æšããããŸã-ãã¥ãŒããŒãã«ç§»åããå¿
èŠããããŸãã è¡åã®ããããã£ã«åºã¥ããŠïŒ
ãã®ç®çã®ããã«ã¯ãéæ圱è¡åãå¿
èŠã§ãã 次ã®ããã«ãªããŸãã
ãã ããNDC空éã®2次å
ã®ãã€ã³ããåçŽã«ä¹ç®ããŠåäžã«åå²ããã ãã§ã¯äžååã§ããå€æãããã€ã³ãã®æ·±ãã«é¢ããããŒã¿ãå¿
èŠã§ãã ãã¥ãŒç©ºéã§æ·±åºŠã䜿çšããã-代æ°å€æãããã€ãè¡ãããããå¯èœãã©ããã確èªããŸãããã ãŸããçš®ããNDC空éãžã®ç¹ã®é·ç§»ãè¡šçŸããŸãã
次ã«ãéå°åœ±è¡åãä¹ç®ããŸãã
次ã«ãXãšYãåçŽåããWã®æ¬åŒ§ãå±éããŸãã
次ã«ãWã®åçŽåãç¶ããŸãã
æåŸã®ä»äžã-1 / nãã«ããããŸãã
éæ圱è¡åãæããåŸãçµæã«ãã¥ãŒç©ºéã®æ·±ããæããå¿
èŠãããããšãããããŸãã ãŸããé ç¹ã·ã§ãŒããŒã®NDCã¹ããŒã¹ã«ããŒã¿ãæºåããŸãã
output.eyeRayN = float4(output.posN.xy, 1.0f, 1.0f);
次ã«ããã¯ã»ã«ã·ã§ãŒããŒã§äž»ãªäœæ¥ãè¡ããŸãã
float4 normalDepthData = normalDepthTex.Sample(normalDepthSampler, input.tex); float3 viewRay = mul(input.eyeRayN, invProj).xyz; viewRay *= normalDepthData.w;
ãã¥ãŒç©ºéã«åº§æšããããŸãã ã©ãã
2.ã¬ã€ãã¬ãŒã·ã³ã°
2.1ãªãã»ããããŒã¿ãããã£ãŠãåŠçããããã¯ã»ã«ã®åº§æšã¯ãã¥ãŒã¹ããŒã¹ã«ãããŸãã 次ã«ããããã®åº§æšãæã€ãã€ã³ããããã©ã³ãã ãªæ¹åã«Nåã®å
ç·ãé
眮ããå¿
èŠããããŸãã æ®å¿µãªãããHLSL APIã«ã¯ãå€éšããŒã¿ã«é¢ä¿ãªããã·ã§ãŒããŒããã»ã¹äžã«ã©ã³ãã ãŸãã¯æ¬äŒŒã©ã³ãã ãªå€ãååŸã§ããããŒã«ããããŸããïŒãŸãããŸãã¯ãã®ãããªãã¯ãããžãŒã®ååšã«ã€ããŠã¯ç¥ããŸããïŒããããã£ãŠãäºåã«ãã®ãããªããŒã¿ãæºåããŸãã ã·ã§ãŒããŒã§ããããååŸããããã«ããã¯ã¹ãã£ã䜿çšããæãç°¡åãªæ¹æ³ã æããã«ããã®ãéã¿ããšããŒã¿å€ã®å¶éã¯ãã¯ã»ã«åœ¢åŒã«äŸåããŸãã ç§ãã¡ã®ç®çã«ã¯ãDXGI_FORMAT_R8G8B8A8_UNORMãšãã圢åŒãéåžžã«é©ããŠããŸãã ããã§ã¯ããµã€ãºãææ¡ããŸãããã ããããæãç°¡åã§ãæãèŠèŠçã§ãããšåæã«æé©ã§ã¯ãªãæ¹æ³ã¯ãç»é¢è§£å床ã«çããé·ããšå¹
ã®ãã¯ã¹ãã£ãäœæããããšã§ãã ãã®å Žåãæ£æ¹åœ¢ã®ãã¯ã¹ãã£åº§æšã®å€ã«åŸã£ãŠããŒã¿ãéžæããŸããããã¯ãïŒ0,0ïŒããïŒ1,1ïŒã®ç¯å²ã«ããããšãæãåºããŸãã ãããããããã®å¶éãè¶
ãããšã©ããªããŸããïŒ æ¬¡ã«ãD3D11_TEXTURE_ADDRESS_MODEåæã§æå®ãããã«ãŒã«ãäœçšããŸãã ãã®å ŽåãD3D11_TEXTURE_ADDRESS_MIRRORã®å€ã«é¢å¿ããããŸãã ãã®ã¢ãã¬ãã·ã³ã°ã«ãŒã«ã®çµæãå³3ã«ç€ºããŸãã

å³3ã¯ãD3D11_TEXTURE_ADDRESS_MIRRORã䜿çšããäŸã§ãããã®ã¢ãããŒãã䜿çšããå Žåãç®çã®ããã«å·®ç°ã¯èš±å®¹ãããŸãïŒå³4ãåç
§ïŒã
å³4-256x256ã®ãã¯ã¹ãã£ãããã³ã°ãš0ã1ã®åº§æšã®ããªããã£ããããã³0ã64ã®åº§æšãšD3D11_TEXTURE_ADDRESS_MIRRORã®ã¢ãã¬ã¹æå®ã®ãã¯ã¹ãã£ãããã³ã°4x4ã®ããªããã£ãæåŸã«ããã¯ã¹ãã£ã«ããŒã¿ãå
¥åããŸãããã ã·ã§ãŒããŒã§ã¯ããã¯ã»ã«ã³ã³ããŒãã³ãRãGãBããã©ã³ãã ãªæ¹åãã¯ãã«ã圢æãããããã¢ã«ãã¡ãã£ãã«ã¯äœ¿çšããŸããïŒããã¯ãåäžç©ºéã®ãã¯ãã«ã§ã¯ãŒãã§ããWã®ã³ã³ããŒãã³ããšèŠãªãããšãã§ããŸãïŒã ãã®çµæãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
for(int y = 0; y < texHeight; y++){ for(int x = 0; x < texWidth; x++){ char* channels = reinterpret_cast<char*>(&data[y * texWidth + x]); channels[0] = rand() % 255;
ãŸãããã¯ã¹ãã£ã®ãµã€ãºãå°ããã»ã©ãç»åããããããã«ãªããšããäºå®ã«ã泚æãæããããšæããŸãïŒå³5ãåç
§ïŒã
å³5-ãµã€ãºã128x128ãš4x4ã®ãã£ã¹ãã¬ã€ã¹ã¡ã³ãã®ãã¯ã¹ãã£ã®éãã®ãã¢ããŠããã¯ã¹ãã£ã®æºåãã§ããŸãããæ®ã£ãŠããã®ã¯ããã®ããŒã¿ãã·ã§ãŒããŒã§ååŸããããšã ãã§ãã ãã ãã0ã1ã®ãã¯ã¹ãã£åº§æšãããã0ãNã®åº§æšã䜿çšããå¿
èŠãããããšãæãåºããŠãã ãããN> 0ã§ãããã®åé¡ã¯ãã·ã§ãŒããŒæºåã®æ®µéã§éåžžã«ç°¡åã«è§£æ±ºãããŸãããã¯ã¹ãã£ãç»é¢å
šäœãå ããããã«ãã¯ã¹ãã£ã®å¹
ãã©ã®ãããæããå¿
èŠããããã ç»é¢è§£å床ã1024x468ã§ããã¯ã¹ãã£ãµã€ãºã2x4ã§ãããšä»®å®ãããšã次ã®ããã«ãªããŸãïŒ
次ã«ãä¿æ°ãè¡šçŸããŸãã
ãã®çµæã次ã®ã³ãŒããååŸããŸãã
float2 rndTexFactor(fWidth, fHeight)
ãããããããªãã®å Žåããã£ã¹ãã¬ã€ã¹ã¡ã³ããã¯ã¹ãã£ããã®éžæã®ãããã®åº§æšãé ç¹ããŒã¿ãšããŠä¿åããããã«ãã£ãŠæ¢è£œã®è£éå€ãååŸããæ¹ãåççã§ãã
ããã«ããã©ãŒãããDXGI_FORMAT_R8G8B8A8_UNORMãéžæããããããªãã»ããã¯0ã1ã®ã¹ããŒã¹ã«ãããŸãïŒã¹ããŒã¹ïŒ-1ã1ïŒã«ç§»åããŸãïŒå€æã®è©³çŽ°ã«ã€ããŠã¯ã第3ç« ãåç
§ïŒã
rndData = normalize(2.0f * rndData - 1.0f);
å€äœãã¯ãã«ãã§ããŸããïŒ
2.2å€äœãã¯ãã«ã®ã«ãŒãã«1ã€ã®ãã¯ãã«ã¯ç¢ºãã«åªããŠããŸãããNåã®ãã¯ãã«ãèµ·åããå¿
èŠããããŸãã 0ããNã®ç¯å²ã§ãã¯ã¹ãã£åº§æšã®ã·ããã®ç¹å®ã®èŠå ãååŸãã次ã®ãããªããšãè¡ãããšãã§ããŸãã
for(int i = 0; i < N; i++){ float3 rndData = tex.Sample(randomOffsetsSampler, input.tex * rndTexFactor + Offset * i).rgb; rndData = normalize(2.0f * rndData - 1.0f); }
ãã®ãªãã·ã§ã³ã¯ãªãœãŒã¹ãéäžçã«äœ¿çšããŸãã ãã¯ã¹ãã£ãããµã³ãã«ã1ã€ã ã䜿çšããŠã蚱容ã§ããçµæãåŸãããšããŸãã ç§ãã¡ã®ç®æšã¯ãåŠçããããã¯ã»ã«å
ãšé£æ¥ãããã¯ã»ã«ã®äž¡æ¹ã§ãæ¯èŒçäžåäžãªãã¯ãã«ååžãå®çŸããããšã§ãã äºåã«æºåãããNåã®ã©ã³ãã ãã¯ãã«ã䜿çšããŠã¿ãŸãããããããã®åãã¯ãã«ã¯ãç¹å®ã®æ°åŠçæäœã§å€äœãã¯ãã«ã«é©çšã§ããŸãã ããããå€äœãã¯ãã«ã®ã³ã¢ããšåŒã³ãŸãã 確ãã«ãããã¯ç§ã説æãããããç°¡åã§ãïŒ
ã³ã¢ãæºåããŸãã
std::vector<D3DXVECTOR4> kernel(KernelSize); int i = 0; for(D3DXVECTOR4 &k : kernel){ kx = Math::RandSNorm(); ky = Math::RandSNorm(); kz = Math::RandSNorm(); kw = 0.0f; D3DXVec4Normalize(&k, &k); FLOAT factor = (float)i / KernelSize; k *= Math::Lerp(0.1f, 0.9f, factor); i++; }
åã³ã³ããŒãã³ãã®å€ã¯-1ã1ã§çæãããŸãããã¯ãã«ã¯åäœé·ã§ã¯ãªãããšã«æ³šæããŠãã ããã ããã¯ãæçµç»åã«å€§ããªåœ±é¿ãäžããããéèŠã§ãã å³ å³6ã¯ãæ圱ããããšãã®éåäœé·ãã¯ãã«ãããéäžãããã€ã³ãã®ã»ããã圢æããããšã瀺ããŠããŸãã
å³6-éåäœé·ãã®ãã¯ãã«ã®æ圱ã¯ãããéäžãããã€ã³ãã®ã»ããã圢æããŸãã ããæ確ã«ããããã«ãæ£å°åœ±ã䜿çšãããŸããããŠãã«ãŒãã«ã®æºåãã§ããŸãã-ã·ã§ãŒããŒã§äœ¿çšããããã«æ®ã£ãŠããŸãã æ°åŠçãªæäœãšããŠãããã¯ãã«ã®åå°ãã䜿çšããããšã«ããŸããã ãã®ããŒã«ã¯éåžžã«äŸ¿å©ã§ãåºã䜿çšãããŠããŸããããšãã°ãé¡é¢ç
§æãèšç®ãããšãã«å
æºã«åå°ãã¯ãã«ãååŸããå¿
èŠãããå ŽåããŸãã¯ããŒã«ãå£ããè·³ãè¿ãæ¹æ³ã調ã¹ãå¿
èŠãããå Žåã§ãã åå°ãã¯ãã«ã®èšç®åŒã¯æ¬¡ã®ããã«ãªããŸãã
ããã§ãvã¯åå°ãããã¯ãã«ãnã¯ãã¯ãã«ã®åå°ã«çžå¯Ÿçãªè¡šé¢ã®æ³ç·ã§ãïŒå³7ãåç
§ïŒ
å³7-åå°ãã¯ãã«åŒã®èŠèŠåãã¯ãã«ã§æåŸã«è¡ãå¿
èŠãããã®ã¯ãæ³ç·ã«ãã£ãŠæ¹åä»ããããåçå
ã«ããããšã確èªããããšã§ãã ãããè¡ãã«ã¯ãæ³ç·ãšã®ã¹ã«ã©ãŒç©ããŒãããå°ããå Žåã«æ¹åãå€æŽããŸãã ãã®çµæã次ã®ã³ãŒããåŸãããŸããã
//float3 kernel[N] - //normalV - float3 rndData = tex.Sample(randomOffsetsSampler, input.tex * rndTexFactor + Offset * i).rgb; rndData = normalize(2.0f * rndData - 1.0f); for(int i = 0; i < N; i++){ float3 samplingRayL = reflect(kernel[N], rndData); samplingRayL *= sign(dot(samplingRayL, normalV)); }
ReflectïŒïŒæäœã®çµæã¯æ£èŠåãããªãããšã«æ³šæããŠãã ããã
3.ããŒã ããã¹ã¯ãªãŒã³äžã®ãã€ã³ããŸã§
æ¯ãè¿ã£ãŠäœãèµ·ãã£ãã®ãèŠãŠã¿ãŸãããã ã ããïŒ
- 深床ããŒã¿ã䜿çšããŠããã©ãŒã ã®ç©ºéå
ã®ãã¯ã»ã«ã®åº§æšãååŸããŸãã
- äºãã«ã©ã³ãã ã«ååžããNæ¬ã®å
ç·ãåŸãŸããã
ããã§ãæçµçã«ç§ãã¡ã®åšãã«ãããã®ãèŠã€ããããã«å¿
èŠãªãã®ããã¹ãŠæããŸããã ç¶ããŸãããã ç¹å®ã®occlusionRadiusã¹ã«ã©ãŒã§ãã¯ãã«ãä¹ç®ãããã¥ãŒç©ºéã®ãã¯ã»ã«ã®ãã€ã³ãã«è¿œå ããŸãã ã¢ãŒãã£ã¹ãã«occlusionRadiuså€ã調æŽãããã®ãè³¢æã§ãã
æ£åŒã«èšãã°ããã¥ãŒã¹ããŒã¹ã§ãsamplingPosVãã€ã³ããååŸããŸãããããã¯ãsamplingRayLæ¹åã®ãã¯ã»ã«ããããçšåºŠã®è·é¢ã«ãããŸãã 次ã«ãæ·±ããèæ
®ããããã«ãåäžãªåå²ããè¡ãããšãå¿ããã«ãçµæã®ãã€ã³ããã¹ã¯ãªãŒã³ã«æ圱ããŸãã
float4 samplingPosH = mul(float4(samplingPosV, 1.0f), proj)
ç§ãã¡ã¯NDCã¹ããŒã¹ã«ããŸãã 次ã«ããã¯ã¹ãã£åº§æšç©ºéã«ç§»åããå¿
èŠããããŸãã ãããè¡ãã«ã¯ããã€ã³ãã-1ãã1ã®å€ã®ç¯å²ãã0ãã1ã®é åã«å€æããŸããY軞ã¯å察æ¹åã«åããããŠããããšã«æ³šæããŠãã ããã ïŒå³8ãåç
§ïŒ
å³8-NDCããã³ãã¯ã¹ãã£åº§æšç©ºéã®åº§æšè»žã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³äžè¬ã«ããã®çš®ã®1次å
å€æã¯æ¬¡ã®ããã«å®è¡ã§ããŸã-æåã«ç¯å²ã®æå°å€ãæžç®ãã次ã«ç¯å²ã®å¹
ïŒæ倧å€ããæå°å€ïŒã§é€ç®ããçµæã®ä¿æ°ã«æ°ããã¹ããŒã¹ã®ç¯å²ã®å¹
ãæããŠãçµæã«å ç®ããŸãæ°ããã¹ããŒã¹ã®æå°å€ã èšãããããããã¯ç°¡åã§ãã ãã®ã±ãŒã¹ã§ã¯ãNxãNDC空éã®X座æšã§ãããTxããã¯ã¹ãã£åº§æšç©ºéã®X座æšã§ãããšä»®å®ããŸãã 次ã®ããšãå€æããŸããã

NDC空éã®Y座æšã¯å察æ¹åã«åããããŠãããããå°ãç°ãªãåäœãããå¿
èŠããããŸãã ããã«èš±å®¹ç¯å²ãè¶
ããŠããŸããããå察ã®ç¬Šå·ãæã€å€ãåãããšã¯ã§ããŸããã ããŒã...ç»é¢ã®å³äžé
ã«ããç¹ãæ³åããŠãã ãã-NDC空éã§ã¯åº§æšã¯ïŒ1ã-1ïŒã«ãªãããã¯ã¹ãã£åº§æšç©ºéã§ã¯-ïŒ1ã1ïŒã«ãªããŸãã ããã§ãå·Šäžé
ã®ãã€ã³ããæ³åããŠãã ãã-ãã®NDC空éã§ã¯åº§æšã¯ïŒ-1ã1ïŒã«ãªãããã¯ã¹ãã£ã®åº§æšç©ºéã§ã¯ïŒ0ã0ïŒã«ãªããŸãã 次ã®ãã¿ãŒã³ãçŸããŸããå¢çé åã§ã¯ãYã¯1ã€ã®åº§æšç³»ã§æ倧å€ãå¥ã®åº§æšç³»ã§æå°å€ãããã³ãã®éãæ³å®ããŸãã ãããã£ãŠãä¿æ°ãååŸãããšãããã1ããæžç®ããŸãã
ãã®åé¡ã¯å¥ã®æ¹æ³ã§è§£æ±ºã§ããŸãã ãœãªã¥ãŒã·ã§ã³ã¯ä»é²1ã«ç€ºãããŠããŸãã
ãã®çµæãã·ã§ãŒããŒã§æ¬¡ã®ã³ãŒããååŸããŸãã
float2 samplingTc; samplingTc.x = 0.5f * samplingRayN.x + 0.5f; samplingTc.y = -0.5f * samplingRayN.y + 0.5f;
次ã®ããã«ã1ã€ã®ãããªãã¯ã¹ã§å€æããã¯ã¹ãã£åº§æšãšæ圱ãšçµã¿åãããããšãã§ããããšãè¿œå ããŸãïŒPã¯æ圱ãããªãã¯ã¹ã§ãïŒã
4.深床ããŒã¿ã®æäœ
ã»ãã®å°ãã ãïŒ æ¥ãã§ïŒ åã®æ®µèœã§ååŸãã座æšã«åºã¥ããŠãããŒã¿ã䜿çšããŠãã¯ã¹ãã£ããéžæãè¡ããŸãã
float sampledDepth = normalDepthTex.Sample(normalDepthSampler, samplingTc).w;
深床ããŒã¿ã¯ã³ã³ããŒãã³ãwã«ä¿åãããŸãã ãããŠ...ãããŠãæã
ã¯åœŒããšäœãããŸããïŒïŒ èãçŽããŠã¿ãŸãããã ãã¥ãŒã®ã¹ããŒã¹ã«ããŸã-Z軞ã¯ã«ã¡ã©ã®æ¹åãšäžèŽããŠããŸãã ãããã£ãŠãåŸããã深床ãå°ããã»ã©ããªããžã§ã¯ãã¯ç§ãã¡ã«è¿ããªããŸãã ãã¥ãŒç©ºéå
ã®ãã¯ã»ã«ããããè·é¢ã«ããç¹ãæ圱ããããšãæãåºãããŠãã ããã ãã¯ã¹ãã£ã¯ããã¥ãŒã¹ããŒã¹ã®æ·±ããä¿åããŸãã ãã¯ã¹ãã£ã®æ·±ããšãã€ã³ãã®æ·±ããæ¯èŒãããšãäœãããããŸããïŒ ãã¯ã¹ãã£ã®æ·±åºŠå€ããã€ã³ãã®æ·±åºŠãããå°ããå Žåãäœããã«ã¡ã©ã«è¿ããªãããã€ã³ãã衚瀺ãããªããªããŸãããããã£ãŠããã®ãäœãããããã«ã¡ã©ã«è¿ãå Žåããã€ã³ãã衚瀺ãããŸãã ãšããã§ãShadowMappingã¯ã»ãŒåãããã«æ©èœããŸãã è»ã§è€éãªæäœãè¡ãå¿
èŠããããäžããäœãèµ·ãã£ãŠãããããããªãå Žåã«ãåãã調æŽããããã«å人ã«äŸé Œãããããªãã®ã§ãã ãããã圌ã¯é
ã£ãŠããŠãããªããæåŸ
ãããã®ãšå察ã®ããŒã¿ãããªãã«è©±ãã®ã¯éåžžã«é¢çœãã ãããšæã£ã...ããããããã¯ç§ãã¡ã®å Žåã§ã¯ãããŸãã
ãããã£ãŠãã«ã¡ã©ããèŠããNã»ããã®ãã€ã³ããå°ãªãã»ã©ããã¯ã»ã«ãåãåãæ¡æ£å
ã¯å°ãªããªããŸãã ç¶æ³ãå°ãç°ãªãæ¹æ³ã§èããããšãã§ããŸã-ãã¯ã»ã«ãããã®æ³ç·ã®æ¹åãèŠããšæ³åããŠã¿ãŸãããïŒå
ç·ã¯æ³ç·ã«ãã£ãŠæ¹åä»ããããåçå
ã«ååžããŠããããïŒã ã«ã¡ã©ã«èŠããNã»ããã®ãã€ã³ããå°ãªãã»ã©ããã¯ã»ã«ããèŠãããšãã§ããã·ãŒã³ãªããžã§ã¯ãã®æ°ãå°ãªããªããŸãïŒã·ãŒã³ãªããžã§ã¯ãã®ããžãªã¡ããªããå¢ããŠãã¥ãŒããããã¯ãããããïŒããããã£ãŠãã·ãŒã³ã®æ£ä¹±å
ãžã®ã¢ã¯ã»ã¹ãå°ãªããªããŸãïŒããã£ïŒããªãã®ã¹ããŒã§ãéã®ä¹å¥³ãïŒãã«ãã¥ãŠïŒç§ã¯ããªãã«ææŠ!!ïŒ
ãŸããã·ãŒã³ã®ç¹å®ã®ãªããžã§ã¯ãïŒååŸãã深床ïŒãããã¯ã»ã«ãã€ã³ããžã®æ£ä¹±å
ãžã®ã¢ã¯ã»ã¹ã«åœ±é¿ãäžããªãããã«ã§ããããšãèæ
®ããå¿
èŠããããŸãïŒå³9ãåç
§ïŒã
å³9-ãã€ã³ãqã¯ã«ã¡ã©ã«è¿ãã§ããããã¯ã»ã«Pã®ãã€ã³ãããé¢ããããŠããããããã®ç
§æã«åœ±é¿ãäžããããšã¯ã§ããŸããã1ãè¿œå ããã ãã§ãªããè·é¢ã«å¿ããŠç¹å®ã®ä¿æ°ãè¿œå ããããšããå§ãããŸãã
float distanceFactor = (1.0f - saturate(abs(viewRay.z - sampledDepth) / occlusionRadius)) * harshness
è·é¢ä¿æ°ã¯ãæ圱ãããã€ã³ãã§ã¯ãªãããã¯ã»ã«ãã€ã³ãã®æ·±ãã«åºã¥ããŠåœ¢æãããŸããç®ã®åã«äœãããããã©ãããç解ããããã«äœ¿çšããŸãããããã¯ç§ãã¡ããã§ãã ãŸããç²ããã©ã¡ãŒã¿ãŒã䜿çšããŠåŒ·åºŠã調æŽããæ©èœãè¿œå ããŸããã
äžè¬ã«ãããã¯ã¢ã«ãŽãªãºã ã®äž»èŠéšåã§ãããããã°ããã¹ãŠã®æ žå¿ã§ãã å€äœãã¯ãã«ãæäœãããµã€ã¯ã«å
šäœãèŠãŠã¿ãŸãããã
//viewRay - //normalV - //float3 kernel[N] - //offset - , float totalOcclusion = 0.0f; [unroll] for(int i = 0; i < 16; i++){ float3 samplingRayL = reflect(kernel[i].xyz, offset); samplingRayL *= sign(dot(samplingRayL, normalV)); float3 samplingPosV = viewRay + (samplingRayL * occlusionRadius); float4 samplingPosH = mul(float4(samplingPosV, 1.0f), proj); samplingPosH.xy /= samplingPosH.w; float2 samplingTc; samplingTc.x = 0.5f * samplingPosH.x + 0.5f; samplingTc.y = -0.5f * samplingPosH.y + 0.5f; float sampledDepth = normalDepthTex.Sample(normalDepthSampler, samplingTc).w; if(sampledDepth < samplingPosV.z){ float distanceFactor = (1.0f - saturate(abs(viewRay.z - sampledDepth) / occlusionRadius)); totalOcclusion += distanceFactor * harshness; } }
çµæãèŠãŠã¿ãŸãããïŒ
ãããïŒ äžäœäœã ïŒ ãããŠãããã«FarCryã¯ãããŸããïŒïŒã ãèœã¡çããŠïŒã-ããªãã«çããŸãã ãããããšããŒã«ã¯å©ããæ¥ãã§ããŸãïŒããããããã¯ãã®èšäºããã§ã¯ãããŸãã-ããã©ãŒã¯å©ããæ¥ãã§ããŸãïŒã
5.ãŒããã䜿çšãã
5.1æãç°¡åãªãªãã·ã§ã³ãŒããå¹æããŸãã¯ãŒããã¯ãã°ã©ãã£ãã¯ã¹ã®å€ãã®é åã§äœ¿çšãããéåžžã«äŸ¿å©ãªããŒã«ã§ãã ç§ã¯ãããé»æ°ããŒããšæ¯èŒããŸãïŒéïŒããã¯éèŠã§ãïŒ-ããã¯äœããä¿®æ£ãŸãã¯æ¹åããããã«äœ¿çšã§ããŸããããã£ããããã®é«ãããã¿ã€ã«ã®äžã«èœã¡ãé»è©±ãä¿®æ£ããããšã¯ã»ãšãã©äžå¯èœã§ãïŒãæç±æãã©ãããããã¹ãŠãããŸãããã ãè€æ°åäŒã£ãïŒã
å¹æã®æ¬è³ªã¯ç°¡åã§ãïŒåãã¯ã»ã«ã«ã€ããŠããã®é£æ¥è²ã®ç®è¡å¹³åãååŸããŸã
ãããã£ãŠãP座æšãæã€ãã¯ã»ã«ããããšããŸã-Ré åïŒAreaHeightãã¯ã»ã«ããšã®AreaWidthïŒã®é£æ¥ããè²ã®ç®è¡å¹³åãèšç®ããŸãããã ãã®ãããªãã®ïŒç§ã¯æå³çã«é
åã®ç¯å²å€ããã§ãã¯ããŸãããããã«ã€ããŠã¯ä»¥äžïŒïŒ
D3DXCOLOR **imgData = ...; // D3DXCOLOR avgColor(0.0f, 0.0f, 0.0f, 0.0f); for(INT x = Px - AreaWidth / 2; x <= Px - AreaWidth / 2; x++) for(INT y = Py - AreaHeight / 2; y <= Py - AreaHeight / 2; y++) avgColor += imgData[x][y]; avgColor /= AreaWidth * AreaHeight;
5.2ã¬ãŠã¹ãã£ã«ã¿ãŒæ¬¡ã«ããããè¡ã£ãŠã¿ãŸããã-åé£æ¥ã®è²ã«ãAreaWidth x AreaHeightã®æ¬¡å
ãæã€ãããªãã¯ã¹ã®å€ãä¹ç®ããŸãã ãŸãããã¹ãŠã®è¡åèŠçŽ ã®åèšã1ã«çãããªãããã«ããŸããããã«ãããç®è¡å¹³åå éã®ç¹æ®ãªã±ãŒã¹ã«ãªããããé åã®ãµã€ãºã§é€ç®ããå¿
èŠããªããªããŸãã ãã®ãããªãããªãã¯ã¹ã¯æ£åŒã«ã¯ãç³ã¿èŸŒã¿ãããªãã¯ã¹ããšåŒã°ãããã³ã¢ããšãåŒã°ãããã®èŠçŽ ã¯ãéã¿ããšåŒã°ããŸãã ãªããããå¿
èŠãªã®ã§ããïŒ ãããã£ãŠãããå€ãã®å¯èœæ§ããããŸã-éã¿ã®å€ãå¶åŸ¡ããããšã«ãããäŸãã°ãèåãç·©ãããªãŒããã®å¹æãéæã§ããŸãã ç³ã¿èŸŒã¿è¡åã«åºã¥ãããã£ã«ã¿ãŒãã¡ããªããããŸã-ã·ã£ãŒããã³ã°ãã£ã«ã¿ãŒãã¡ãã£ã¢ã³ãã£ã«ã¿ãŒã䟵é£ãã£ã«ã¿ãŒãããã³ãã«ãã¢ããã§ãã
æãäžè¬çãªãŒãããã£ã«ã¿ãŒã¯ãã¬ãŠã¹ãã£ã«ã¿ãŒã§ãã ãã®éèŠãªç¹æ§ã¯ç·åœ¢åé¢æ§ã§ããããã«ãããæåã«è¡ã®å
¥åç»åããŒããã次ã«åã®è¡ã®ç»åããŒããã1次å
ãã£ã«ã¿ãŒã®å€ã§1ãµã€ã¯ã«ãå®è¡ã§ããŸãã
xã¯-AreaWidth / 2ããAreaWidth / 2ãŸã§ã®æŽæ°ã§ããqã¯ãããããã¬ãŠã¹ååžã®æšæºåå·®ãã§ã
ãã£ã«ã¿ãŒãããªãã¯ã¹ã圢æããé¢æ°ãå®è£
ããŸããã
typedef std::vector<float> KernelStorage; KernelStorage GetGaussianKernel(INT Radius, FLOAT Deviation) { float a = (Deviation == -1) ? Radius * Radius : Deviation * Deviation; float f = 1.0f / (sqrtf(2.0f * D3DX_PI * a)); float g = 2.0f * a; KernelStorage outData(Radius * 2 + 1); for(INT x = -Radius; x <= Radius; x++) outData[x + Radius] = f * expf(-(x * x) / a); float summ = std::accumulate(outData.begin(), outData.end(), 0.0f); for(float &w : outData) w /= summ; return outData; }
ååŸ5ã䜿çšããåå·®ã¯5ã®2ä¹ã§ãã
5.3ã·ã§ãŒããŒãšããã«é¢é£ãããã¹ãŠ2ã€ã®ãã¯ã¹ãã£ã䜿çšããŸãã1ã€ã¯ãœãŒã¹ããŒã¿ã䜿çšãããã1ã€ã¯äžéçµæãä¿åããããã«äœ¿çšããŸãã ç»é¢è§£å床ãšãã¯ã»ã«åœ¢åŒDXGI_FORMAT_R32G32B32A32_FLOATã«å¯Ÿå¿ãããµã€ãºã§äž¡æ¹ã®ãã¯ã¹ãã£ãäœæããŸãã ãã¡ãããå質ãããŸãèœãšãããšãªãããã¯ã¹ãã£ã®ãµã€ãºãå°ããããããšã¯ã§ããŸããããã®å Žåãç§ã¯ããããªãããšã«ããŸããã 次ã®ã¹ããŒã ã«åŸã£ãŠãã¯ã¹ãã£ãæäœããŸãã
// { // } // { // }
åãšåæ§ã«ãNDC空éã®åè§åœ¢ãæäœããŸããããã¯ãç»é¢é åå
šäœãå ãããã¯ã¹ãã£åº§æšã¯0ã1ã§ããä»åºŠã¯ããã¯ã¹ãã£ã®å¢çãè¶ããåŠçæ¹æ³ãèããŸãã
ã·ã§ãŒããŒã³ãŒãã«çŽæ¥ãã§ãã¯ãå®è£
ãããšããªãœãŒã¹ã倧éã«æ¶è²»ããŸãã
å
ã»ã©èšã£ãããã«ããã®å ŽåãD3D11_TEXTURE_ADDRESS_MODEåæã§æå®ãããã«ãŒã«ãæå¹ã«ãªããŸããã«ãŒã«D3D11_TEXTURE_ADDRESS_CLAMPã¯ç§ãã¡ã«é©ããŠããŸãã次ã®ããšãèµ·ãããŸã-å座æšã¯ç¯å²[0ã1]ã«å¶éãããŸããã€ãŸãã座æšïŒ1.1ã0ïŒãéžæãããšã座æšïŒ1ã0ïŒã®ãã¯ã»ã«ããŒã¿ãååŸããã座æšïŒ-0.1ã0ïŒãéžæãããšãïŒ0ã0ïŒã®ããŒã¿ãååŸãããŸãã Yã«ã€ããŠãåæ§ã§ãïŒå³12ãåç
§ïŒãå³12ãã£ã«ã¿ãŒã®ãµã€ãºã«é¢é£ããD3D11_TEXTURE_ADDRESS_CLAMPã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³æåŸã«ç¥ãå¿
èŠãããã®ã¯ããã¯ã¹ãã£åº§æšç©ºéã§1ãã¯ã»ã«ã移åããããã«ã©ãã ãåé²ããå¿
èŠããããã§ãããã®åé¡ã¯ç°¡åã«è§£æ±ºãããŸã-ç»é¢ã®è§£å床ã1024 x 768ãã¯ã»ã«ã§ãããšããŸãããå·Šäžé
ãã-ïŒ1 / 1024ã1 / 768ïŒããã®åé¡ã®è§£ãæ¹çšåŒã®åœ¢ã§è¡šçŸããããšãã§ããŸãã ïŒSxãSyïŒãéå§äœçœ®ãšããïŒExãEyïŒçµäºäœçœ®ãšãããSããEã«ç§»åããã«ã¯ç»é¢ã®ã©ã®éšåã移åããå¿
èŠããããŸããïŒããšãã質åã«å¯Ÿããçãã次ã®ããã«ããŸããç»é¢ã®å·Šäžé
ãã1ãã¯ã»ã«ç§»åãããå Žåãæ¹çšåŒã¯æ¬¡ã®ããã«ãªããŸããFã®è¡šçŸãšååŸïŒããã§ãããããããã¯ã»ã«ã·ã§ãŒããŒã®ã³ãŒããååŸã§ããŸãã cbuffer Data : register(b0) { float4 weights[11]; float2 texFactors; float2 padding; }; cbuffer Data2 : register(b1) { int isVertical; float3 padding2; }; struct PIn { float4 posH : SV_POSITION; float2 tex : TEXCOORD0; }; Texture2D colorTex :register(t0); SamplerState colorSampler :register(s0); float4 ProcessPixel(PIn input) : SV_Target { float2 texOffset = (isVertical) ? float2(texFactors.x, 0.0f) : float2(0.0f, texFactors.y); int halfSize = 5; float4 avgColor = 0; for(int i = -halfSize; i <= halfSize; ++i){ float2 texCoord = input.tex + texOffset * i; avgColor += colorTex.Sample(colorSampler, texCoord) * weights[i + halfSize].x; } return avgColor; }
ããã§ã¯ç¹å¥ãªããšã¯äœãèµ·ãããªããããé ç¹ã·ã§ãŒããŒã¯ããã§ã¯åŒçšããŸããã§ãã-ããŒã¿ãããã«ã転éãããŸããç§ãã¡ãåŸããã®ãèŠãŠã¿ãŸãããïŒå³13ãšããžãèæ
®ããªããŒããã®ãã¢æªãã¯ãããŸããããä»åºŠã¯ãŒãããé¡ã®åé¡ã解決ããå¿
èŠããããŸããç§ãã¡ã®å Žåãããã¯äžèŠæããããããç°¡åã§ã-çµå±ã®ãšãããå¿
èŠãªããŒã¿ã¯ãã¹ãŠæã£ãŠããŸãïŒç»é¢ã¹ããŒã¹ã«ããå ŽåãéåžžããŒã¿ãšæ·±åºŠããŒã¿ã®æ¥æ¿ãªå€åã远跡ããã®ã«ååã§ããæ³ç·ã®ã¹ã«ã©ãŒç©ãŸãã¯é£æ¥ãåŠçããããã¯ã»ã«ã®æ·±ãã®å·®ã®çµ¶å¯Ÿå€ãç¹å®ã®å€ããã倧ãããå°ããå ŽåãåŠçããããã¯ã»ã«ã¯ãã§ãŒã¹ã©ã€ã³ã«å±ãããšä»®å®ããŸãããšããžãé»è²ã§åŒ·èª¿è¡šç€ºããå°ããªã·ã§ãŒããŒãäœæããŸãããæäœã®åçã¯ãŒããã®å Žåãšåãã§ããæåã«åçŽæ¹åã«ã次ã«æ°Žå¹³æ¹åã«æž¡ããŸããæ¹åã«å¿ããŠãå·Šå³ã®2ã€ã®é£äººããŸãã¯äžäžã®2ã€ã®é£äººãæ¯èŒããŸãã次ã®ãããªçµæã«ãªããŸããã bool CheckNeib(float2 Tc, float DepthV, float3 NormalV) { float4 normalDepth = normalDepthTex.Sample(normalDepthSampler, Tc); float neibDepthV = normalDepth.w; float3 neibNormalV = normalize(normalDepth.xyz); return dot(neibNormalV, NormalV) < 0.8f || abs(neibDepthV - DepthV) > 0.2f; } float4 ProcessPixel(PIn input) : SV_Target { float2 texOffset = (isVertical) ? float2(0.0f, texFactors.y) : float2(texFactors.x, 0.0f); float4 normalDepth = normalDepthTex.Sample(normalDepthSampler, input.tex); float depthV = normalDepth.w; float3 normalV = normalize(normalDepth.xyz); bool onEdge = CheckNeib(input.tex + texOffset, depthV, normalV) || CheckNeib(input.tex - texOffset, depthV, normalV); return onEdge ? float4(1.0f, 1.0f, 0.0f, 1.0f).rgba : colorTex.Sample(colorSampler, input.tex) ; }
é¡ã®éžæã瀺ãå³14.ãŒããã®éã«ãããã©ã®ããã«äœ¿çšããŸããïŒãšãŠãç°¡åã§ãïŒç§ãã¡ã¯ãè²ãèæ
®ããããã¯ã»ã«ããéåžžã«é ãã«ããããŸãã¯æ³ç·æ¹åã§èããç°ãªããããã®é£ã®è²ãèæ
®ããŸãããããã§ãçµæãåŠçæžã¿ã®éã¿ã®åèšã§å²ãå¿
èŠããããŸããã³ãŒãã¯æ¬¡ã®ãšããã§ãã float4 ProcessPixel(PIn input) : SV_Target { float2 texOffset = (isVertical) ? float2(0.0f, texFactors.y) : float2(texFactors.x, 0.0f); float4 normalDepth = normalDepthTex.SampleLevel(normalDepthSampler, input.tex, 0); float depthV = normalDepth.w; float3 normalV = normalize(normalDepth.xyz); int halfSize = 5; float totalWeight = 0.0f; float4 totalColor = 0.0f; [unroll] for(int i = -halfSize; i <= halfSize; ++i){ float2 texCoord = input.tex + texOffset * i; float4 normalDepth2 = normalDepthTex.SampleLevel(normalDepthSampler, texCoord, 0); float neibDepthV = normalDepth2.w; float3 neibNormalV = normalize(normalDepth2.xyz); if(dot(neibNormalV, normalV) < 0.8f || abs(neibDepthV - depthV) > 0.2f) continue; float weight = weights[halfSize + i].x; totalWeight += weight; totalColor += colorTex.Sample(colorSampler, texCoord) * weight; } return totalColor / totalWeight; }
次ã®ããã«ãªããŸããïŒ6.äºæããªãå€æŽ
ãã®èšäºã®äœæ¥ãçµãããšãå¥ã®ãã¹ãã®çµæããªãŒããŒã©ããã®çµæãã«ã¡ã©ã®æ¹åã«å¯ŸããŠäžå®å®ã§ããããšãããããŸããããããä¿®æ£ããã«ã¯ãåŠçããããã¯ã»ã«ã®åº§æšãšã¢ã€ãã 3ã®ãã€ã³ãããã¥ãŒã¹ããŒã¹ããã¯ãŒã«ãã«å€æããå¿
èŠããããŸããç§ã®å Žåããã¹ãŠã®éèŠãªããŒã¿ããã¥ãŒã¹ããŒã¹ã«æ ŒçŽãããšããäºå®ãåé¡ãè€éã«ããŠããããããã¹ãŠã®ã¬ã€ã®ã«ãŒãã§ããã€ã³ã深床ããã¥ãŒã¹ããŒã¹ã«å€æãããããã¯ã¹ãã£ããã¯ãŒã«ãã¹ããŒã¹ã«æ·±åºŠãå€æããå¿
èŠããããŸãããŸããæ³ç·ãã¯ãŒã«ã空éã«å€æããããšãå¿ããªãã§ãã ããããã ãããµã€ã¯ã«ã«äŸåããªããããããã»ã©éèŠã§ã¯ãããŸããã7.çµè«
ç§ã®èšäºã«æ³šç®ããŠãããèªè
ã«æè¬ããããšæããŸãããããŠãããã«å«ãŸããæ
å ±ã圌ã«ãšã£ãŠå©çšå¯èœã§ãããèå³æ·±ãæçšã§ããããšãé¡ã£ãŠããŸããLeonid ForhaxeDã®èšäºã«ãæè¬ããããšæããŸã -ç§ã¯ããããå€ããåãããããæ¹åããããšããŸããããµã³ãã«ã®ãœãŒã¹ã³ãŒãã¯github.com/AlexWIN32/SSAODemoããããŠã³ããŒãã§ããŸããäŸå
šäœãŸãã¯åã
ã®ãµãã·ã¹ãã ãšããŠã®æäœã«é¢ããææ¡ãã³ã¡ã³ãã¯ãã¡ãŒã«ã§éä¿¡ããããã³ã¡ã³ããšããŠæ®ãããšãã§ããŸããæåãç¥ã£ãŠããŸãïŒä»é²1:
MinVal â , Range â , Factor â , 0 1. NDC , , , , . NDC
:
:
:
, , , :
:
ãã®çµæã以äžãåŸãããŸãã