å°åœ¢ããªãŒãã³ã¹ããŒã¹ã§ã®ã»ãšãã©ã®ã³ã³ãã¥ãŒã¿ãŒã²ãŒã ã®äžå¯æ¬ ãªéšåã§ãããšäž»åŒµããã®ã¯å°é£ã§ãã ãã¬ãŒã€ãŒã®åšå²ã®è¡šé¢ã®ã¬ãªãŒãã®å€æŽãå®è£
ããåŸæ¥ã®æ¹æ³ã¯æ¬¡ã®ãšããã§ã-å¹³é¢ã§ããã¡ãã·ã¥ïŒã¡ãã·ã¥ïŒãååŸãããã®ã°ãªããå
ã®åããªããã£ãã«å¯ŸããŠããã®ããªããã£ãã«åºæã®å€ã§ãã®å¹³é¢ã®æ³ç·ã«æ²¿ã£ãŠã·ããããŸãã ç°¡åã«èšãã°ã256 x 256ãã¯ã»ã«ã®åäžãã£ãã«ãã¯ã¹ãã£ãšå¹³é¢ã°ãªããããããŸãã åããªããã£ãã«ã€ããŠãå¹³é¢äžã®åº§æšã«ããããã¯ã¹ãã£ããå€ãååŸããŸãã ããã§ãååŸããå€ã«ãã£ãŠãå¹³é¢ã«åçŽãªããªããã£ãã®åº§æšãåçŽã«ã·ããããŸãïŒå³1ïŒ
å³1æšé«ããã+å¹³é¢=å°åœ¢ãªãæ©èœããã®ã§ããïŒ ãã¬ãŒã€ãŒãçã®è¡šé¢ã«ããããã®çã®ååŸããã¬ãŒã€ãŒã®ãµã€ãºã«æ¯ã¹ãŠéåžžã«å€§ãããšæ³åãããšã衚é¢ã®æ²çã¯ç¡èŠãããå¹³é¢ã䜿çšãããŸãã ããããç§ãã¡ãçäœã«ãããšããäºå®ãç¡èŠããªããšã©ããªããŸããïŒ ãã®èšäºã§ã¯ããã®ãããªã©ã³ãã¹ã±ãŒããæ§ç¯ããçµéšãèªè
ãšå
±æããããšæããŸãã
1.ã»ã¯ã¿ãŒ
æããã«ãçäœå
šäœã®ã©ã³ãã¹ã±ãŒããããã«æ§ç¯ããããšã¯è³¢æã§ã¯ãããŸãã-ãã®ã»ãšãã©ã¯è¡šç€ºãããŸããã ãããã£ãŠãç¹å®ã®ããªããã£ãã®ç©ºéã®ç¹å®ã®æå°éã®é åãäœæããå¿
èŠããããŸãããã®ããªããã£ãã®çäœã®å¯èŠéšåã®ã¬ãªãŒããæ§æãããŸãã 圌ã®ã»ã¯ã¿ãŒã«ååãä»ããŸãã ã©ããã£ãŠæã«å
¥ããŸããïŒ ãããã£ãŠãå³2aãèŠãŠãã ããã ç·ã®ã»ã«ã¯ç§ãã¡ã®ã»ã¯ã¿ãŒã§ãã æ¬¡ã«ã6ã€ã®ã°ãªãããäœæããŸããåã°ãªããã¯ç«æ¹äœã®é¢ã§ãïŒå³2bïŒã 次ã«ãã°ãªããã圢æããããªããã£ãã®åº§æšãæ£èŠåããŸãïŒå³2cïŒã
å³2ãã®çµæãçäœã«æåœ±ãããç«æ¹äœãåŸãããŸãããããã§ãã»ã¯ã¿ãŒã¯ãã®é¢ã®1ã€ã®é åã§ãã ãªãæ©èœããã®ã§ããïŒ ã°ãªããäžã®ä»»æã®ç¹ãåç¹ããã®ãã¯ãã«ãšèããŠãã ããã ãã¯ãã«æ£èŠåãšã¯äœã§ããïŒ ããã¯ãäžãããããã¯ãã«ãåãæ¹åã®ãã¯ãã«ã«å€æããŸãããåäœé·ã¯åãã§ãã ããã»ã¹ã¯æ¬¡ã®ãšããã§ããæåã«ããã¿ãŽã©ã¹ã®å®çã«åŸã£ãŠãŠãŒã¯ãªããã¡ããªãã¯ã§ãã¯ãã«ã®é·ããèŠã€ããŸãã

次ã«ããã¯ãã«ã®åã³ã³ããŒãã³ãããã®å€ã§é€ç®ããŸã

ä»ãèªåããŠãã ãããçãšã¯äœã§ããïŒ çäœã¯ãäžããããç¹ããçè·é¢ã«ããç¹ã®éåã§ãã çã®ãã©ã¡ããªãã¯æ¹çšåŒã¯æ¬¡ã®ããã«ãªããŸã

ããã§ãx0ãy0ãz0ã¯çã®äžå¿ã®åº§æšãRã¯ãã®ååŸã§ãã ãã®äŸã§ã¯ãçäœã®äžå¿ãåç¹ã§ãããååŸã¯åäžã§ãã æ¢ç¥ã®å€ã眮ãæããŠãæ¹çšåŒã®2ã€ã®éšåã®ã«ãŒããååŸããŸãã æ¬¡ã®ããšãããããŸã

æåéããæåŸã®å€æã¯æ¬¡ã®ããšã瀺ããŠããŸãããçã«å±ããããã«ã¯ããã¯ãã«ã®é·ãã¯1ã«çãããªããã°ãªããŸãããã ãããæ£èŠåã«ãã£ãŠéæããããã®ã§ãã
ããããçäœã®äžå¿ãšååŸãä»»æã®å Žåã¯ã©ãã§ããããïŒ æ¬¡ã®åŒã䜿çšããŠãããã«å±ãããã€ã³ããèŠã€ããããšãã§ããŸã

ããã§ãpSã¯çäžã®ç¹ãCã¯çã®äžå¿ãpNormã¯ä»¥åã«æ£èŠåããããã¯ãã«ãRã¯çã®ååŸã§ãã ç°¡åãªèšèã§èšãã°ãããã§ã¯æ¬¡ã®ããšãèµ·ãããŸãããçã®äžå¿ããè·é¢Rã®ã°ãªããäžã®ç¹ã«åãã£ãŠç§»åããŸããã çµæãšããŠãåãã¯ãã«ã«ã¯åäœé·ããããããçµæãšããŠããã¹ãŠã®ç¹ã¯çã®äžå¿ãããã®ååŸã®è·é¢ã ãçè·é¢ã«ãªããçã®æ¹çšåŒãçã«ãªããŸãã
2.管ç
èŠç¹ããæœåšçã«èŠããã»ã¯ã¿ãŒã®ã°ã«ãŒããååŸããå¿
èŠããããŸãã ãããããããè¡ãæ¹æ³ã¯ïŒ ããç¹ãäžå¿ãšããçäœããããšããŸãã ãŸããçäœã«ããã»ã¯ã¿ãŒãšãçäœã«è¿ã空éã«ãããã€ã³ãPããããŸãã æ¬¡ã«ã2ã€ã®ãã¯ãã«ãäœæããŸãã1ã€ã¯çã®äžå¿ããã»ã¯ã¿ãŒã®äžå¿ã«åãããããã1ã€ã¯çã®äžå¿ããèŠç¹ã«åããããŸãã å³3ãã芧ãã ãã-ãããã®ãã¯ãã«éã®è§åºŠã®çµ¶å¯Ÿå€ã90åºŠæªæºã®å Žåã«ã®ã¿ãã»ã¯ã¿ãŒãèŠãããšãã§ããŸãã
å³3 a-90åºŠæªæºã®è§åºŠ-ã»ã¯ã¿ãŒãæœåšçã«èŠããã b-90床ãã倧ããè§åºŠ-ã»ã¯ã¿ãŒã¯è¡šç€ºãããŸãããã®è§åºŠãååŸããæ¹æ³ã¯ïŒ ãããè¡ãã«ã¯ããã¯ãã«ã®ã¹ã«ã©ãŒç©ã䜿çšããŸãã 3次å
ã®å Žåãæ¬¡ã®ããã«èšç®ãããŸãã

ã¹ã«ã©ãŒç©ã«ã¯ååžããããã£ããããŸãã

å
ã»ã©ããã¯ãã«ã®é·ãã®æ¹çšåŒãå®çŸ©ããŸãã-ä»ã§ã¯ããã¯ãã«ã®é·ãã¯ããã®ãã¯ãã«èªäœã®ã¹ã«ã©ãŒç©ã®ã«ãŒãã«çãããšèšããŸãã ãŸãã¯ãã®é-ãã¯ãã«èªäœã®ã¹ã«ã©ãŒç©ã¯ãã®é·ãã®2ä¹ã«çãããªããŸãã
ããã§ã¯ãã³ãµã€ã³ã®æ³åãèŠãŠã¿ãŸãããã 2ã€ã®å®åŒåã®1ã€ã¯æ¬¡ã®ããã«ãªããŸãïŒå³4ïŒã

å³4ã³ãµã€ã³ã®æ³åãã¯ãã«ã®é·ããaãšbãšããŠãšããšãè§åºŠã¢ã«ãã¡ãæ¢ããŠããŸãã ããããã©ã®ããã«ããŠäŸ¡å€ãåŸãã®ã§ããããïŒ èŠãŠãã ããïŒbããaãåŒããšãaããbã«åãããã¯ãã«ãåŸãããŸãããã¯ãã«ã¯æ¹åãšé·ãã ãã§ç¹åŸŽä»ããããã®ã§ããã¯ãã«aã®çµããã«ãã®éå§ç¹ãã°ã©ãã£ã«ã«ã«èŠã€ããããšãã§ããŸãã ããã«åºã¥ããŠãcã¯ãã¯ãã«b-aã®é·ãã«çãããšèšããŸãã ã ãããç§ãã¡ã¯æåããŸãã

é·ãã®äºä¹ãã¹ã«ã©ãŒç©ãšããŠè¡šçŸãã

ååžããããã£ã䜿çšããŠæ¬åŒ§ãéããŸã

å°ãåã

ãããŠæåŸã«ãæ¹çšåŒã®äž¡æ¹ã®åèªããã€ãã¹2ã§å²ããšã

ããã¯ãã¹ã«ã©ãŒç©ã®ãã1ã€ã®ããããã£ã§ãã ãã®å Žåããã¯ãã«ã®é·ãã1ã«ãªãããã«ãã¯ãã«ãæ£èŠåããå¿
èŠããããŸãã è§åºŠãèšç®ããå¿
èŠã¯ãããŸãã-ã³ãµã€ã³å€ã§ååã§ãã ãŒãæªæºã®å Žåããã®ã»ã¯ã¿ãŒã¯ç§ãã¡ã«èå³ããªããšå®å
šã«èšããŸã
3.ã°ãªãã
ããªããã£ããæç»ããæ¹æ³ã«ã€ããŠèããæãæ¥ãŸããã å
ã»ã©èšã£ãããã«ãã»ã¯ã¿ãŒã¯ç§ãã¡ã®ã¹ããŒã ã®äž»èŠãªã³ã³ããŒãã³ãã§ãããããæœåšçã«èŠããã»ã¯ã¿ãŒããšã«ã°ãªãããæãããã®ããªããã£ããã©ã³ãã¹ã±ãŒãã圢æããŸãã åã»ã«ã¯ã2ã€ã®äžè§åœ¢ã䜿çšããŠè¡šç€ºã§ããŸãã åã»ã«ã«ã¯é£æ¥ããé¢ããããããäžè§åœ¢ã®ã»ãšãã©ã®é ç¹ã®å€ã¯2ã€ä»¥äžã®ã»ã«ã«å¯ŸããŠç¹°ãè¿ãããŸãã é ç¹ãããã¡ãŒã®ããŒã¿ãè€è£œããªãããã«ãã€ã³ããã¯ã¹ãããã¡ãŒãåããŸãã ã€ã³ããã¯ã¹ã䜿çšãããå Žåãã°ã©ãã£ãã¯ãã€ãã©ã€ã³ã¯ãããã®å©ããåããŠãé ç¹ãããã¡ãŒå
ã®ã©ã®ããªããã£ããåŠçããããæ±ºå®ããŸãã ïŒå³5ïŒéžæããããããžã¯ãäžè§åœ¢ã®ãªã¹ãïŒD3D11_PRIMITIVE_TOPOLOGY_TRIANGLELISTïŒã§ãã
å³5ã€ã³ããã¯ã¹ãšããªããã£ãã®èŠèŠè¡šç€ºã»ã¯ã¿ãŒããšã«åå¥ã®é ç¹ãããã¡ãŒãäœæãããšãè²»çšãããããããŸãã ã°ãªãã空éã®åº§æšã§1ã€ã®ãããã¡ãŒã䜿çšããæ¹ãã¯ããã«å¹ççã§ããã€ãŸããxãåã§ãyãè¡ã§ãã ãããããããããã©ã®ããã«ããŠçäœã®ãã€ã³ããåŸãã®ã§ããããïŒ ã»ã¯ã¿ãŒã¯ãç¹å®ã®ãã€ã³ãSã§å§ãŸãæ£æ¹åœ¢ã®é åã§ãããã¹ãŠã®ã»ã¯ã¿ãŒã®é¡ã®é·ãã¯åãã§ããSLenãšåŒã³ãŸãããã ã°ãªããã¯ã»ã¯ã¿ãŒã®å
šé åãã«ããŒããè¡ãšåã®æ°ãåãã§ãããããã£ãŠãã»ã«é¢ã®é·ããèŠã€ããããã«ãæ¬¡ã®æ¹çšåŒãæ§ç¯ã§ããŸãã

ããã§ãLenã¯ã»ã«ã®é¢ã®é·ããMSizeã¯ã°ãªããã®è¡ãŸãã¯åã®æ°ã§ãã äž¡åŽãMSizeã§å²ããCLenãååŸããŸã

ããã«é²ã¿ãŸãã ã»ã¯ã¿ãŒãå±ããç«æ¹äœã®é¢ã®ç©ºéã¯ãåäœé·ãã®2ã€ã®ãã¯ãã«ã®ç·åœ¢çµåãšããŠè¡šãããšãã§ããŸã-V1ããã³V2ãšåŒã³ãŸãã æ¬¡ã®æ¹çšåŒããããŸãïŒå³6ãåç
§ïŒã

å³6ã°ãªããäžã®ç¹ã®åœ¢æã®èŠèŠè¡šç€ºçäžã®ç¹ãååŸããããã«ãå
ã«å°åºããæ¹çšåŒã䜿çšããŸã

4.é«ã
ãã®ç¬éã«éæããããšã¯ãã¹ãŠãã»ãšãã©é¢šæ¯ã«äŒŒãŠããŸããã é«ãã®éã-ãããå¯èœã«ããäœãã远å ããæãæ¥ãŸããã åç¹ãäžå¿ãšããåäœååŸã®çäœãšããã®çäœã«ããå€ãã®ãã€ã³ã{P0ãP1ãP2 ... PN}ããããšæ³åããŠãã ããã ãããã®åç¹ã¯ãåç¹ããã®åäœãã¯ãã«ãšããŠè¡šãããšãã§ããŸãã ããã§ãå€ã®ã»ãããããããããããç¹å®ã®ãã¯ãã«ã®é·ãã§ãããšæ³åããŠãã ããïŒå³7ïŒã

ãããã®å€ã2次å
ã®ãã¯ã¹ãã£ã«ä¿åããŸãã ãã¯ã»ã«ãã¯ã¹ãã£ã®åº§æšãšçäžã®ç¹ãã¯ãã«ã®é¢ä¿ãèŠã€ããå¿
èŠããããŸãã å§ããŸãããã
ãã«ã«ã座æšã«å ããŠãçäœäžã®ç¹ã¯ãç座æšç³»ã䜿çšããŠèšè¿°ããããšãã§ããŸãã ãã®å Žåã座æšã¯ãæ¹äœè§ã極è§ãåç¹ãããã€ã³ããŸã§ã®æçè·é¢ã®å€ã®3ã€ã®èŠçŽ ã§æ§æãããŸãã æ¹äœè§ã¯ãX軞ãšãåç¹ããXZå¹³é¢äžã®ç¹ãžã®ããŒã ã®æåœ±ãšã®éã®è§åºŠã§ãã 0ã360床ã®å€ãåãããšãã§ããŸãã æ¥µè§-Y軞ãšåç¹ããç¹ãŸã§ã®å
ç·ãšã®éã®è§åºŠã 察空ãŸãã¯éåžžãšåŒã°ããããšããããŸãã 0ã180床ã®å€ãåããŸãã ïŒå³8ãåç
§ïŒ
å³8çé¢åº§æšãã«ã«ãç³»ããçé¢ã«ç§»åããã«ã¯ã次ã®åŒã䜿çšããŸãïŒY軞ãäžåãã§ãããšä»®å®ããŸãïŒã

ããã§ãdã¯ãã€ã³ããŸã§ã®è·é¢ãaã¯æ¥µè§ãbã¯æ¹äœè§ã§ãã ãã©ã¡ãŒã¿dã¯ããæ¹çšåŒãããããããã«ããåç¹ããç¹ãŸã§ã®ãã¯ãã«ã®é·ãããšããŠèª¬æããããšãã§ããŸãã æ£èŠåããã座æšã䜿çšãããšã極è§ãèŠã€ãããšãã«åå²ãåé¿ã§ããŸãã å®éããªããããã®è§åºŠãå¿
èŠãªã®ã§ããããïŒ ãããããæå€§ç¯å²ã§é€ç®ããŠã0ãã1ãŸã§ã®ä¿æ°ãååŸãããããã䜿çšããŠã·ã§ãŒããŒã®ãã¯ã¹ãã£ããéžæããŸãã æ¥µè§ã®ä¿æ°ãååŸããå Žåãè§åºŠãäœçœ®ããååã®äžãèæ
®ããå¿
èŠããããŸãã ãããããxããŒãã®å ŽåãåŒz / xã®å€ã¯å®çŸ©ãããŸããããšèšããŸãã zããŒãã«çããå Žåãxã®å€ã«é¢ä¿ãªãè§åºŠã¯ãŒãã«ãªããŸãã
ãããã®å€ã«ç¹å¥ãªã±ãŒã¹ã远å ããŸãããã æ£èŠåããã座æšïŒéåžžïŒ-ããã€ãã®æ¡ä»¶ã远å ããŸãïŒæ³ç·ã®Xå€ããŒãã§Zå€ããŒããã倧ããå Žåãä¿æ°ã¯0.25ãXããŒãã§ZããŒãããå°ããå Žåã¯0.75ã«ãªããŸãã Zã®å€ããŒãã§XããŒãããå°ããå Žåããã®å Žåãä¿æ°ã¯0.5ã«ãªããŸãã ãããã¯ãã¹ãŠããµãŒã¯ã«ã§ç°¡åã«ç¢ºèªã§ããŸãã ããããZããŒãã§XããŒããã倧ããå Žåã¯ã©ããªããŸããïŒãã®å Žåã0ãš1ã®äž¡æ¹ãæ£ããã§ããããïŒ 1ãéžæããããšãæ³åããŠãã ããããŸããæå°æ¹äœè§0ããæå€§90床ã®ã»ã¯ã¿ãŒãèããŠã¿ãŸãããã æ¬¡ã«ããã®ã»ã¯ã¿ãŒã衚瀺ããã°ãªããã®æåã®è¡ã«ããæåã®3ã€ã®é ç¹ãæ€èšããŸãã æåã®é ç¹ã«ã€ããŠã¯ãæ¡ä»¶ãæºããããã¯ã¹ãã£åº§æšXã1ã«èšå®ããŸããæããã«ããã®æ¡ä»¶ã¯æ¬¡ã®2ã€ã®é ç¹ã«ã¯åœãŠã¯ãŸããŸããã 0.1ïŒã ãã ããåãè¡ã®æåŸã®3ã€ã®é ç¹ã®è§åºŠã270ã360ã®ã»ã¯ã¿ãŒã§ã¯ããã¹ãŠãæ£ãããªããŸããæåŸã®é ç¹ã®æ¡ä»¶ãæ©èœããã»ããïŒ0.9ã0.95ã1.0ïŒãååŸãããŸãã çµæãšããŠãŒããéžæãããšãã»ããïŒ0.0ã0.05ã0.1ïŒãšïŒ0.9ã0.95ã0.0ïŒãåŸãããŸã-ãããã®å Žåã§ããããã¯ããªãé¡èãªè¡šé¢ã®æªã¿ã«ã€ãªãããŸãã ããã§ã¯ã次ãé©çšããŸãããã ã»ã¯ã¿ãŒã®äžå¿ãåãããã®äžå¿ãæ£èŠåããŠãçäœã«ç§»åããŸãã æ¬¡ã«ããã¯ãã«ïŒ0ã0ã1ïŒã«ãã£ãŠæ£èŠåãããäžå¿ã®ã¹ã«ã©ãŒç©ãèšç®ããŸãã æ£åŒã«èšãã°ããã®ãã¯ãã«ã¯XYå¹³é¢ã«åçŽã§ãããã»ã¯ã¿ãŒã®äžå¿ã®æ£èŠåããããã¯ãã«ãšãã®ã¹ã«ã©ãŒç©ãèšç®ããã®ã§ãäžå¿ãå¹³é¢ã®ã©ã¡ãåŽã«ããããçè§£ã§ããŸãã ãŒãããå°ããå Žåãã»ã¯ã¿ãŒã¯å¹³é¢ã®åŸãã«ãããå€1ãå¿
èŠã§ããã¹ã«ã©ãŒç©ããŒããã倧ããå Žåãã»ã¯ã¿ãŒã¯å¹³é¢ã®åã«ãããããå¢çå€ã¯0ã«ãªããŸãïŒå³9ãåç
§ïŒã
å³9ãã¯ã¹ãã£åº§æšã«0ã1ãéžæããåé¡ä»¥äžã¯ãçé¢ãããã¯ã¹ãã£åº§æšãååŸããããã®ã³ãŒãã§ãã æ³šæããŠãã ãã-èšç®ã®ãšã©ãŒã®ããããŒããšçãããã©ããã®æ£åžžå€ã確èªããããšã¯ã§ããŸããã代ããã«ããããã®çµ¶å¯Ÿå€ãç¹å®ã®ãããå€ïŒããšãã°ã0.001ïŒãšæ¯èŒããå¿
èŠããããŸã
//norm - , //offset - , norm //zeroTreshold - (0.001) float2 GetTexCoords(float3 norm, float3 offset) { float tX = 0.0f, tY = 0.0f; bool normXIsZero = abs(norm.x) < zeroTreshold; bool normZIsZero = abs(norm.z) < zeroTreshold; if(normXIsZero || normZIsZero){ if(normXIsZero && norm.z > 0.0f) tX = 0.25f; else if(norm.x < 0.0f && normZIsZero) tX = 0.5f; else if(normXIsZero && norm.z < 0.0f) tX = 0.75f; else if(norm.x > 0.0f && normZIsZero){ if(dot(float3(0.0f, 0.0f, 1.0f), offset) < 0.0f) tX = 1.0f; else tX = 0.0f; } }else{ tX = atan(norm.z / norm.x); if(norm.x < 0.0f && norm.z > 0.0f) tX += 3.141592; else if(norm.x < 0.0f && norm.z < 0.0f) tX += 3.141592; else if(norm.x > 0.0f && norm.z < 0.0f) tX = 3.141592 * 2.0f + tX; tX = tX / (3.141592 * 2.0f); } tY = acos(norm.y) / 3.141592; return float2(tX, tY); }
é ç¹ã·ã§ãŒããŒã®äžéããŒãžã§ã³ãæäŸããŸã
//startPos - //vec1, vec2 - //gridStep - //sideSize - //GetTexCoords() - VOut ProcessVertex(VIn input) { float3 planePos = startPos + vec1 * input.netPos.x * gridStep.x + vec2 * input.netPos.y * gridStep.y; float3 sphPos = normalize(planePos); float3 normOffset = normalize(startPos + (vec1 + vec2) * sideSize * 0.5f); float2 tc = GetTexCoords(sphPos, normOffset); float height = mainHeightTex.SampleLevel(mainHeightTexSampler, tc, 0).x; posL = sphPos * (sphereRadius + height); VOut output; output.posH = mul(float4(posL, 1.0f), worldViewProj); output.texCoords = tc; return output; }
5.ç
§æ
颚æ¯ã®è²ã®ç
§æäŸåæ§ãå®çŸããããã«ã次ã®åŒã䜿çšããŸãã

ããã§ãIã¯ãã€ã³ãã®è²ãLdã¯å
æºã®è²ãKdã¯ç
§æããã衚é¢ã®ææã®è²ãaã¯å
æºã®ãã¯ãã«ãšç
§æããã衚é¢ã®æ³ç·ãšã®éã®è§åºŠã§ãã ããã¯ãã©ã³ããŒãã®ã³ãµã€ã³ã®æ³åã®ç¹å¥ãªå Žåã§ãã ããã«ãããã®ãšãã®çç±ãèŠãŠã¿ãŸãããã LdãšKdã®ä¹ç®ã¯ãè²ã®æåããšã®ä¹ç®ãã€ãŸãïŒLd.r * Kd.rãLd.g * Kd.gãLd.b * Kd.bïŒãæå³ããŸãã æ¬¡ã®ç¶æ³ãæ³åãããšãæå³ãçè§£ãããããªãå ŽåããããŸãããªããžã§ã¯ããç·è²ã®å
æºã§ç
§ããããå Žåããªããžã§ã¯ãã®è²ã¯ç·è²ã®ã°ã©ããŒã·ã§ã³ã«ãªããšæ³å®ããŸãã çµæïŒ0 * Kd.rã1 * Kd.gã0 * Kd.bïŒã¯ïŒ0ãKd.gã0ïŒ-ãŸãã«å¿
èŠãªãã®ãäžããŸãã ããã«é²ã¿ãŸãã åè¿°ã®ããã«ãæ£èŠåããããã¯ãã«éã®è§åºŠã®äœåŒŠã¯ããããã®ã¹ã«ã©ãŒç©ã§ãã ç§ãã¡ã®èгç¹ãããã®æå€§å€ãšæå°å€ãèããŠã¿ãŸãããã ãã¯ãã«éã®è§åºŠã®äœåŒŠã1ã®å Žåããã®è§åºŠã¯0ã§ãããããã£ãŠãäž¡æ¹ã®ãã¯ãã«ã¯åäžçŽç·äžã«ãããŸãïŒåãç·äžã«ãããŸãïŒã
åãããšãã³ãµã€ã³-1ã®å€ã«ãåœãŠã¯ãŸããŸãããã®å Žåã®ã¿ããã¯ãã«ã¯å察æ¹åãæããŸãã æ³ç·ãã¯ãã«ãšå
ââæºãžã®ãã¯ãã«ãå
±ç·æ§ç¶æ
ã«è¿ãã»ã©ãæ³ç·ãå±ãã衚é¢ã®ç
§æä¿æ°ãé«ããªãããšãããããŸãã ãŸãããã®æ³ç·ãå
æºãžã®æ¹åã«å¯ŸããŠå察æ¹åãåããŠããå Žåã衚é¢ãç
§ããããšã¯ã§ããªããšæ³å®ãããŠããŸãããã®ãããæ£ã®ã³ãµã€ã³å€ã®ã¿ã䜿çšããŸãã
ç§ã¯ãã©ã¬ã«ãœãŒã¹ã䜿çšããŠããããããã®äœçœ®ã¯ç¡èŠã§ããŸãã èæ
®ãã¹ãå¯äžã®ããšã¯ãå
æºã«ãã¯ãã«ã䜿çšããããšã§ãã ã€ãŸããå
ç·ã®æ¹åïŒ1.0ã-1.0ã0ïŒã§ããã°ããã¯ãã«ïŒ-1.0ã1.0ã0ïŒã䜿çšããå¿
èŠããããŸãã ç§ãã¡ã«ãšã£ãŠé£ããã®ã¯ãæ³ç·ãã¯ãã«ã ãã§ãã å¹³é¢ã®æ³ç·ãèšç®ããã®ã¯ç°¡åã§ã-ãããèšè¿°ãã2ã€ã®ãã¯ãã«ã®ãã¯ãã«ç©ãçæããå¿
èŠããããŸãã ãã¯ãã«ç©ã¯å坿ã§ããããšã«æ³šæããããšãéèŠã§ã-å åã®é åºãèæ
®ããå¿
èŠããããŸãã ãã®å Žåãæ¬¡ã®ããã«ãã°ãªãã空éå
ã®é ç¹ã®åº§æšãç¥ã£ãŠãäžè§åœ¢ã®æ³ç·ãååŸã§ããŸãïŒpxãšpyã®å¢çã±ãŒã¹ãèæ
®ããŠããªãããšã«æ³šæããŠãã ããïŒ
float3 p1 = GetPosOnSphere(p); float3 p2 = GetPosOnSphere(float2(px + 1, py)); float3 p3 = GetPosOnSphere(float2(px, py + 1)); float3 v1 = p2 - p1; float3 v2 = p3 - p1; float3 n = normalzie(cross(v1, v2));
ããããããã ãã§ã¯ãããŸããã ã»ãšãã©ã®ã°ãªããé ç¹ã¯ãäžåºŠã«4ã€ã®å¹³é¢ã«å±ããŸãã 蚱容ã§ããçµæãåŸãã«ã¯ã次ã®ããã«å¹³åæ³ç·ãèšç®ããå¿
èŠããããŸãã
Na = normalize(n0 + n1 + n2 + n3)
GPUã§ãã®ã¡ãœãããå®è£
ããã®ã¯éåžžã«é«äŸ¡ã§ããæ³ç·ãšãã®å¹³ååãèšç®ããã«ã¯2ã€ã®ã¹ããããå¿
èŠã§ãã ããã«ãæå¹æ§ã¯äœãã§ãã ããã«åºã¥ããŠãå¥ã®æ¹æ³ãéžæããŸãã-æ³ç·ãããã䜿çšããŸãïŒå³10ïŒã
å³10æ³ç·ãããããã䜿çšããåçã¯ãé«ãããããšåãã§ã-ã¡ãã·ã¥é ç¹ã®ç座æšããã¯ã¹ãã£ã«å€æããéžæãè¡ããŸãã ãã®ããŒã¿ãçŽæ¥äœ¿çšããããšã¯ã§ããŸãã-çäœã䜿çšããŠãããé ç¹ã«ã¯ç¬èªã®æ³ç·ãããããããèæ
®ããå¿
èŠããããŸãã ãããã£ãŠãæ³ç·ãããããŒã¿ãåºåºã®TBN座æšãšããŠäœ¿çšããŸãã æ ¹æ ã¯äœã§ããïŒ ä»¥äžã«äŸã瀺ããŸãã ããªããå®å®é£è¡å£«ã§ãããå®å®ã®ã©ããã«ããç¯å°ã«åº§ã£ãŠãããšæ³åããŠãã ããã MCCãããããŒã³ã³ãã1ã¡ãŒãã«å·Šã2ã¡ãŒãã«äžã3ã¡ãŒãã«åæ¹ã«ç§»åããå¿
èŠããããŸãããšããã¡ãã»ãŒãžã衚瀺ãããŸãã ããã¯ã©ã®ããã«æ°åŠçã«è¡šçŸã§ããŸããïŒ ïŒ1ã0ã0ïŒ* 1 +ïŒ0ã1ã0ïŒ* 2 +ïŒ0ã0ã1ïŒ* 3 =ïŒ1,2,3ïŒã è¡å圢åŒã§ã¯ããã®æ¹çšåŒã¯æ¬¡ã®ããã«è¡šçŸã§ããŸãã

ä»ãããªããç¯å°ã«ã座ã£ãŠãããšæ³åããŠã¿ãŠãã ãããMCCããããªãã«æžãããã®ã¯ããæ¹åãã¯ãã«ãéä¿¡ããŸãããæåã®ãã¯ãã«ã§1ã¡ãŒãã«ã2çªç®ã§2ã¡ãŒãã«ã3çªç®ã§3ã¡ãŒãã«é²ãå¿
èŠããããŸããã æ°ãã座æšã®æ¹çšåŒã¯æ¬¡ã®ããã«ãªããŸãã

å±éããããšã³ããªã¯æ¬¡ã®ããã«ãªããŸãã

ãŸãã¯ãããªãã¯ã¹åœ¢åŒã§ïŒ

ãããã£ãŠããã¯ãã«V1ãV2ãããã³V3ã®è¡åã¯åºåºã§ããããã¯ãã«ïŒ1,2,3ïŒã¯ãã®åºåºã®ç©ºéå
ã®åº§æšã§ãã
äžé£ã®ãã¯ãã«ïŒåºåºMïŒããããããŒã³ã³ã«å¯Ÿããçžå¯Ÿçãªäœçœ®ïŒãã€ã³ãPïŒãããã£ãŠããããšãæ³åããŠãã ããã ãã®åºç€ã®ç©ºéã§ã®åº§æšãç¥ãå¿
èŠããããŸã-åãå Žæã«ããããã«ãããã®ãã¯ãã«ã«æ²¿ã£ãŠã©ãã ãåé²ããå¿
èŠããããã ç®çã®åº§æšãæ³åããŠãã ããïŒXïŒ

PãMãããã³Xãæ°å€ã®å ŽåãåçŽã«æ¹çšåŒã®äž¡åŽãMã§åé¢ããŸãããæ²ããããª...éè¡åã®ããããã£ã«åŸã£ãŠãéã«ãªããŸãã

ããã§ãIã¯åäœè¡åã§ãã ç§ãã¡ã®å Žåããã®ããã«èŠããŸã

ããã«ããäœãåŸãããŸããïŒ ãã®è¡åã«Xãæãããšã

ãŸããè¡åã®ä¹ç®ã«ã¯çµåæ§ã®ç¹æ§ãããããšãæç¢ºã«ããå¿
èŠããããŸãã

ãã¯ãã«ã3è¡1åã®è¡åãšããŠéåžžã«æ£ããèããããšãã§ããŸãã
äžèšã®ãã¹ãŠãèãããšãåŒã®å³åŽã«XãååŸããããã«ãæ£ããé åºã§äž¡åŽã«éMè¡åãä¹ç®ããå¿
èŠããããšçµè«ä»ããããšãã§ããŸã

ä»åŸãã®çµæãå¿
èŠã«ãªããŸãã
åé¡ã«æ»ããŸãããã æ£èŠçŽäº€åºåºã䜿çšããŸã-ããã¯ãV1ãV2ãããã³V3ãäºãã«çŽäº€ïŒ90床ã®è§åºŠã圢æïŒããåäœé·ããæã€ããšãæå³ããŸãã æ¥ç·ãã¯ãã«ã¯ãV1ãV2-äºéæ¥ç·ãã¯ãã«ãV3-æ³ç·ãšããŠæ©èœããŸãã åŸæ¥ã®DirectX転眮ãã¥ãŒã§ã¯ããããªãã¯ã¹ã¯æ¬¡ã®ããã«ãªããŸãã

ããã§ãTã¯æ¥ç·ãã¯ãã«ãBã¯äž¡æ¥ç·ãã¯ãã«ãNã¯æ³ç·ã§ãã ããããèŠã€ããŸãããã éåžžãæãç°¡åãªæ¹æ³ã¯ãå®éããããã¯ãã€ã³ãã®æ£èŠåããã座æšã§ãã Bitangentãã¯ãã«ã¯ãæ³ç·ãã¯ãã«ç©ãšæ¥ç·ãã¯ãã«ã«çãããªããŸãã æãé£ããã®ã¯ãæ¥ç·ãã¯ãã«ã䜿çšããããšã§ãã ããã¯ãããç¹ã§ã®åã®æ¥ç·ã®æ¹åã«çãããªããŸãã ãã®ç¬éãèŠãŠã¿ãŸãããã ãŸããããè§åºŠaã«ã€ããŠXZå¹³é¢ã®åäœåäžã®ç¹ã®åº§æšãèŠã€ããŸã

ãã®ç¹ã§ã®åã®æ¥ç·ã®æ¹åã¯ã2ã€ã®æ¹æ³ã§èŠã€ããããšãã§ããŸãã åäžã®ç¹ãžã®ãã¯ãã«ãšæ¥ç·ãã¯ãã«ã¯çŽäº€ããŸã-ãããã£ãŠã颿°sinãšcosã¯åšæçã§ãããããåçŽã«pi / 2ãè§åºŠaã«è¿œå ããŠãç®çã®æ¹åãååŸã§ããŸãã pi / 2ã®offsetããããã£ã«ãããšïŒ

次ã®ãã¯ã¿ãŒããããŸãã

埮åã䜿çšããããšãã§ããŸã-詳现ã«ã€ããŠã¯ãä»é²3ãåç
§ããŠãã ããããããã£ãŠãå³11ã§ãåé ç¹ã®åºåºãæ§ç¯ãããçäœãèŠãããšãã§ããŸãã éããã¯ãã«ã¯æ³ç·ãèµ€ã¯æ¥ç·ãã¯ãã«ãç·ã¯äž¡æ¹åãã¯ãã«ã§ãã
å³11åé ç¹ã«TBNããŒã¹ãæã€çã èµ€-æ¥ç·ãã¯ãã«ãç·-äºæ¹åãã¯ãã«ãéãã¯ãã«-éåžžåºç€ãçè§£ããŸãã-ããŠãæ³ç·ããããååŸããŸãããã ãããè¡ãã«ã¯ãSobelãã£ã«ã¿ãŒã䜿çšããŸãã Sobelãã£ã«ã¿ãŒã¯ãåãã€ã³ãïŒå€§ãŸãã«èšãã°ãèŒåºŠå€åãã¯ãã«ïŒã§ç»åã®èŒåºŠåŸé
ãèšç®ããŸãã ãã£ã«ã¿ãŒã®åçã¯ããã³ã¢ããšåŒã°ããç¹å®ã®å€ã®ãããªãã¯ã¹ãããã®ãããªãã¯ã¹ã®æ¬¡å
å
ã®åãã¯ã»ã«ãšãã®é£æ¥ãã¯ã»ã«ã«é©çšããå¿
èŠããããšããããšã§ãã ã«ãŒãã«Kã§ãã¯ã»ã«PãåŠçãããšããŸããç»åã®å¢çã«ãªãå Žåãå·Šäžãäžãå³äžãªã©ã®8ã€ã®é£æ¥ãã¯ã»ã«ããããŸãã ããããtlãtãtbãlãrãblãbãbrãšåŒã³ãŸãã ãããã£ãŠããã®ãã¯ã»ã«ã«Kã«ãŒãã«ãé©çšããããšã¯æ¬¡ã®ãšããã§ãã
Pn = tl * KïŒ0ã0ïŒ+ t * KïŒ0,1ïŒ+ tb * KïŒ0,2ïŒ+
ïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspl * KïŒ1ã0ïŒ+ P * KïŒ1,1ïŒ+ r * KïŒ1,2ïŒ+
ïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspïŒnbspbl * KïŒ2ã0ïŒ+ b * KïŒ2,1ïŒ+ br * KïŒ2,2ïŒ
ãã®ããã»ã¹ã¯ãç³ã¿èŸŒã¿ããšåŒã°ããŸãã Sobelãã£ã«ã¿ãŒã¯2ã€ã®ã³ã¢ã䜿çšããŠãåçŽæ¹åãšæ°Žå¹³æ¹åã®åŸé
ãèšç®ããŸãã ããããKxããã³KãšããŠç€ºããŸãã

åºç€ããããŸã-å®è£
ãéå§ã§ããŸãã ãŸãããã¯ã»ã«ã®æãããèšç®ããå¿
èŠããããŸãã PALã·ã¹ãã ã§ã¯ãRGBã«ã©ãŒã¢ãã«ããYUVã¢ãã«ãžã®å€æã䜿çšããŸãã

ãã ããç»åã¯å
ã
ã°ã¬ãŒã¹ã±ãŒã«ã§ãã£ãããããã®æé ã¯çç¥ã§ããŸãã ããã§ãKxããã³Kyã«ãŒãã«ã䜿çšããŠå
ã®ã€ã¡ãŒãžããçž®å°ãããå¿
èŠããããŸãã ãããã£ãŠãXããã³Yã°ã©ããŒã·ã§ã³ã®ã³ã³ããŒãã³ããååŸããŸãã ãã®ãã¯ãã«ã®æ³ç·å€ãéåžžã«æçšã§ã-䜿çšããŸããããæ£èŠåãããåŸé
æ³ç·ã®å€ãå«ãç»åã«ã¯ããã€ãã®æçšãªçšéããããŸãã æ£èŠåãšã¯ãæ¬¡ã®æ¹çšåŒãæå³ããŸã

ããã§ãVã¯æ£èŠåããå€ãVminãšVmaxã¯ãããã®å€ã®ç¯å²ã§ãã ãã®å Žåãæå°å€ãšæå€§å€ã¯çæããã»ã¹äžã«è¿œè·¡ãããŸãã Sobelãã£ã«ã¿ãŒã®å®è£
äŸã¯æ¬¡ã®ãšããã§ãã
float SobelFilter::GetGrayscaleData(const Point2 &Coords) { Point2 coords; coords.x = Math::Saturate(Coords.x, RangeI(0, image.size.width - 1)); coords.y = Math::Saturate(Coords.y, RangeI(0, image.size.height - 1)); int32_t offset = (coords.y * image.size.width + coords.x) * image.pixelSize; const uint8_t *pixel = &image.pixels[offset]; return (image.pixelFormat == PXL_FMT_R8) ? pixel[0] : (0.30f * pixel[0] +
ãœãŒãã«ãã£ã«ã¿ãŒã«ã¯ç·åœ¢å颿§ã®ç¹æ§ãããããããã®æ¹æ³ãæé©åã§ãããšèšããªããã°ãªããŸããã
é£ããéšåã¯çµãããŸãã-æ³ç·ãããã®ãã¯ã»ã«ã®Rãã£ã³ãã«ãšGãã£ã³ãã«ã®åŸé
æ¹åã®X座æšãšY座æšãæžãçããå¿
èŠããããŸãZ座æšã«ã¯1ã€äœ¿çšããŸãã ãŸãã3次å
ã®ä¿æ°ãã¯ãã«ã䜿çšããŠãããã®å€ã調æŽããŸãã 以äžã¯ãã³ã¡ã³ãä»ãã®æ³ç·ããããçæããäŸã§ãã
次ã«ãã·ã§ãŒããŒã§æ³ç·ãããã䜿çšããäŸã瀺ããŸãã
6.詳现ã¬ãã«
ããŠãä»ç§ãã¡ã®é¢šæ¯ãã©ã€ãã¢ãããããŠããŸãïŒ æã«é£ã¶ããšãã§ããŸã-é«ãããããç¹ç¯ãããããªã¢ã«ã®è²ãèšå®ããã»ã¯ã¿ãŒãããŒãããã°ãªãããµã€ãºã{16ã16}ã«èšå®ããŸã...ã¯ããäœããè¶³ããŸãã-{256ã256}ãå
¥ããŸã-ãããäœããé
ããªããŸãããããŠãªãé æ¹ã»ã¯ã¿ãŒã§ã®è©³çŽ°åºŠãé«ãã®ã§ããïŒ ããã«ã芳枬è
ãææã«è¿ããã°è¿ãã»ã©ãèŠãããšãã§ããã»ã¯ã¿ãŒã¯å°ãªããªããŸãã ã¯ã...ãŸã ããã¹ãããšããããããããŸãïŒ æåã«ãäœåãªã»ã¯ã¿ãŒãã«ããããæ¹æ³ãèŠã€ããŸãããã ããã§æ±ºå®ããå€ã¯ãææã®è¡šé¢ããã®èŠ³æž¬è
ã®é«ãã§ã-é«ãã»ã©ãããå€ãã®ã»ã¯ã¿ãŒãèŠãããšãã§ããŸãïŒå³12ïŒ
å³12芳枬è
ã®èº«é·ã®åŠçæžã¿ã»ã¯ã¿ãŒæ°ãžã®äŸåæ§æ¬¡ã®ããã«é«ããèŠã€ããŸã-çäœã®äžå¿ã«ãã芳枬è
ã®äœçœ®ãããã¯ãã«ãæ§ç¯ãããã®é·ããèšç®ããŠãçäœã®ååŸã®å€ãããããæžç®ããŸãã åã«ããªãã¶ãŒããŒã«ãããã¯ãã«ãšã»ã¯ã¿ãŒã®äžå¿ã«ãããã¯ãã«ã®ã¹ã«ã©ãŒç©ããŒãæªæºã§ããå Žåããã®ã»ã¯ã¿ãŒã¯é¢å¿ããããŸãã-ä»ã§ã¯ãŒãã§ã¯ãªããé«ãã«ç·åœ¢ã«äŸåããå€ã䜿çšããŸãã ãŸãã倿°ã決å®ããŸããããã¹ã«ã©ãŒç©ã®æå°å€ãšæå€§å€ãããã³é«ãã®æå°å€ãšæå€§å€ãååŸããŸãã æ¬¡ã®æ¹çšåŒç³»ãæ§ç¯ããŸã

2çªç®ã®æ¹çšåŒã§Aã衚çŸãã

2çªç®ã®æ¹çšåŒã®Aãæåã®æ¹çšåŒã«ä»£å
¥ããŸã

æåã®æ¹çšåŒããBã衚çŸãã

æåã®æ¹çšåŒã®Bã2çªç®ã®æ¹çšåŒã«ä»£å
¥ããŸã

次ã«ã颿°ã®å€æ°ã眮ãæããŸã

ãããŠåŸã

ããã§ãHminãšHmaxã¯é«ãã®æå°å€ãšæå€§å€ãDminãšDmaxã¯ã¹ã«ã©ãŒç©ã®æå°å€ãšæå€§å€ã§ãã ãã®åé¡ã¯å¥ã®æ¹æ³ã§è§£æ±ºã§ããŸã-ä»é²4ãåç
§ããŠãã ããã
次ã«ã詳现ã¬ãã«ãçè§£ããå¿
èŠããããŸãã ãããããã¹ã«ã©ãŒç©ã®ç¯å²ã決å®ããŸãã æ¬äŒŒã³ãŒãã§ã¯ãç¹å®ã®ã¬ãã«ã§ã»ã¯ã¿ãŒã®ã¡ã³ããŒã·ãããæ±ºå®ããããã»ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
,
åã¬ãã«ã®å€ã®ç¯å²ãèšç®ããå¿
èŠããããŸãã ãŸãã2ã€ã®æ¹çšåŒã®ã·ã¹ãã ãæ§ç¯ããŸã

ããã解決ããŠãç§ãã¡ã¯åŸã

ãããã®ä¿æ°ã䜿çšããŠã颿°ãå®çŸ©ããŸã

ããã§ãRmaxã¯ã¹ã«ã©ãŒç©ã®ãã¡ã€ã³ïŒDïŒHïŒ-DminïŒãRminã¯ã¬ãã«ã«ãã£ãŠæ±ºå®ãããæå°é åã§ãã 0.01ã®å€ã䜿çšããŸãã æ¬¡ã«ãDmaxããçµæãæžç®ããå¿
èŠããããŸã

ãã®é¢æ°ã䜿çšããŠããã¹ãŠã®ã¬ãã«ã®ãšãªã¢ãååŸããŸãã 以äžã«äŸã瀺ããŸãã
const float dotArea = dotRange.maxVal - dotRange.minVal; const float Rmax = dotArea, Rmin = 0.01f; float lodsCnt = lods.size(); float A = Rmax; float B = powf(Rmin / Rmax, 1.0f / (lodsCnt - 1.0f)); for(size_t g = 0; g < lods.size(); g++){ lods[g].dotRange.minVal = dotRange.maxVal - A * powf(B, g); lods[g].dotRange.maxVal = dotRange.maxVal - A * powf(B, g + 1); } lods[lods.size() - 1].dotRange.maxVal = 1.0f;
ããã§ãã»ã¯ã¿ãŒãã©ã®è©³çްã¬ãã«ã«å±ãããã倿ã§ããŸãïŒå³13ïŒã
å³13詳现ã¬ãã«ã«å¿ããã»ã¯ã¿ãŒã®è²ã®åºå¥æ¬¡ã«ãã°ãªããã®ãµã€ãºãææ¡ããå¿
èŠããããŸãã ã¬ãã«ããšã«ã°ãªãããç¶æããã®ã¯éåžžã«é«äŸ¡ã§ããããã»ã¬ãŒã·ã§ã³ã䜿çšããŠ1ã€ã®ã°ãªããã®è©³çްããªã³ã¶ãã©ã€ã§å€æŽããæ¹ãã¯ããã«å¹ççã§ãã ãããè¡ãã«ã¯ãéåžžã®é ç¹ãšãã¯ã»ã«ã«å ããŠããã«ã·ã§ãŒããŒãšãã¡ã€ã³ã·ã§ãŒããŒãå®è£
ããå¿
èŠããããŸãã ãã«ã·ã§ãŒããŒã®äž»ãªã¿ã¹ã¯ã¯ããã¬ãŒã¯ãã€ã³ããæºåããããšã§ãã ããã¯ãã¡ã€ã³é¢æ°ãšã³ã³ãããŒã«ãã€ã³ãã®ãã©ã¡ãŒã¿ãŒãèšç®ãã颿°ã®2ã€ã®éšåã§æ§æãããŠããŸãã æ¬¡ã®å±æ§ã®å€ãå¿
ãæå®ããŠãã ããã
ãã¡ã€ã³
åå²
åºåããããžãŒ
åºåå¶åŸ¡ç¹
patchconstantfunc
äžè§æž¬éçšã®ãã«ã·ã§ãŒããŒã®äŸã次ã«ç€ºããŸãã
struct PatchData { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; PatchData GetPatchData(InputPatch<VIn, 3> Patch, uint PatchId : SV_PrimitiveID) { PatchData output; flloat tessFactor = 2.0f; output.edges[0] = tessFactor; output.edges[1] = tessFactor; output.edges[2] = tessFactor; output.inside = tessFactor; return output; } [domain("tri")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(3)] [patchconstantfunc("GetPatchData")] VIn ProcessHull(InputPatch<VIn, 3> Patch, uint PointId : SV_OutputControlPointID, uint PatchId : SV_PrimitiveID) { return Patch[PointId]; }
ã芧ã®ãšãããäž»ãªäœæ¥ã¯GetPatchDataïŒïŒã§è¡ãããŸãã ãã®ã¿ã¹ã¯ã¯ãããã»ã¬ãŒã·ã§ã³ä¿æ°ã確ç«ããããšã§ãã åŸã§èª¬æããŸãããä»åºŠã¯ãã¡ã€ã³ã·ã§ãŒããŒã«é²ã¿ãŸãã ãã«ã·ã§ãŒããŒããå¶åŸ¡ç¹ãåãåããããã»ã¬ãŒã¿ãŒãã座æšãåãåããŸãã äžè§åœ¢ã®å Žåã®äœçœ®ãŸãã¯ãã¯ã¹ãã£åº§æšã®æ°ããå€ã¯ã次ã®åŒã䜿çšããŠèšç®ããå¿
èŠããããŸã
N = C1 * Fx + C2 * Fy + C3 * Fz
ããã§ãC1ãC2ãããã³C3ã¯å¶åŸ¡ç¹ã®å€ãFã¯ããã»ã¬ãŒã¿ã®åº§æšã§ãã ãŸãããã¡ã€ã³ã·ã§ãŒããŒã§ã¯ãHullã·ã§ãŒããŒã§æå®ãããå€ã«å¯Ÿå¿ããå€ãæã€ãã¡ã€ã³å±æ§ãèšå®ããå¿
èŠããããŸãã ãã¡ã€ã³ã·ã§ãŒããŒã®äŸã次ã«ç€ºããŸãã
cbuffer buff0 : register(b0) { matrix worldViewProj; } struct PatchData { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; [domain("quad")] PIn ProcessDomain(PatchData Patch, float3 Coord : SV_DomainLocation, const OutputPatch<VIn, 3> Tri) { float3 posL = Tri[0].posL * Coord.x + Tri[1].posL * Coord.y + Tri[2].posL * Coord.z; float2 texCoords = Tri[0].texCoords * Coord.x + Tri[1].texCoords * Coord.y + Tri[2].texCoords * Coord.z; PIn output; output.posH = mul(float4(posL, 1.0f), worldViewProj); output.normalW = Tri[0].normalW; output.texCoords = texCoords; return output; }
ãã®å Žåã®é ç¹ã·ã§ãŒããŒã®åœ¹å²ã¯æå°éã«æããããŠããŸã-ç§ã«ãšã£ãŠã¯ãããŒã¿ãæ¬¡ã®æ®µéã«ãæãããã ãã§ãã
次ã«ãåæ§ã®ãã®ãå®è£
ããå¿
èŠããããŸãã ç§ãã¡ã®äž»ãªã¿ã¹ã¯ã¯ãããã»ã¬ãŒã·ã§ã³ä¿æ°ãèšç®ããããšã§ããããæ£ç¢ºã«ã¯ããªãã¶ãŒãã®èº«é·ãžã®äŸåæ§ãæ§ç¯ããŸãã åã³æ¹çšåŒç³»ãæ§ç¯ããŸã

以åãšåãæ¹æ³ã§è§£æ±ºãããšã

ããã§ãTminãšTmaxã¯ããã»ã¬ãŒã·ã§ã³ä¿æ°ã®æå°å€ãšæå€§å€ãHminãšHmaxã¯èŠ³æž¬è
ã®é«ãã®æå°å€ãšæå€§å€ã§ãã ç§ã®æå°ããã»ã¬ãŒã·ã§ã³ä¿æ°ã¯1ã§ãã æå€§å€ã¯ã¬ãã«ããšã«åå¥ã«èšå®ãããŸã
ïŒäŸïŒ1ã2ã4ã16ïŒã
å°æ¥çã«ã¯ãå åã®æé·ãæãè¿ã2ã®ã¹ãä¹ã«å¶éããå¿
èŠããããŸãã
ã€ãŸãã2ã3ã®å€ã®å Žåãå€ã2ã«èšå®ããŸãã4ã7ã®å€ã®å Žåã4ãèšå®ããŸãã8ã15ã®å€ã®å Žåãä¿æ°ã¯8ã«ãªããŸããèŠå 6ã«ã€ããŠãã®åé¡ãè§£ããŸãããããŸããæ¬¡ã®æ¹çšåŒãè§£ã
ãŸãã察æ°ã®
ç¹æ§ã«åŸã£ãŠæ¹çšåŒã®2ã€ã®éšåã®10鲿°ã®å¯Ÿæ°ãåã
ãŸããäž¡æ¹ã®éšåãlogïŒ2ïŒ
ããããããã ãã§ã¯ãããŸããã
Xã¯çŽ2.58ã§ããæ¬¡ã«ãå°æ°éšåããªã»ãããããã¥ãŒã¹ãçµæã®æ°å€ã®ã¹ãä¹ããå¿
èŠããããŸãã詳现ã¬ãã«ã®ããã»ã¬ãŒã·ã§ã³ä¿æ°èšç®ã³ãŒãã¯æ¬¡ã®ãšããã§ã float h = camera->GetHeight(); const RangeF &hR = heightRange; for(LodsStorage::Lod &lod : lods){
7.ãã€ãº
é«ããããã®ãµã€ãºã倿Žããã«ãã©ã³ãã¹ã±ãŒãã®ãã£ããŒã«ãå¢ããæ¹æ³ãèŠãŠã¿ãŸããããæ¬¡ã®ããšãæãæµ®ãã³ãŸã-é«ãã®å€ãã°ã©ããŒã·ã§ã³ãã€ãºãã¯ã¹ãã£ããååŸããå€ã«å€æŽããŸãããµã³ããªã³ã°ãã座æšã¯ãã¡ã€ã³åº§æšã®Nåã«ãªããŸãããã§ãããããšããã¢ãã¬ã¹æå®ã®ãã©ãŒã¿ã€ãïŒD3D11_TEXTURE_ADDRESS_MIRRORïŒã䜿çšãããŸãïŒå³14ãåç
§ïŒã
å³14é«ããããã®ããç+ãã€ãºãããã®ããç=å
šé«ã®ããçãã®å Žåãé«ãã¯æ¬¡ã®ããã«èšç®ãããŸãã
ãããŸã§ã®ãšãããåšæçãªæ§è³ªã¯å€§å¹
ã«è¡šçŸãããŠããŸãããç
§æãšãã¯ã¹ãã£ãªã³ã°ã®è¿œå ã«ãããç¶æ³ã¯ããè¯ãå€åããŸãããããŠãã°ã©ããŒã·ã§ã³ãã€ãºãã¯ã¹ãã£ãšã¯äœã§ããïŒå€§ãŸãã«èšã£ãŠãããã¯ã©ã³ãã ãªå€ã®æ Œåã§ããã©ãã£ã¹ã®ãµã€ãºããã¯ã¹ãã£ã®ãµã€ãºã«åãããæ¹æ³ãèŠãŠã¿ãŸãããããµã€ãº256 x 256ãã¯ã»ã«ã®ãã€ãºãã¯ã¹ãã£ãäœæãããšããŸããã°ãªã«ã®å¯žæ³ããã¯ã¹ãã£ã®ãµã€ãºãšäžèŽããå Žåãããã¯ç°¡åã§ã-ãã¬ãã§ãã¯ã€ããã€ãºã®ãããªãã®ãåŸãããŸããããããã°ãªããã«2 x 2ã®æ¬¡å
ãããå Žåã¯ã©ãã§ããããïŒçãã¯ç°¡åã§ã-è£éã䜿çšããŸããç·åœ¢è£éã®å®åŒåã®1ã€ã¯æ¬¡ã®ãšããã§ãã
ããã¯æéã§ãããåæã«ç§ãã¡ã«ãšã£ãŠã¯æé©ãªãªãã·ã§ã³ã§ã¯ãããŸãããã³ãµã€ã³ããŒã¹ã®è£éã䜿çšããããšããå§ãããŸãã
ãã ãã察è§ç·ã®ç«¯ïŒã»ã«ã®å·Šäžé
ãšå³äžé
ïŒã«æ²¿ã£ãŠå€ãåçŽã«è£éããããšã¯ã§ããŸããããã®å Žåãè£éã2åé©çšããå¿
èŠããããŸããæ Œåã®ã»ã«ã®1ã€ã玹ä»ããŸãããã圌女ã«ã¯4ã€ã®ã³ãŒããŒããããŸããããããV1ãV2ãV3ãV4ãšåŒã³ãŸãããããŸãããã®ã»ã«å
ã«ã¯ç¬èªã®2次å
座æšç³»ãããããã€ã³ãïŒ0ã0ïŒã¯V1ã«å¯Ÿå¿ãããã€ã³ãïŒ1ã1ïŒã¯V3ã«å¯Ÿå¿ããŸãïŒå³15aãåç
§ïŒã座æšïŒ0.5ã0.5ïŒã§å€ãååŸããã«ã¯ãæåã«V1ãšV4ã®éãV2ãšV3ã®éã®2ã€ã®Xè£éå€ãååŸããæåŸã«ãããã®å€ã®éã§Yã«è£éããå¿
èŠããããŸãïŒå³15bïŒã以äžã«äŸã瀺ããŸãã
float2 coords(0.5f, 0.5f) float4 P1 = lerp(V1, V4, coords.x); float4 P2 = lerp(V2, V3, coords.x); float4 P = lerp(P1, P2, coords.y)
å³15a-座æšV1ãV2ãV3ãV4ã®æ Œåã»ã«ã®ç»åãb-ã»ã«ã®äŸã§ã®2ã€ã®è£éã®ã·ãŒã±ã³ã¹ã次ãå®è¡ããŸããã-ãã€ãºãã¯ã¹ãã£ã®ãã¯ã»ã«ããšã«ã2x4ã°ãªããã®è£éå€ãååŸãã4x4ã°ãªããã®è£éå€ã0.5åããŠããã8x4ã°ãªããã®0.25åãªã©ã远å ããŸãã qäžå®ã®å¶é-ããã¯ãªã¯ã¿ãŒãã®è¿œå ãšåŒã°ããŸãïŒå³16ïŒãåŒã¯æ¬¡ã®ãšããã§ãã

å³16ãªã¯ã¿ãŒãã远å ããäŸä»¥äžã«å®è£
äŸã瀺ããŸãã for(int32_t x = 0; x < size.width; x++) for(int32_t y = 0; y < size.height; y++){ float val = 0.0f; Vector2 normPos = {(float)x / (float)(sideSize - 1), (float)y / (float)(sideSize - 1)}; for(int32_t o = 0; o < octavesCnt; o++){ float frequency = powf(2.0f, (float)(startFrequency + o)); float intencity = powf(intencityFactor, (float)o); Vector2 freqPos = normPos * frequency; Point2 topLeftFreqPos = Cast<Point2>(freqPos); Point2 btmRightFreqPos = topLeftFreqPos + Point2(1, 1); float xFrac = freqPos.x - (float)topLeftFreqPos.x; float yFrac = freqPos.y - (float)topLeftFreqPos.y; float iVal = GetInterpolatedValue(topLeftFreqPos, btmRightFreqPos, xFrac, yFrac); val += iVal * intencity; } noiseValues[y * size.width + x] = val; }
ãŸããV1ãV2ãV3ãããã³V4ã®å Žåãæ¬¡ã®ããã«å€èªäœãšãã®è¿åããåèšãååŸã§ããŸãã float GetSmoothValue(const Point2 &Coords) { float corners = (GetValue({Coords.x - 1, Coords.y - 1}) + GetValue({Coords.x + 1, Coords.y - 1}) + GetValue({Coords.x - 1, Coords.y + 1}) + GetValue({Coords.x + 1, Coords.y + 1})) / 16.0f; float sides = (GetValue({Coords.x - 1, Coords.y}) + GetValue({Coords.x + 1, Coords.y}) + GetValue({Coords.x, Coords.y - 1}) + GetValue({Coords.x, Coords.y + 1})) / 8.0f; float center = GetValue(Coords) / 4.0f; return center + sides + corners; }
ãããã®å€ãè£éã«äœ¿çšããŸããã³ãŒãã®æ®ãã¯æ¬¡ã®ãšããã§ãã float GetInterpolatedValue(const Point2 &TopLeftCoord, const Point2 &BottomRightCoord, float XFactor, float YFactor) { Point2 tlCoords(TopLeftCoord.x, TopLeftCoord.y); Point2 trCoords(BottomRightCoord.x, TopLeftCoord.y); Point2 brCoords(BottomRightCoord.x, BottomRightCoord.y); Point2 blCoords(TopLeftCoord.x, BottomRightCoord.y); float tl = (useSmoothValues) ? GetSmoothValue(tlCoords) : GetValue(tlCoords); float tr = (useSmoothValues) ? GetSmoothValue(trCoords) : GetValue(trCoords); float br = (useSmoothValues) ? GetSmoothValue(brCoords) : GetValue(brCoords); float bl = (useSmoothValues) ? GetSmoothValue(blCoords) : GetValue(blCoords); float bottomVal = Math::CosInterpolation(bl, br, XFactor); float topVal = Math::CosInterpolation(tl, tr, XFactor); return Math::CosInterpolation(topVal, bottomVal, YFactor); }
ãµãã»ã¯ã·ã§ã³ã®çµããã«ããããŸã§èª¬æããŠããããšã¯ãã¹ãŠãPerlinã®ãã€ãºã®å®è£
ãæšæºçãªå®è£
ãšã¯å°ãç°ãªãããšãèšããããšæããŸããé«ããèšç®ããŸãããæ¬¡ã«ãæ³ç·ã®åŠçæ¹æ³ãèŠãŠã¿ãŸããããã¡ã€ã³ã®é«ããããã®å Žåãšåæ§ã«ããã€ãºãã¯ã¹ãã£ããæ³ç·ããããçæããå¿
èŠããããŸããæ¬¡ã«ãã·ã§ãŒããŒã§ãã¡ã€ã³ã«ãŒãã®æ³ç·ãšãã€ãºãã¯ã¹ãã£ã®æ³ç·ã远å ããŸããããã¯å®å
šã«æ£ããããã§ã¯ãããŸããããåãå
¥ããããçµæããããããšèšããªããã°ãªããŸããã以äžã«äŸã瀺ããŸãã
8.ããŒããŠã§ã¢ã®ã€ã³ã¹ã¿ã³ã¹å
æé©åãããŸããããæ¬äŒŒã³ãŒãã§ã»ã¯ã¿ãŒãæç»ãããµã€ã¯ã«ã¯æ¬¡ã®ããã«ãªããŸã S V1 V2
ãã®ã¢ãããŒãã®ããã©ãŒãã³ã¹ã¯éåžžã«å°ããã§ããããã€ãã®æé©åãªãã·ã§ã³ããããŸã-åã»ã¯ã¿ãŒã®ã¹ã«ã©ãŒç©ãèšç®ããªãããã«ããã¥ãŒãã®åãã¬ãŒã³ã«ã¯ã¢ããããªãŒãæ§ç¯ã§ããŸãã V1ãšV2ã®å€ã¯ãåã»ã¯ã¿ãŒã§ã¯ãªããããããå±ãããã¥ãŒãã®6ã€ã®å¹³é¢ã«å¯ŸããŠãæŽæ°ã§ããŸãã 3çªç®ã®ãªãã·ã§ã³-InstancingãéžæããŸããããããäœã§ãããã«ã€ããŠç°¡åã«èª¬æããŸããæ£®ãæããããšããŸããããããªãŒã¢ãã«ããããããªãŒã®äœçœ®ãå¯èœãªã¹ã±ãŒãªã³ã°ãŸãã¯å転-倿ãããªãã¯ã¹ã®ã»ããããããŸããã¯ãŒã«ãã¹ããŒã¹ã«å€æããããã¹ãŠã®ããªãŒã®æäžéšãå«ã1ã€ã®ãããã¡ãäœæã§ããŸã-ããã¯è¯ããªãã·ã§ã³ã§ãããã©ã¬ã¹ãã¯ãããäžã§å®è¡ãããŸããããããã倿ãå®è£
ããå¿
èŠãããå Žåã¯ã©ãã§ãããã-ããšãã°ãé¢šã«æºããæšããããè¡ãããšãã§ããŸã-ã¢ãã«ã®é ç¹ã®ããŒã¿ãNå1ã€ã®ãããã¡ãŒã«ã³ããŒããããªãŒã€ã³ããã¯ã¹ïŒ0ããNïŒãé ç¹ããŒã¿ã«è¿œå ããŸããæ¬¡ã«ã倿è¡åã®é
åãæŽæ°ãã倿°ãšããŠã·ã§ãŒããŒã«æž¡ããŸããã·ã§ãŒããŒã§ãããªãŒã€ã³ããã¯ã¹ã«ãã£ãŠç®çã®ãããªãã¯ã¹ãéžæããŸããããŒã¿ã®éè€ãã©ã®ããã«åé¿ã§ããŸããïŒæåã«ããããã®é ç¹ãããã€ãã®ãããã¡ããåéã§ãããšããäºå®ã«æ³šæãåèµ·ããããšæããŸããé ç¹ãèšè¿°ããã«ã¯ãD3D11_INPUT_ELEMENT_DESCæ§é äœã®InputSlotãã£ãŒã«ãã«ãœãŒã¹ã€ã³ããã¯ã¹ãæå®ããå¿
èŠããããŸããããã¯ãã¢ãŒãã£ã³ã°ãã§ã€ã·ã£ã«ã¢ãã¡ãŒã·ã§ã³ãå®è£
ãããšãã«äœ¿çšã§ããŸãã2ã€ã®ãã§ãŒã¹ç¶æ
ãå«ã2ã€ã®é ç¹ãããã¡ãŒãããããããã®å€ãç·åœ¢ã«è£éãããšããŸãããããã説æããæ¹æ³ã¯æ¬¡ã®ãšããã§ããæ¬¡ã«ã倿è¡åã®é
åãæŽæ°ãã倿°ãšããŠã·ã§ãŒããŒã«æž¡ããŸããã·ã§ãŒããŒã§ãããªãŒã€ã³ããã¯ã¹ã«ãã£ãŠç®çã®ãããªãã¯ã¹ãéžæããŸããããŒã¿ã®éè€ãã©ã®ããã«åé¿ã§ããŸããïŒæåã«ããããã®é ç¹ãããã€ãã®ãããã¡ããåéã§ãããšããäºå®ã«æ³šæãåèµ·ããããšæããŸããé ç¹ãèšè¿°ããã«ã¯ãD3D11_INPUT_ELEMENT_DESCæ§é äœã®InputSlotãã£ãŒã«ãã«ãœãŒã¹ã€ã³ããã¯ã¹ãæå®ããå¿
èŠããããŸããããã¯ãã¢ãŒãã£ã³ã°ãã§ã€ã·ã£ã«ã¢ãã¡ãŒã·ã§ã³ãå®è£
ãããšãã«äœ¿çšã§ããŸãã2ã€ã®ãã§ãŒã¹ç¶æ
ãå«ã2ã€ã®é ç¹ãããã¡ãŒãããããããã®å€ãç·åœ¢ã«è£éãããšããŸãããããã説æããæ¹æ³ã¯æ¬¡ã®ãšããã§ããæ¬¡ã«ã倿è¡åã®é
åãæŽæ°ãã倿°ãšããŠã·ã§ãŒããŒã«æž¡ããŸããã·ã§ãŒããŒã§ãããªãŒã€ã³ããã¯ã¹ã«ãã£ãŠç®çã®ãããªãã¯ã¹ãéžæããŸããããŒã¿ã®éè€ãã©ã®ããã«åé¿ã§ããŸããïŒæåã«ããããã®é ç¹ãããã€ãã®ãããã¡ããåéã§ãããšããäºå®ã«æ³šæãåèµ·ããããšæããŸããé ç¹ãèšè¿°ããã«ã¯ãD3D11_INPUT_ELEMENT_DESCæ§é äœã®InputSlotãã£ãŒã«ãã«ãœãŒã¹ã€ã³ããã¯ã¹ãæå®ããå¿
èŠããããŸããããã¯ãã¢ãŒãã£ã³ã°ãã§ã€ã·ã£ã«ã¢ãã¡ãŒã·ã§ã³ãå®è£
ãããšãã«äœ¿çšã§ããŸãã2ã€ã®ãã§ãŒã¹ç¶æ
ãå«ã2ã€ã®é ç¹ãããã¡ãŒãããããããã®å€ãç·åœ¢ã«è£éãããšããŸãããããã説æããæ¹æ³ã¯æ¬¡ã®ãšããã§ããé ç¹ãèšè¿°ããã«ã¯ãD3D11_INPUT_ELEMENT_DESCæ§é äœã®InputSlotãã£ãŒã«ãã«ãœãŒã¹ã€ã³ããã¯ã¹ãæå®ããå¿
èŠããããŸããããã¯ãã¢ãŒãã£ã³ã°ãã§ã€ã·ã£ã«ã¢ãã¡ãŒã·ã§ã³ãå®è£
ãããšãã«äœ¿çšã§ããŸãã2ã€ã®ãã§ãŒã¹ç¶æ
ãå«ã2ã€ã®é ç¹ãããã¡ãŒãããããããã®å€ãç·åœ¢ã«è£éãããšããŸãããããã説æããæ¹æ³ã¯æ¬¡ã®ãšããã§ããé ç¹ãèšè¿°ããã«ã¯ãD3D11_INPUT_ELEMENT_DESCæ§é äœã®InputSlotãã£ãŒã«ãã«ãœãŒã¹ã€ã³ããã¯ã¹ãæå®ããå¿
èŠããããŸããããã¯ãã¢ãŒãã£ã³ã°ãã§ã€ã·ã£ã«ã¢ãã¡ãŒã·ã§ã³ãå®è£
ãããšãã«äœ¿çšã§ããŸãã2ã€ã®ãã§ãŒã¹ç¶æ
ãå«ã2ã€ã®é ç¹ãããã¡ãŒãããããããã®å€ãç·åœ¢ã«è£éãããšããŸãããããã説æããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã D3D11_INPUT_ELEMENT_DESC desc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"POSITION", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 24, D3D11_INPUT_PER_VERTEX_DATA, 0} }
ã·ã§ãŒããŒã§ã¯ãé ç¹ã次ã®ããã«èšè¿°ããå¿
èŠããããŸãã struct VIn { float3 position1 : POSITION0; float3 normal1 : NORMAL0; float2 tex1 : TEXCOORD0; float3 position2 : POSITION1; float3 normal2 : NORMAL1; float2 tex2 : TEXCOORD1; }
次ã«ãå€ãè£éããã ãã§ã float3 res = lerp(input.position1, input.position2, factor);
ãªããããããŠããã®ã§ããïŒ
æšã®äŸã«æ»ããŸãããã2ã€ã®ãœãŒã¹ããé ç¹ãåéããŸããæåã®ãœãŒã¹ã«ã¯ããŒã«ã«ç©ºéã®äœçœ®ããã¯ã¹ãã£åº§æšãæ³ç·ãå«ãŸãã2çªç®ã®ãœãŒã¹ã«ã¯4ã€ã®4次å
ãã¯ãã«ã®åœ¢åŒã®å€æãããªãã¯ã¹ãå«ãŸããŸããé ç¹ã®èª¬æã¯æ¬¡ã®ããã«ãªããŸãã D3D11_INPUT_ELEMENT_DESC desc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"WORLD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1}, }
2çªç®ã®éšåã§ã¯ãInputSlotClassãã£ãŒã«ãã¯D3D11_INPUT_PER_INSTANCE_DATAã§ãããInstanceDataStepRateãã£ãŒã«ãã¯1ã§ããããšã«æ³šæããŠãã ããïŒInstanceDataStepRateãã£ãŒã«ãã®ç°¡åãªèª¬æã«ã€ããŠã¯ãä»é²1ãåç
§ããŠãã ããïŒããã®å Žåãã³ã¬ã¯ã¿ãŒã¯ãã¿ã€ãD3D11_INPUT_PER_INSTANCE_DATAã®ãœãŒã¹ããã®åèŠçŽ ã«å¯ŸããŠãã¿ã€ãD3D11_INPUT_PER_VERTEX_DATAã®ãœãŒã¹ããã®ãããã¡ãŒå
šäœã®ããŒã¿ã䜿çšããŸããã·ã§ãŒããŒã§ã¯ããããã®é ç¹ã¯æ¬¡ã®ããã«èšè¿°ã§ããŸãã struct VIn { float3 posL : POSITION; float3 normalL : NORMAL; float2 tex : TEXCOORD; row_major float4x4 world : WORLD; };
屿§D3D11_USAGE_DYNAMICããã³D3D11_CPU_ACCESS_WRITEã§2çªç®ã®ãããã¡ãŒãäœæããããšã«ãããCPUåŽããæŽæ°ã§ããŸãããã®çš®ã®ãžãªã¡ããªãæç»ããã«ã¯ãDrawInstancedïŒïŒãŸãã¯DrawIndexedInstancedïŒïŒãåŒã³åºãå¿
èŠããããŸããDrawInstancedIndirectïŒïŒããã³DrawIndexedInstancedIndirectïŒïŒãžã®åŒã³åºãããããŸã-ãããã«ã€ããŠã¯ãä»é²2ãåç
§ããŠãã ããããããã¡ã®èšå®ãšDrawIndexedInstancedïŒïŒé¢æ°ã®äœ¿çšäŸã¯æ¬¡ã®ãšããã§ãã
æåŸã«ããããã¯ã«æ»ããŸããããã»ã¯ã¿ãŒãå±ããå¹³é¢äžã®ç¹ãšããã®å¹³é¢ãèšè¿°ãã2ã€ã®ãã¯ãã«ã䜿çšããŠãã»ã¯ã¿ãŒãæåã§èšè¿°ããŸãããããã£ãŠãããŒã¯ã¯2ã€ã®ãœãŒã¹ã§æ§æãããŸãã1ã€ç®ã¯ã°ãªãã空éã®åº§æšã2ã€ç®ã¯ã»ã¯ã¿ãŒããŒã¿ã§ããé ç¹ã®èª¬æã¯æ¬¡ã®ããã«ãªããŸãã std::vector<D3D11_INPUT_ELEMENT_DESC> meta = {
座æšãã°ãªãã空éã«æ ŒçŽããããã«ã3次å
ãã¯ãã«ã䜿çšããŠããããšã«æ³šæããŠãã ããïŒz座æšã¯äœ¿çšãããŸããïŒ9.éå°ã«ãªã³ã°
ãã1ã€ã®éèŠãªæé©åã³ã³ããŒãã³ãã¯ãFrustumã«ãªã³ã°ã§ããå¯èŠæ§ã®ãã©ãããã¯ãã«ã¡ã©ããèŠããã·ãŒã³ã®é åã§ããæ§ç¯æ¹æ³ ãŸãããã€ã³ãã¯4ã€ã®åº§æšç³»ïŒããŒã«ã«ãã¯ãŒã«ãããã¥ãŒãæåœ±ã®å座æšç³»ïŒã«ããå¯èœæ§ãããããšã«æ³šæããŠãã ããããããã®éã®é·ç§»ã¯ããããªãã¯ã¹ãäžçãçš®ãããã³æåœ±ãããªãã¯ã¹ã«ãã£ãŠå®è¡ããã倿ã¯ãããŒã«ã«ããäžçãäžçããçš®ããããŠæåŸã«çš®ããæåœ±ç©ºéã«é çªã«è¡ãããªããã°ãªããŸããããããã®è¡åãä¹ç®ããããšã«ããããããã®ãã¹ãŠã®å€æã1ã€ã«ãŸãšããããšãã§ããŸããéèŠæåœ±æ³ã䜿çšããŸããããã¯ããããããåäžé€ç®ããæå³ããŸãããã¯ãã«ïŒPxãPyãPzã1ïŒã«æåœ±è¡åãä¹ç®ããåŸããã®æåããã®ãã¯ãã«ã®Wæåã«åå²ããŸããæåœ±ç©ºéãžã®ç§»è¡ãšåäžãªåå²ã®åŸããã€ã³ãã¯NDC空éã«è¡šç€ºãããŸããNDC空éã¯3ã€ã®åº§æšxãyãzã®ã»ããã§ããxãšyã¯[-1ã1]ã«å±ããzã¯[0,1]ã«å±ããŸãïŒOpenGLã§ã¯ãã©ã¡ãŒã¿ãŒãå€å°ç°ãªããšèšããªããã°ãªããŸããïŒãããã§ã¯ãåé¡ã®è§£æ±ºã«åãããããŸããããç§ã®å Žåããã©ãããã¯ãã¥ãŒããŒãã«ãããŸãããããèšè¿°ãã6ã€ã®å¹³é¢ãå¿
èŠã§ãïŒå³17aïŒãå¹³é¢ã¯ãæ³ç·ãšãã®å¹³é¢ã«å±ããç¹ã䜿çšããŠèšè¿°ã§ããŸãããŸãããã€ã³ããååŸããŸããã-ããã®ããã«ãNDC空éã§æ¬¡ã®åº§æšã»ãããååŸããŸãã std::vector<Point4F> pointsN = { {-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, 0.0f, 1.0f}, { 1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, -1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, -1.0f, 1.0f, 1.0f} };
æåã®4ç¹ã§zã®å€ã¯0ã§ã-ããã¯ãããããè¿ãã¯ãªããã³ã°å¹³é¢ã«å±ããæåŸã®4ç¹ã§zã1-ããããé ãã¯ãªããã³ã°å¹³é¢ã«å±ããããšãæå³ããŸããæ¬¡ã«ããããã®ãã€ã³ãããã¥ãŒããŒãã«å€æããå¿
èŠããããŸããããããã©ã®ããã«ïŒå®å®é£è¡å£«ã«ã€ããŠã®äŸãèŠããŠãããŠãã ãã-ãããŠãããã¯åãããšã§ããç¹ã«éæåœ±è¡åãæããå¿
èŠããããŸãã確ãã«ããã®åŸãããããã座æšWã§å²ãå¿
èŠããããŸãããã®çµæãå¿
èŠãªåº§æšãååŸããŸãïŒå³17bïŒãããã§ãæ³ç·ãæ±ããŸããã-ãããã¯ãã©ãããå
ã«åããããã¹ããªã®ã§ããã¯ãã«ç©ã®èšç®ã«å¿
èŠãªé åºãéžæããå¿
èŠããããŸãã Matrix4x4 invProj = Matrix4x4::Inverse(camera->GetProjMatrix()); std::vector<Point3F> pointsV; for(const Point4F &pN : pointsN){ Point4F pV = invProj.Transform(pN); pV /= pV.w; pointsV.push_back(Cast<Point3F>(pV)); } planes[0] = {pointsV[0], pointsV[1], pointsV[2]};
å³17å¯èŠæ§ã®ãã©ããããã©ãããã¯æ§ç¯ãããŠããŸã-䜿çšããæãæ¥ãŸããããã©ãããå
ã«åãŸããªãã»ã¯ã¿ãŒã¯æç»ããŸãããã»ã¯ã¿ãŒãå¯èŠæ§ã®ãã©ãããå
ã«ãããã©ããã倿ããããã«ããã®ã»ã¯ã¿ãŒã®äžå¿ã«ããå¢ççã確èªããŸããããã§ã¯æ£ç¢ºãªçµæã¯åŸãããŸãããããã®å Žåãããã€ãã®äœåãªã»ã¯ã¿ãŒãæç»ããããšããäºå®ã«åé¡ã¯ãããŸãããçã®ååŸã¯æ¬¡ã®ããã«èšç®ãããŸãã
ããã§ãTRã¯ã»ã¯ã¿ãŒã®å³äžé
ãBLã¯å·Šäžé
ã§ãããã¹ãŠã®ã»ã¯ã¿ãŒã¯åãé¢ç©ãæã£ãŠãããããååŸãäžåºŠèšç®ããã°ååã§ããã»ã¯ã¿ãŒãèšè¿°ããçäœãå¯èŠæ§ãã©ãããå
ã«ãããã©ãããã©ã®ããã«å€æããŸããïŒãŸããçäœãå¹³é¢ãšäº€å·®ãããã©ããã倿ããå¿
èŠããããŸããããã§ãªãå Žåã¯ãçäœã®ã©ã¡ãåŽããã§ãããã倿ããŸããçã®äžå¿ã«ãããã¯ãã«ãååŸããŸããã
ããã§ãPã¯å¹³é¢äžã®ç¹ãSã¯çã®äžå¿ã§ããæ¬¡ã«ãæ³ç·å¹³é¢ã§ãã®ãã¯ãã«ã®ã¹ã«ã©ãŒç©ãèšç®ããŸããæ¹åã¯ãã¹ã«ã©ãŒç©ã®ç¬Šå·ã䜿çšããŠæ±ºå®ã§ããŸããåè¿°ã®ããã«ãæ£ã®å Žåãçã¯å¹³é¢ã®åã«ãããè² ã®å Žåãçã¯åŸãã«ãããŸããçãå¹³é¢ãšäº€å·®ãããã©ããã倿ããããã«æ®ã£ãŠããŸãã NïŒæ³ç·ãã¯ãã«ïŒãšVã®2ã€ã®ãã¯ãã«ãåããŸããããNããVãžã®ãã¯ãã«ãäœæããŸããããKãšåŒã³ãŸãããããããã£ãŠãKãšæ£åŒã«90床ã®è§åºŠã圢æãããããªé·ãNãèŠã€ããå¿
èŠããããŸãã Kã¯çŽäº€ããŠããŸããïŒãããŠããã¯ãå³18aãèŠãŠãã ãã-çŽè§äžè§åœ¢ã®ããããã£ãã
ãã³ãµã€ã³ãèŠã€ããå¿
èŠãããããšãããããŸããåè¿°ã®ã¹ã«ã©ãŒç©ããããã£ã䜿çšããŠã
äž¡åŽã| V | * | N |ã§é€ç®ããŸãããããŠåŸã
ãã®çµæã䜿çšããŸãïŒ
ãã| V | V | |ããã¯äžã®ã«ããããã¯ããããšãå¯èœã§ãã¡ããã©æ°ã ããæã
ãåŸã
ãã¯ãã«Nãæ£èŠåãããŠããã®ã§ãçµæã®å€ã«ãã£ãŠãæã
ã¯åã«ä¹ç®ããæåŸã®ã¹ããããããã以å€ã®ãã¯ãã«ãæ£èŠåãããªããã°ãªããªã-ãã®å Žåã«ã¯ããã®ãããªæçµæ¹çšåŒã«ãã¯ã¹ïŒ
ã©ãã§Dãããæ°ãããã¯ã¿ãŒã§ãããã®ããã»ã¹ã¯ããã¯ãã«æåœ±ããšåŒã°ããŸãïŒå³18bïŒããããããªããããå¿
èŠãªã®ã§ããããïŒæã
ã¯ããã¯ãã«ã®é·ããšæ¹åã«ãã£ãŠæ±ºå®ããããã®äœçœ®ããå€åããªãããšãç¥ã£ãŠãã-æã
ã¯ãããSãææããããã«Dãé
眮ããå Žåããã®é·ãã¯ãå¹³é¢ïŒris.18sïŒãžSããæå°è·é¢ã«çããããšã¯ããã®ææ®µã
å³.18 a Nã®Vãžã®æåœ±ãbãã€ã³ãã«é©çšãããæåœ±Nã®é·ãã®èŠèŠç衚çŸãsèŠèŠç衚çŸ
Sãäžå¿ãšããçã«é©çšãããæåœ±Nã®é·ãæåœ±ãã¯ãã«ã¯å¿
èŠãªãã®ã§ãé·ããèšç®ããã ãã§ååã§ãã Nãåäœãã¯ãã«ã§ããå ŽåãVã®ã¹ã«ã©ãŒç©ãNã ãã§èšç®ããå¿
èŠããããŸãããã¹ãŠããŸãšãããšãçã®äžå¿ãšå¹³é¢ã®æ³ç·ãšã®ãã¯ãã«ã®ã¹ã«ã©ãŒç©ã®å€ããŒããã倧ããååŸããå°ããå Žåãçã¯æçµçã«å¹³é¢ãšäº€å·®ãããšçµè«ä»ããããšãã§ããŸããã®çãçäœãå¯èŠæ§ã®ãã©ãããã®å
åŽã«ãããšäž»åŒµããããã«ã¯ããããå¹³é¢ã®1ã€ãšäº€å·®ããããåå¹³é¢ã®åã«ããããšã確èªããå¿
èŠããããŸããåã ã¡ã«è³ªåããããšãã§ããŸã-çäœã亀差ãããå°ãªããšã1ã€ã®é£è¡æ©ã®èåŸã«ããå Žåãããã¯ééããªãå¯èŠæ§ã®ãã©ãããã®å€åŽã«ãããŸããã ãããããçäœã®äžå¿ãããã©ããããé
眮ãããŠããã®ãšåã空éãã€ãŸããã¥ãŒã®ç©ºéã«å€æããããšã«æ³šæããŠãã ããã bool Frustum::TestSphere(const Point3F &Pos, float Radius, const Matrix4x4 &WorldViewMatrix) const { Point3F posV = WorldViewMatrix.Transform(Pos); for(const Plane &pl : planes){ Vector3 toSphPos = posV - pl.pos; if(Vector3::Dot(toSphPos, pl.normal) < -Radius) return false; } return true; }
10.ã¯ã©ãã¯
解決ããªããã°ãªããªããã1ã€ã®åé¡ã¯ã詳现ã¬ãã«ã®å¢çã§ã®äºè£ã§ãïŒå³19ïŒã
å³19æ¯èгäºè£ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãŸãã詳现ã¬ãã«ã®å¢çã«ããã»ã¯ã¿ãŒãç¹å®ããå¿
èŠããããŸããäžèŠãããã¯ãªãœãŒã¹éçŽåã®ã¿ã¹ã¯ã®ããã§ã-åã¬ãã«ã®ã»ã¯ã¿ãŒã®æ°ã¯çµ¶ããå€åããŠããããã§ãããã ãã飿¥ããŒã¿ã䜿çšããå Žåããœãªã¥ãŒã·ã§ã³ã¯å€§å¹
ã«ç°¡çŽ åãããŸãã飿¥ããŒã¿ãšã¯äœã§ããïŒåã»ã¯ã¿ãŒã«ã¯4ã€ã®è¿é£ããããŸããããããžã®åç
§ã®ã»ãã-ãã€ã³ã¿ãŒãŸãã¯ã€ã³ããã¯ã¹-飿¥ããŒã¿ã§ãã圌ãã®å©ããåããŠãã©ã®ã»ã¯ã¿ãŒãåœå¢ã«ããããç°¡åã«å€æã§ããŸã-é£äººãã©ã®ã¬ãã«ã«å±ããŠãããã確èªããã ãã§ããããŠãåã»ã¯ã¿ãŒã®é£äººãèŠã€ããŸããããç¹°ãè¿ããŸããããã¹ãŠã®ã»ã¯ã¿ãŒãã«ãŒãããå¿
èŠã¯ãããŸãããã°ãªãã空éã®X座æšãšY座æšãæã€ã»ã¯ã¿ãŒã§äœæ¥ããŠãããšæ³åããŠãã ãããç«æ¹äœã®ç«¯ã«è§Šããªãå Žåããã®é£ã®åº§æšã¯æ¬¡ã®ããã«ãªããŸãïŒäžããã®é£äºº-ïŒXãY-1ïŒäžããã®é£äºº-ïŒXãY + 1ïŒå·Šããã®é£äºº-ïŒX-1ãYïŒå³ããã®é£äºº-ïŒX + 1ãYïŒã»ã¯ã¿ãŒãrib骚ã«è§Šããå Žåããã®ç¹å¥ãªå®¹åšãå
¥ããŸãã6ã€ã®é¢ãã¹ãŠãåŠçããåŸããã¥ãŒãã®ãã¹ãŠã®å¢çã»ã¯ã¿ãŒãå«ãŸããŸãããã®ã³ã³ããã§ã¯ãæŽçããå¿
èŠããããŸããäºåã«ãåã»ã¯ã¿ãŒã®ãšããžãèšç®ããŸãã struct SectorEdges { CubeSectors::Sector *owner; typedef std::pair<Point3F, Point3F> Edge; Edge edges[4]; }; std::vector<SectorEdges> sectorsEdges;
次ã¯ãã¹ããã®ãã®ã§ã for(SectorEdges &edgs : sectorsEdges) for(size_t e = 0; e < 4; e++) if(edgs.owner->adjacency[e] == nullptr) FindSectorEdgeAdjacency(edgs, (AdjacencySide)e, sectorsEdges);
FindSectorEdgeAdjacencyïŒïŒé¢æ°ã¯æ¬¡ã®ããã«ãªããŸã void CubeSectors::FindSectorEdgeAdjacency(SectorEdges &Sector, CubeSectors::AdjacencySide Side, std::vector<SectorEdges> &Neibs) { SectorEdges::Edge &e = Sector.edges[Side]; for(SectorEdges &edgs2 : Neibs){ if(edgs2.owner == Sector.owner) continue; for(size_t e = 0; e < 4; e++){ SectorEdges::Edge &e2 = edgs2.edges[e]; if((Math::Equals(e.first, e2.first) && Math::Equals(e.second, e2.second)) || (Math::Equals(e.second, e2.first) && Math::Equals(e.first, e2.second))) { Sector.owner->adjacency[Side] = edgs2.owner; edgs2.owner->adjacency[e] = Sector.owner; return; } } } }
2ã€ã®ã»ã¯ã¿ãŒã®é£æ¥ããŒã¿ãæŽæ°ããããšã«æ³šæããŠãã ãã-ç®çã®ïŒã»ã¯ã¿ãŒïŒãšèŠã€ãã£ã飿¥ã次ã«ã飿¥ããŒã¿ã䜿çšããŠã詳现ã¬ãã«ã®å¢çã«å±ããã»ã¯ã¿ãŒã®ãšããžãèŠã€ããå¿
èŠããããŸãããã®ãããªèšç»-ã¬ã³ããªã³ã°ããåã«ãå¢çã»ã¯ã¿ãŒãèŠã€ããŸããæ¬¡ã«ãåã»ã¯ã¿ãŒã®ã€ã³ã¹ã¿ã³ã¹ãããã¡ãŒã«ãäž»ãªæ
å ±ã«å ããŠã飿¥ã»ã¯ã¿ãŒã®ããã»ã¬ãŒã·ã§ã³ä¿æ°ãšããã»ã¬ãŒã·ã§ã³ä¿æ°ã®4次å
ãã¯ãã«ãæžã蟌ã¿ãŸããé ç¹ã®èª¬æã¯æ¬¡ã®ããã«ãªããŸãã std::vector<D3D11_INPUT_ELEMENT_DESC> meta = {
詳现ã¬ãã«ã§ã»ã¯ã¿ãŒãå²ãåœãŠãåŸãåã»ã¯ã¿ãŒã®é£æ¥ããã»ã¬ãŒã·ã§ã³ä¿æ°ã決å®ããŸãã for(LodsStorage::Lod &lod : lods){ const std::vector<Sector*> §ors = lod.GetSectors(); bool lastLod = lod.GetInd() == lods.GetCount() - 1; for(Sector *s : sectors){ int32_t tessFacor = s->GetTessFactor(); s->GetBorderTessFactor() = { GetNeibTessFactor(s, Sector::ADJ_BOTTOM, tessFacor, lastLod), GetNeibTessFactor(s, Sector::ADJ_LEFT, tessFacor, lastLod), GetNeibTessFactor(s, Sector::ADJ_TOP, tessFacor, lastLod), GetNeibTessFactor(s, Sector::ADJ_RIGHT, tessFacor, lastLod) }; } }
飿¥ããããã»ã¬ãŒã·ã§ã³ä¿æ°ãæ€çŽ¢ãã颿°ïŒ float Terrain::GetNeibTessFactor(Sector *Sec, Sector::AdjacencySide Side, int32_t TessFactor, bool IsLastLod) { Sector *neib = Sec->GetAdjacency()[Side]; int32_t neibTessFactor = neib->GetTessFactor(); return (neibTessFactor < TessFactor) ? (float)neibTessFactor : 0.0f; }
ãŒããè¿ãå Žåããµã€ãåŽã®é£äººã¯ç§ãã¡ã«ãšã£ãŠé¢å¿ããããŸãããå
ã«é²ã¿ãããã»ã¬ãŒã·ã§ã³ä¿æ°ã倧ããã¬ãã«ã®åŽé¢ããäºè£ãé€å»ããå¿
èŠããããšèšããŸããã·ã§ãŒããŒã«æž¡ããŸãããããŸããããã»ã¬ãŒã¿ã®åº§æšã䜿çšããŠã°ãªãã座æšãååŸããå¿
èŠãããããšãæãåºãããŠãã ãããæ¬¡ã«ããããã®åº§æšãç«æ¹äœã®ç«¯ã®ç¹ã«å€æããããã®ç¹ãæ£èŠåãããŸã-ããã§ãçäžã®ç¹ãã§ããŸããã float3 p = Tri[0].netPos * Coord.x + Tri[1].netPos * Coord.y + Tri[2].netPos * Coord.z; float3 planePos = Tri[0].startPos + Tri[0].vec1 * px * gridStep.x + Tri[0].vec2 * py * gridStep.y; float3 sphPos = normalize(planePos);
ãŸããé ç¹ãã°ãªããã®æåãŸãã¯æåŸã®è¡ã«å±ããŠããããæåãŸãã¯æåŸã®åã«å±ããŠãããã調ã¹ãå¿
èŠããããŸãããã®å Žåãé ç¹ã¯ã»ã¯ã¿ãŒã®ç«¯ã«å±ããŸããããããããã§ã¯ååã§ã¯ãããŸãããé ç¹ã詳现ã¬ãã«ã®å¢çã«å±ããŠãããã©ããã倿ããå¿
èŠããããŸãããããè¡ãããã«ã飿¥ã»ã¯ã¿ãŒã«é¢ããæ
å ±ããŸãã¯ããããããã®ãã»ã¬ãŒã·ã§ã³ã¬ãã«ã䜿çšããŸãã float4 bTf = Tri[0].borderTessFactor; bool isEdge = (bTf.x != 0.0f && py == 0.0f) ||
çŸåšãäž»ãªæ®µéã¯å®éã«ã¯äºè£ã®é€å»ã§ããå³20ãã芧ãã ãããèµ€ãç·ã¯ã2çªç®ã®è©³çްã¬ãã«ã«å±ããããŒã¯ã®ãšããžã§ãã 2æ¬ã®éãç·-3çªç®ã®è©³çްã¬ãã«ã®å¢çã V3ã¯èµ€ãç·ã«å±ããŠããå¿
èŠããããŸã-ã€ãŸãã第2ã¬ãã«ã®å±æ©ã«onããŠããŸããé«ãV1ãšV2ã¯äž¡æ¹ã®ã¬ãã«ã§çãããããV3ã¯ãããã®éã®ç·åœ¢è£éã«ãã£ãŠèŠã€ããããšãã§ããŸã
å³20ç·ã®åœ¢ã§äºè£ã圢æããé¢ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãããŸã§ã®ãšãããV1ãšV2ãä¿æ°FããããŸããããŸãããã€ã³ãV3ã®ã€ã³ããã¯ã¹ãèŠã€ããå¿
èŠããããŸããã€ãŸããã°ãªããã®ãµã€ãºã32 x 32ã§ãããã»ã¬ãŒã·ã§ã³ä¿æ°ã4ã®å Žåããã®ã€ã³ããã¯ã¹ã¯0ã128ïŒ32 * 4ïŒã«ãªããŸããã°ãªãã空épã«ã¯ãã§ã«åº§æšããããŸã-ãã®äŸã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãããšãã°ïŒ15.5ã16ïŒã«ãªããŸããã€ã³ããã¯ã¹ãååŸããã«ã¯ã座æšpã®1ã€ã«ããã»ã¬ãŒã·ã§ã³ä¿æ°ãä¹ç®ããŸãããŸããé¡ã®å§ãŸããšãã®çµãããžã®æ¹åãã€ãŸãã»ã¯ã¿ãŒã®ã³ãŒããŒã®1ã€ãå¿
èŠã§ãã float edgeVertInd = 0.0f; float3 edgeVec = float3(0.0f, 0.0f, 0.0f); float3 startPos = float3(0.0f, 0.0f, 0.0f); uint neibTessFactor = 0; if(bTf.x != 0.0f && py == 0.0f){
次ã«ãV1ãšV2ã®ã€ã³ããã¯ã¹ãèŠã€ããå¿
èŠããããŸããæ°åã®3ããããšããŸãã2ã®åæ°ã§ãã2ã€ã®æãè¿ãæ°åãèŠã€ããå¿
èŠããããŸãããããè¡ãã«ã¯ã3ã2ã§å²ã£ãäœããèšç®ããŸãïŒ1ã«çããïŒã次ã«ããã®å°äœã3ã«æžç®ãŸãã¯å ç®ããŠãç®çã®çµæãååŸããŸãããŸããã€ã³ããã¯ã¹ã§ã¯ã2ã€ã§ã¯ãªãã詳现ã¬ãã«ã®ããã»ã¬ãŒã·ã§ã³ä¿æ°ã®æ¯çããããŸããã€ãŸãã3çªç®ã®ã¬ãã«ã®ä¿æ°ã16ã§ã2çªç®ã®ã¬ãã«2ã®ä¿æ°ã8ã®å Žåãæ¯çã¯8ã«ãªããŸããããã§ãé«ããååŸããã«ã¯ããŸãçã®å¯Ÿå¿ãããã€ã³ããååŸãããšããžã®ãã€ã³ããæ£èŠåããå¿
èŠããããŸãããªãã®å§ç¹ãšæ¹åã¯ãã§ã«æºåãããŠããŸããV1ããV2ãŸã§ã®ãã¯ãã«ã®é·ããèšç®ããããšã¯æ®ã£ãŠããŸããå
ã®ã¡ãã·ã¥ã»ã«ã®ãšããžã®é·ãã¯gridStep.xã§ãããããå¿
èŠãªé·ãã¯gridStep.x / Tri [0] .tessFactorã§ããæ¬¡ã«ãåè¿°ã®ããã«ãçäœã®ãã€ã³ãã§é«ããååŸããŸãã float GetNeibHeight(float3 EdgeStartPos, float3 EdgeVec, float VecLen, float3 NormOffset) { float3 neibPos = EdgeStartPos + EdgeVec * VecLen; neibPos = normalize(neibPos); return GetHeight(neibPos, NormOffset); } float vertOffset = gridStep.x / Tri[0].tessFactor; uint tessRatio = (uint)tessFactor / (uint)neibTessFactor; uint ind = (uint)edgeVertInd % tessRatio; uint leftNeibInd = (uint)edgeVertInd - ind; float leftNeibHeight = GetNeibHeight(startPos, edgeVec, vertOffset * leftNeibInd, normOffset); uint rightNeibInd = (uint)edgeVertInd + ind; float rightNeibHeight = GetNeibHeight(startPos, edgeVec, vertOffset * rightNeibInd, normOffset);
ããŠãææ°ã®ã³ã³ããŒãã³ãã¯ä¿æ°Fã§ããé€ç®ã®æ®ããä¿æ°ã®æ¯ïŒindïŒã§é€ç®ããä¿æ°ã®æ¯ïŒtessRatioïŒã§é€ç®ããããšã§åŸãããŸãã float factor = (float)ind / (float)tessRatio;
æçµæ®µé-é«ãã®ç·åœ¢è£éãšæ°ããé ç¹ã®ååŸ float avgHeight = lerp(leftNeibHeight, rightNeibHeight, factor); posL = sphPos * (sphereRadius + avgHeight);
ã»ã¯ã¿ãŒã®å¢çã1ãŸãã¯0ã«çãããšããžã®ãã¯ã¹ãã£åº§æšã«ããå Žæã«ãäºè£ãçºçããå ŽåããããŸãããã®å Žåã2ã€ã®åº§æšã®é«ãã®å¹³åå€ãååŸããŸãã float GetHeight(float2 TexCoords) { float2 texCoords2 = TexCoords * texCoordsScale; float mHeight = mainHeightTex.SampleLevel(mainHeightTexSampler, TexCoords, 0).x; float dHeight = distHeightTex.SampleLevel(distHeightTexSampler, texCoords2, 0).x; return (mHeight + dHeight) * maxTerrainHeight; } float GetHeight(float3 SphPos, float3 NormOffset) { float2 texCoords1 = GetTexCoords(SphPos, NormOffset); float height = GetHeight(texCoords1); if(texCoords1.x == 1.0f){ float height2 = GetHeight(float2(0.0f, texCoords1.y)); return lerp(height, height2, 0.5f); }else if(texCoords1.x == 0.0f){ float height2 = GetHeight(float2(1.0f, texCoords1.y)); return lerp(height, height2, 0.5f); }else return height; }
11. GPUã§ã®åŠç
ã»ã¯ã¿ãŒã®åŠçãGPUã«è»¢éããŸãããã 2ã€ã®ã³ã³ãã¥ãŒãã·ã§ãŒããŒããããŸãã1ã€ç®ã¯å¯èŠæ§ãã©ããããåãåãã詳现ã¬ãã«ã決å®ãã2ã€ç®ã¯å¢çããã»ã¬ãŒã·ã§ã³ä¿æ°ãåãåã£ãŠã¯ã©ãã¯ãé€å»ããŸãã CPUã®å Žåã®ããã«ãåæãããŸã§ã»ã¯ã¿ãŒã®é£æ¥ãæ£ãã倿ã§ããªãããã2段éã«åããå¿
èŠããããŸããäž¡æ¹ã®ã·ã§ãŒããŒã¯è©³çްã¬ãã«ã®ããŒã¿ã䜿çšããã»ã¯ã¿ãŒãåŠçãããããã»ã¯ã¿ãŒãšãããã®2ã€ã®äžè¬çãªæ§é ãå°å
¥ããŸããã struct Sector { float3 vec1, vec2; float3 startPos; float3 normCenter; int adjacency[4]; float borderTessFactor[4]; int lod; }; struct Lod { RangeF dotRange; float tessFactor; float padding; float4 color; };
å
¥åïŒã»ã¯ã¿ãŒã«é¢ããåææ
å ±ãå«ãïŒãäžéïŒæåã®æ®µéã®çµæãšããŠååŸãããã»ã¯ã¿ãŒã®ããŒã¿ãå«ãïŒãæçµïŒã¬ã³ããªã³ã°ã«è»¢éãããŸãïŒã®3ã€ã®ã¡ã€ã³ãããã¡ãŒã䜿çšããŸããå
¥åãããã¡ãŒã®ããŒã¿ã¯å€æŽãããªããããD3D11_BUFFER_DESCæ§é äœã®Usageãã£ãŒã«ãã«å€D3D11_USAGE_IMMUTABLEã䜿çšããã®ãåççã§ãããã¹ãŠã®ã»ã¯ã¿ãŒã®ããŒã¿ãæžã蟌ãã ãã§ã飿¥ããŒã¿ã«ã¯ã»ã¯ã¿ãŒãã€ã³ã¿ãŒã§ã¯ãªãã»ã¯ã¿ãŒã€ã³ããã¯ã¹ã䜿çšããŸãã詳现ã¬ãã«ã®ã€ã³ããã¯ã¹ãšããã»ã¬ãŒã·ã§ã³ã®å¢çä¿æ°ã«ã¯ããŒãå€ãèšå®ããŸãã static const size_t sectorSize = sizeof(Vector3) +
次ã«ãäžéãããã¡ã«ã€ããŠå°ã説æããŸããæåã®ã·ã§ãŒããŒã®åºåãš2çªç®ã®ã·ã§ãŒããŒã®å
¥åãšãã2ã€ã®åœ¹å²ãæãããŸãããããã£ãŠãBindFlagsãã£ãŒã«ããD3D11_BIND_UNORDERED_ACCESSã«èšå®ããŸããD3D11_BIND_SHADER_RESOURCEããŸããã·ã§ãŒããŒãäœæ¥çµæãæžã蟌ãããšãã§ããUnorderedAccessViewãšããããã¡ãŒãå
¥åãšããŠäœ¿çšããShaderResourceViewã®2ã€ã®ãã£ã¹ãã¬ã€ãäœæããŸãããã®ãµã€ãºã¯ã以åã«äœæãããå
¥åãããã¡ãšåãã«ãªããŸã UINT miscFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; intermediateData = Utils::DirectX::CreateBuffer( sectors.GetSectors().size() * sectorSize,
次ã«ãæåã®ã·ã§ãŒããŒã®äž»ãªæ©èœã瀺ããŸãã StructuredBuffer<Sector> inputData : register(t0); RWStructuredBuffer<Sector> outputData : register(u0); [numthreads(1, 1, 1)] void Process( int3 TId : SV_DispatchThreadID ) { int ind = TId.x; Sector sector = inputData[ind]; float dotVal = dot(toWorldPos, sector.normCenter); if(dotVal < dotRange.minVal || dotVal > dotRange.maxVal){ outputData[ind] = sector; return; } if(!IsVisible(sector.normCenter)){ outputData[ind] = sector; return; } for(int l = 0; l < 4; l++){ Lod lod = lods[l]; if(dotVal >= lod.dotRange.minVal && dotVal <= lod.dotRange.maxVal) sector.lod = l + 1; } outputData[ind] = sector; }
ã¹ã«ã©ãŒç©ãèšç®ããåŸãã»ã¯ã¿ãŒãæœåšçã«èŠããé åã«ãããã©ããã確èªããŸããæ¬¡ã«ãåã«ç€ºããFrustum :: TestSphereïŒïŒåŒã³åºããšåäžã®IsVisibleïŒïŒåŒã³åºãã䜿çšããŠããã®å¯èŠæ§ã®äºå®ãæç¢ºã«ããŸãã颿°ã®æäœã¯ã倿°worldViewãsphereRadiusãfrustumPlanesPosVãããã³frustumPlanesNormalsVã«äŸåããŸãããããã®å€ã¯ãäºåã«ã·ã§ãŒããŒã«æž¡ãå¿
èŠããããŸããæ¬¡ã«ã詳现ã¬ãã«ã決å®ããŸããåäžããã®ã¬ãã«ã€ã³ããã¯ã¹ã瀺ããŠããããšã«æ³šæããŠãã ãããããã¯ã第2段éã§è©³çްã¬ãã«ããŒãã®ã»ã¯ã¿ãŒãç Žæ£ããããã«å¿
èŠã§ããæ¬¡ã«ã第2段éã®ãããã¡ãŒãæºåããå¿
èŠããããŸãã Computeã·ã§ãŒããŒã®åºåãšããã»ã¬ãŒã¿ãŒã®å
¥åãšããŠãããã¡ãŒã䜿çšããŸã-ãã®ãããBindFlagsãã£ãŒã«ãã§å€D3D11_BIND_UNORDERED_ACCESSãæå®ããå¿
èŠããããŸã| D3D11_BIND_VERTEX_BUFFERããããã¡ããŒã¿ãçŽæ¥æäœããå¿
èŠããããããMiscFlagsãã£ãŒã«ãã«å€D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWSãæå®ããŸãããã®ãããªãããã¡ã衚瀺ããã«ã¯ãFlagsãã£ãŒã«ãã«DXGI_FORMAT_R32_TYPELESSå€ã䜿çšããNumElementsãã£ãŒã«ãã«4ã€ã®ãããã¡ãã¹ãŠã瀺ããŸã size_t instancesByteSize = instanceByteSize * sectors.GetSectors().size(); outputData = Utils::DirectX::CreateBuffer(instancesByteSize, D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DEFAULT, 0, D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS, 0); D3D11_BUFFER_UAV uavParams = {0, instancesByteSize / 4, D3D11_BUFFER_UAV_FLAG_RAW}; outputUAW = Utils::DirectX::CreateUnorderedAccessView(outputData, uavParams, DXGI_FORMAT_R32_TYPELESS);
ã«ãŠã³ã¿ãŒãå¿
èŠã«ãªããŸããããã䜿çšããŠãã·ã§ãŒããŒã®ã¡ã¢ãªãã¢ãã¬ã¹æå®ããDrawIndexedInstancedïŒïŒåŒã³åºãã®instanceCountåŒæ°ã§ãã®æçµå€ã䜿çšããŸããã«ãŠã³ã¿ãŒããµã€ãºã16ãã€ãã®ãããã¡ãŒãšããŠå®è£
ããŸããããŸããD3D11_BUFFER_UAVãã£ãŒã«ãã®Flagsãã£ãŒã«ãã«è¡šç€ºãäœæãããšãã«ãå€D3D11_BUFFER_UAV_FLAG_COUNTERã䜿çšããŸãã counter = Utils::DirectX::CreateBuffer(sizeof(UINT), D3D11_BIND_UNORDERED_ACCESS, D3D11_USAGE_DEFAULT, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, 4); D3D11_BUFFER_UAV uavParams = {0, 1, D3D11_BUFFER_UAV_FLAG_COUNTER}; counterUAW = Utils::DirectX::CreateUnorderedAccessView(counter, uavParams);
2çªç®ã®ã·ã§ãŒããŒã³ãŒãã䜿çšããŸã StructuredBuffer<Sector> inputData : register(t0); RWByteAddressBuffer outputData : register(u0); RWStructuredBuffer<uint> counter : register(u1); [numthreads(1, 1, 1)] void Process( int3 TId : SV_DispatchThreadID ) { int ind = TId.x; Sector sector = inputData[ind]; if(sector.lod != 0){ sector.borderTessFactor[0] = GetNeibTessFactor(sector, 0);
GetNeibTessFactorïŒïŒé¢æ°ã®ã³ãŒãã¯ã察å¿ããCPUãšã»ãŒåãã§ããå¯äžã®éãã¯ãè¿ââé£ãžã®ãã€ã³ã¿ã§ã¯ãªãè¿é£ã®ã€ã³ããã¯ã¹ã䜿çšããããšã§ããoutputDataãããã¡ãŒã¯RWByteAddressBufferåã§ãããããStoreã¡ãœããïŒuintã¢ãã¬ã¹ãuintå€ïŒã䜿çšããŠæäœããŸããdataSize倿°ã®å€ã¯ãD3D11_INPUT_PER_INSTANCE_DATAã¯ã©ã¹ã®é ç¹ããŒã¿ã®ãµã€ãºãšçãããé ç¹ã®èª¬æã¯ã»ã¯ã·ã§ã³10ã«ãããŸããäžè¬ã«ãããã¯C / C ++ã®ãã€ã³ã¿ãŒã䜿çšããåŸæ¥ã®äœæ¥ã§ãã2ã€ã®ã·ã§ãŒããŒãå®è¡ããåŸãoutputDataãInstanceBufferãšããŠäœ¿çšã§ããŸããã¬ã³ããªã³ã°ããã»ã¹ã¯æ¬¡ã®ããã«ãªããŸã Utils::DirectX::SetPrimitiveStream({vb, outputData}, ib, {vertexSize, instanceByteSize}, D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST); DeviceKeeper::GetDeviceContext()->CopyStructureCount(indirectArgs, 4, counterUAW); Shaders::Apply(terrainShaders, [&]() { DeviceKeeper::GetDeviceContext()->DrawIndexedInstancedIndirect(indirectArgs, 0); }); Utils::DirectX::SetPrimitiveStream({nullptr, nullptr}, nullptr, {0, 0});
DrawIndexedInstancedIndirectïŒïŒããã³CopyStructureCountïŒïŒã¡ãœããã®è©³çްã«ã€ããŠã¯ãä»é²2ãåç
§ããŠãã ããã12.ã«ã¡ã©
ç°¡åãªFPSïŒãã¡ãŒã¹ãããŒãœã³ã·ã¥ãŒã¿ãŒïŒã«ã¡ã©ãã¢ãã«åããæ¹æ³ã¯ãåãã§ããããç§ã¯ãã®ã·ããªãªã«åŸã£ãŠè¡åããŸãïŒ- 1. 2ã€ã®è§åºŠããæ¹åãã¯ãã«ãååŸããŸã
- 2.æ¹åãã¯ãã«ãšãã¯ãã«ïŒ0ã1ã0ïŒã䜿çšããŠãåºåºãååŸããŸã
- 3.æé 2ã§ååŸããæ¹åãã¯ãã«ãšå³ã®ãã¯ãã«ã«åŸã£ãŠãã«ã¡ã©ã®äœçœ®ã倿ŽããŸã
ç§ãã¡ã®å Žåãç¶æ³ã¯ããè€éã§ã-æåã«ãææã®äžå¿ã«å¯ŸããŠç§»åããå¿
èŠãããã2çªç®ã«ããã¯ãã«ïŒ0ã1ã0ïŒã®ä»£ããã«åºåºãæ§ç¯ãããšãã«ãçŸåšã®ç¹ã§çã®æ³ç·ã䜿çšããå¿
èŠããããŸããæãŸããçµæãéæããããã«ã2ã€ã®ããŒã¹ã䜿çšããŸããåè
ã«ããã°ãäœçœ®ãå€ãããåŸè
ã¯ã«ã¡ã©ã®åãã説æããŸããåºåºã¯çžäºäŸåããŠããŸãããæåã«äœçœ®ã®åºåºãèšç®ãããããããããå§ããŸããåæäœçœ®ããŒã¹ïŒpDirãpUpãpRightïŒãšãè·é¢ãç§»åããæ¹åãã¯ãã«vDirããããšããŸãããŸããvDirã®æåœ±ãpDirããã³pRightã§èšç®ããå¿
èŠããããŸãããããã远å ãããšãæŽæ°ãããæ¹åãã¯ãã«ãåŸãããŸãïŒå³21ïŒã
å³21 projDirãååŸããããã®èŠèŠçãªããã»ã¹æ¬¡ã«ããã®ãã¯ãã«
ã«æ²¿ã£ãŠç§»åããŸããPã¯ã«ã¡ã©ã®äœçœ®ãmFãšmSã¯ä¿æ°ã§ããããã¯ãåæ¹ãŸãã¯åŽæ¹ã«ç§»åããå¿
èŠãããéãæå³ããŸããPNã¯çäœã«å±ããªããããPNãæ°ããã«ã¡ã©äœçœ®ãšããŠäœ¿çšããããšã¯ã§ããŸããã代ããã«ããã€ã³ãPNã§çã®æ³ç·ãèŠã€ãããã®æ³ç·ã¯ãã¯ãã«upã®æ°ããå€ã«ãªããŸããä»ãç§ãã¡ã¯æŽæ°ãããåºç€ã圢æããããšãã§ããŸã Vector3 nUp = Vector3::Normalize(PN - spherePos); Vector3 nDir = projDir Vector3 nRight = Vector3::Normalize(Vector3::Cross(pUp, pDir))
ããã§ãspherePosã¯çã®äžå¿ã§ããåãã¯ãã«ãä»ã®2ã€ã®ãã¯ãã«ã«çŽäº€ãããå¿
èŠããããŸãããã¯ãã«ç©ã®ç¹æ§ã«åŸã£ãŠãnRightã¯ãã®æ¡ä»¶ãæºãããŸãã nUpãšnDirã§åãããšãéæããããã«æ®ã£ãŠããŸãããããè¡ãã«ã¯ãnDirãnUpã«æåœ±ããçµæã®ãã¯ãã«ãnDirããæžç®ããŸãïŒå³22ïŒãå³22
nUpã«å¯ŸããnDirã®çŽäº€ånUpã§ãåãããšãã§ããŸãããæ¹åãå€ããããããã®å Žåã¯åãå
¥ããããŸãããæ¬¡ã«ãnDirãæ£èŠåããæ¹åã®æŽæ°ãããæ£èŠçŽäº€åºåºãååŸããŸãã2çªç®ã®éèŠãªã¹ãããã¯ããªãªãšã³ããŒã·ã§ã³ã®åºç€ãæ§ç¯ããããšã§ããäž»ãªåé¡ã¯ãæ¹åãã¯ãã«ãååŸããããšã§ããæãé©åãªè§£æ±ºçã¯ã極è§aãæ¹äœè§bãããã³åç¹ããã®è·é¢ã1ã«çããç¹ãçé¢åº§æšãããã«ã«ã座æšã«å€æããããšã§ããæ¥µè§ããŒãã«çãããã€ã³ãã«å¯ŸããŠãã®ãããªé·ç§»ãè¡ãå Žåã«ã®ã¿ããã¯ãã«ãèŠäžããããŸããè§åºŠãã€ã³ã¯ãªã¡ã³ããããã®ãããªãã¯ãã«ãåæ¹ãåããšä»®å®ãããããããã¯ç§ãã¡ã«ã¯å®å
šã«é©ããŠããŸããã 90床ã®éåžžã®è§åºŠã·ããã§åé¡ã¯è§£æ±ºããŸãããè§åºŠã·ããã«ãŒã«ã䜿çšãããšãããšã¬ã¬ã³ãã«
ãªããŸãããã®çµæã次
ãåŸãããŸããããã§ãaã¯æ¥µè§ãbã¯æ¹äœè§ã§ãããã®çµæã¯ãç§ãã¡ã«å®å
šã«é©ããŠããããã§ã¯ãããŸãã-äœçœ®ã«åºã¥ããŠæ¹åãã¯ãã«ãæ§ç¯ããå¿
èŠããããŸãã vDirã®æ¹çšåŒãæžãçŽããŸãããã
å®å®é£è¡å£«ã®ãããªãã®ã¯ãã¹ãŠããã®æ¹åã«éåžžã«å€ãããã®æ¹åã«éåžžã«å€ãã®ãã®ãæã£ãŠããŸããããã§ãæšæºåºåºã®ãã¯ãã«ãpDirãpUpãããã³pRightã«çœ®ãæãããšãå¿
èŠãªæ¹åãåŸãããããšã¯æããã§ãããã®ããã«
åãããšãè¡åä¹ç®ã®åœ¢ã§æ³åã§ããŸããã
ãã¯ãã«vUpã¯æåã¯pUpãšçãããªããŸãã vUpãšvDirã®ãã¯ãã«ç©ãèšç®ããããšã§vRightãååŸããvUpã
æ®ãã®åºåºãã¯ãã«ã«çŽäº€ãããŸããåçã¯nDirã䜿çšãããšããšåãã§
ãããŒã¹ãèŠã€ããŸãã-ã«ã¡ã©ã®äœçœ®ãèšç®ããããã«æ®ã£ãŠããŸããããã¯
ãspherePosãçäœã®äžå¿ãsphereRadiusãçäœã®ååŸãheightãçäœã®è¡šé¢ããã®é«ãã§ããå Žåã«è¡ãããŸãã説æããã«ã¡ã©ã®ã³ãŒãã瀺ããŸãã float moveFactor = 0.0f, sideFactor = 0.0f, heightFactor = 0.0f; DirectInput::GetInsance()->ProcessKeyboardDown({ {DIK_W, [&](){moveFactor = 1.0f;}}, {DIK_S, [&](){moveFactor = -1.0f;}}, {DIK_D, [&](){sideFactor = 1.0f;}}, {DIK_A, [&](){sideFactor = -1.0f;}}, {DIK_Q, [&](){heightFactor = 1.0f;}}, {DIK_E, [&](){heightFactor = -1.0f;}} }); if(moveFactor != 0.0f || sideFactor != 0.0f){ Vector3 newDir = Vector3::Normalize(pDir * Vector3::Dot(pDir, vDir) + pRight * Vector3::Dot(pRight, vDir)); Point3F newPos = pos + (newDir * moveFactor + pRight * sideFactor) * Tf * speed; pDir = newDir; pUp = Vector3::Normalize(newPos - spherePos); pRight = Vector3::Normalize(Vector3::Cross(pUp, pDir)); pDir = Vector3::Normalize(pDir - pUp * Vector3::Dot(pUp, pDir)); pos = spherePos + pUp * (sphereRadius + height); angles.x = 0.0f; } if(heightFactor != 0.0f){ height = Math::Saturate(height + heightFactor * Tf * speed, heightRange); pos = spherePos + pUp * (sphereRadius + height); } DirectInput::MouseState mState = DirectInput::GetInsance()->GetMouseDelta(); if(mState.x != 0 || mState.y != 0 || moveFactor != 0.0f || sideFactor != 0.0f){ if(mState.x != 0) angles.x = angles.x + mState.x / 80.0f; if(mState.y != 0) angles.y = Math::Saturate(angles.y + mState.y / 80.0f, RangeF(-Pi * 0.499f, Pi * 0.499f)); vDir = Vector3::Normalize(pRight * sinf(angles.x) * cosf(angles.y) + pUp * -sinf(angles.y) + pDir * cosf(angles.x) * cosf(angles.y)); vUp = pUp; vRight = Vector3::Normalize(Vector3::Cross(vUp, vDir)); vUp = Vector3::Normalize(vUp - vDir * Vector3::Dot(vDir, vUp)); } viewMatrix = Matrix4x4::Inverse({{vRight, 0.0f}, {vUp, 0.0f}, {vDir, 0.0f}, {pos, 1.0f}});
äœçœ®ã®åºæºãæŽæ°ããåŸãangles.xããŒãã«ããããšã«æ³šæããŠãã ãããããã¯éèŠã§ããèŠéè§ãåæã«å€æŽããçäœã®åšããç§»åããããšãæ³åããŠã¿ãŸãããããŸããæ¹åãã¯ãã«ãpDirãšpRightã«æåœ±ãããªãã»ããïŒnewPosïŒãååŸããŠãããã«åºã¥ããŠäœçœ®ã®åºåºãæŽæ°ããŸãã2çªç®ã®æ¡ä»¶ãæ©èœãããªãªãšã³ããŒã·ã§ã³ããŒã¹ã®æŽæ°ãéå§ããŸããããããpDirãšpRightã¯vDirã«å¿ããŠãã§ã«å€æŽãããŠãããããæ¹äœè§ïŒangles.xïŒããªã»ããããã«ãå転ã¯ãããã¯ãŒã«ãã«ãªããŸãããããã«
èªè
ãèšäºã«èå³ãæã£ãŠãããããšã«æè¬ããŸãããã®äžã«å«ãŸããŠããæ
å ±ã圌ã«ãšã£ãŠå©çšå¯èœã§ãããè峿·±ãæçšã§ãã£ãããšãé¡ã£ãŠããŸããããªãã¯ç§ã«é»åã¡ãŒã«alexwin32@mail.ruã§ææ¡ãã³ã¡ã³ããéãããã³ã¡ã³ãã®åœ¢ã§ç§ãæ®ãããšãã§ããŸããæåãç¥ã£ãŠããŸãïŒä»é²1InstanceDataStepRate , D3D11_INPUT_PER_VERTEX_DATA D3D11_INPUT_PER_INSTANCE_DATA. â . « ?» â . . â , 99 . :
UINT colorsRate = 99 / 3; std::vector<D3D11_INPUT_ELEMENT_DESC> meta = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"WORLD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"WORLD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 2, 0, D3D11_INPUT_PER_INSTANCE_DATA, colorsRate}, };
, , 33 «». 33 , 33 â .. . , , c D3D11_USAGE_IMMUTABLE. , , GPU , . :
matricesTb = Utils::DirectX::CreateBuffer(sizeof(Matrix4x4) * 99, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); colorsTb = Utils::DirectX::CreateBuffer(colors, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE, 0);
( â , )
Utils::DirectX::Map<Matrix4x4>(matricesTb, [&](Matrix4x4 *Data) {
,
ä»é²2DrawIndexedInstanced() DrawIndexedInstancedIndirect() , , DrawIndexedInstanced(). D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS. :
, . ããã¯ã©ã®ããã«äœ¿çšã§ããŸããïŒ , GPU. â Compute AppendStructuredBuffer, . CopyStructureCount() «», DrawIndexedInstancedIndirect()
ä»é²3, X a, z â Z :

. , . :

:

? . , ( t >= 0):

X

Y

, (2, 3),

P(t) :

« (3, 2) t (2, 3)». :

X

Y

. : « (3, 2), ».