WebGLã¡ãã·ã¥ã·ã§ãŒããŒã®ã¯ãŒã¯ã°ã«ãŒã忣ãšGPUã¹ã¬ããç·šæã®è€éããæ¢ããŸãã倿§ãªããŒããŠã§ã¢ã§æå€§ã®ããã©ãŒãã³ã¹ãšå¹çãåŸãããã®ã³ãŒãæé©åæ¹æ³ãçè§£ããŸãããã
WebGLã¡ãã·ã¥ã·ã§ãŒããŒã®ã¯ãŒã¯ã°ã«ãŒã忣ïŒGPUã¹ã¬ããç·šæã®è©³çŽ°è§£èª¬
ã¡ãã·ã¥ã·ã§ãŒããŒã¯WebGLã°ã©ãã£ãã¯ã¹ãã€ãã©ã€ã³ã«ãããéèŠãªé²æ©ã§ãããéçºè ã¯ãžãªã¡ããªã®åŠçãšã¬ã³ããªã³ã°ããã现ããå¶åŸ¡ã§ããããã«ãªããŸããGPUäžã§ã®ã¯ãŒã¯ã°ã«ãŒããšã¹ã¬ããã®ç·šæã»åæ£æ¹æ³ãçè§£ããããšã¯ããã®åŒ·åãªæ©èœã®ããã©ãŒãã³ã¹äžã®å©ç¹ãæå€§åããããã«äžå¯æ¬ ã§ãããã®ããã°èšäºã§ã¯ãWebGLã¡ãã·ã¥ã·ã§ãŒããŒã®ã¯ãŒã¯ã°ã«ãŒã忣ãšGPUã¹ã¬ããç·šæã«ã€ããŠãäž»èŠãªæŠå¿µãæé©åæŠç¥ãå®è·µçãªäŸã亀ããªãã詳ãã解説ããŸãã
ã¡ãã·ã¥ã·ã§ãŒããŒãšã¯ïŒ
åŸæ¥ã®WebGLã¬ã³ããªã³ã°ãã€ãã©ã€ã³ã¯ããžãªã¡ããªã®åŠçã«é ç¹ã·ã§ãŒããŒãšãã©ã°ã¡ã³ãã·ã§ãŒããŒã«äŸåããŠããŸããã¡ãã·ã¥ã·ã§ãŒããŒã¯æ¡åŒµæ©èœãšããŠå°å ¥ãããããæè»ã§å¹ççãªä»£æ¿ææ®µãæäŸããŸãããããã¯ãåºå®æ©èœã®é ç¹åŠçãšããã»ã¬ãŒã·ã§ã³ã¹ããŒãžããéçºè ãGPUäžã§çŽæ¥ãžãªã¡ããªãçæã»æäœã§ããããã°ã©ããã«ãªã·ã§ãŒããŒã¹ããŒãžã«çœ®ãæããŸããããã«ãããç¹ã«å€æ°ã®ããªããã£ããæã€è€éãªã·ãŒã³ã§ãå€§å¹ ãªããã©ãŒãã³ã¹åäžãæåŸ ã§ããŸãã
ã¡ãã·ã¥ã·ã§ãŒããŒãã€ãã©ã€ã³ã¯ãäž»ã«2ã€ã®ã·ã§ãŒããŒã¹ããŒãžã§æ§æãããŸãïŒ
- ã¿ã¹ã¯ã·ã§ãŒããŒïŒãªãã·ã§ã³ïŒïŒ ã¿ã¹ã¯ã·ã§ãŒããŒã¯ãã¡ãã·ã¥ã·ã§ãŒããŒãã€ãã©ã€ã³ã®æåã®ã¹ããŒãžã§ããã¡ãã·ã¥ã·ã§ãŒããŒã«ãã£ã¹ããããããã¯ãŒã¯ã°ã«ãŒãã®æ°ã決å®ãã圹å²ãæ ããŸããã¡ãã·ã¥ã·ã§ãŒããŒã§åŠçãããåã«ãžãªã¡ããªãã«ãªã³ã°ãããã现ååãããããããã«äœ¿çšã§ããŸãã
- ã¡ãã·ã¥ã·ã§ãŒããŒïŒ ã¡ãã·ã¥ã·ã§ãŒããŒã¯ãã¡ãã·ã¥ã·ã§ãŒããŒãã€ãã©ã€ã³ã®äžæ žãšãªãã¹ããŒãžã§ããé ç¹ãšããªããã£ããçæãã圹å²ãæ ããŸããå ±æã¡ã¢ãªã«ã¢ã¯ã»ã¹ã§ããåãã¯ãŒã¯ã°ã«ãŒãå ã®ã¹ã¬ããéã§éä¿¡ãå¯èœã§ãã
ã¯ãŒã¯ã°ã«ãŒããšã¹ã¬ããã®çè§£
ã¯ãŒã¯ã°ã«ãŒãã®åæ£ã«ã€ããŠæãäžããåã«ãGPUã³ã³ãã¥ãŒãã£ã³ã°ã®æèã«ãããã¯ãŒã¯ã°ã«ãŒããšã¹ã¬ããã®åºæ¬çãªæŠå¿µãçè§£ããããšãäžå¯æ¬ ã§ãã
ã¯ãŒã¯ã°ã«ãŒã
ã¯ãŒã¯ã°ã«ãŒãã¯ãGPUã®ã³ã³ãã¥ãŒããŠãããäžã§åæã«å®è¡ãããã¹ã¬ããã®éãŸãã§ããã¯ãŒã¯ã°ã«ãŒãå
ã®ã¹ã¬ããã¯å
±æã¡ã¢ãªãéããŠäºãã«éä¿¡ã§ããã¿ã¹ã¯ã§ã®å調ãå¹ççãªããŒã¿å
±æãå¯èœã§ããã¯ãŒã¯ã°ã«ãŒãã®ãµã€ãºïŒå«ãŸããã¹ã¬ããæ°ïŒã¯ãããã©ãŒãã³ã¹ã«åœ±é¿ãäžããéèŠãªãã©ã¡ãŒã¿ã§ããã·ã§ãŒããŒã³ãŒãå
ã§ layout(local_size_x = N, local_size_y = M, local_size_z = K) in; ãšãã修食åã䜿ã£ãŠå®çŸ©ãããNãMãKãã¯ãŒã¯ã°ã«ãŒãã®æ¬¡å
ã衚ããŸãã
æå€§ã¯ãŒã¯ã°ã«ãŒããµã€ãºã¯ããŒããŠã§ã¢ã«äŸåãããã®å¶éãè¶ ãããšæªå®çŸ©ã®åäœãåŒãèµ·ãããŸããã¯ãŒã¯ã°ã«ãŒããµã€ãºã®äžè¬çãªå€ã¯ãGPUã¢ãŒããã¯ãã£ãšããŸãæŽåããåŸåãããããã2ã®ã¹ãä¹ïŒäŸïŒ64ã128ã256ïŒã§ãã
ã¹ã¬ããïŒã€ã³ãã±ãŒã·ã§ã³ïŒ
ã¯ãŒã¯ã°ã«ãŒãå
ã®åã¹ã¬ããã¯ã€ã³ãã±ãŒã·ã§ã³ãšãåŒã°ããŸããåã¹ã¬ããã¯åãã·ã§ãŒããŒã³ãŒããå®è¡ããŸãããç°ãªãããŒã¿ãæäœããŸããçµã¿èŸŒã¿å€æ° gl_LocalInvocationID ã¯ãåã¹ã¬ããã«ãã®ã¯ãŒã¯ã°ã«ãŒãå
ã§ã®äžæã®èå¥åãæäŸããŸãããã®èå¥åã¯3Dãã¯ãã«ã§ã(0, 0, 0) ãã (N-1, M-1, K-1) ãŸã§ã®ç¯å²ã§ããããã§NãMãKã¯ã¯ãŒã¯ã°ã«ãŒãã®æ¬¡å
ã§ãã
ã¹ã¬ããã¯ã¯ãŒãïŒãŸãã¯ãŠã§ãŒãããã³ãïŒã«ã°ã«ãŒãåããããããGPUäžã§ã®å®è¡ã®åºæ¬åäœã§ããã¯ãŒãå ã®ãã¹ãŠã®ã¹ã¬ããã¯ãåæã«åãåœä»€ãå®è¡ããŸããã¯ãŒãå ã®ã¹ã¬ãããïŒåå²ã«ããïŒç°ãªãå®è¡ãã¹ããã©ãå Žåãäžéšã®ã¹ã¬ãããäžæçã«éã¢ã¯ãã£ãã«ãªããä»ã®ã¹ã¬ãããå®è¡ãããããšããããŸããããã¯ã¯ãŒãåå²ãšããŠç¥ãããããã©ãŒãã³ã¹ã«æªåœ±é¿ãäžããå¯èœæ§ããããŸãã
ã¯ãŒã¯ã°ã«ãŒãã®åæ£
ã¯ãŒã¯ã°ã«ãŒãã®åæ£ãšã¯ãGPUãã¯ãŒã¯ã°ã«ãŒãããã®ã³ã³ãã¥ãŒããŠãããã«ã©ã®ããã«å²ãåœãŠãããæããŸããWebGLã®å®è£ ã¯ãå©çšå¯èœãªããŒããŠã§ã¢ãªãœãŒã¹äžã§ã®ã¯ãŒã¯ã°ã«ãŒãã®ã¹ã±ãžã¥ãŒãªã³ã°ãšå®è¡ãæ åœããŸãããã®ããã»ã¹ãçè§£ããããšã¯ãGPUã广çã«å©çšããå¹ççãªã¡ãã·ã¥ã·ã§ãŒããŒãäœæããäžã§éèŠã§ãã
ã¯ãŒã¯ã°ã«ãŒãã®ãã£ã¹ããã
ãã£ã¹ãããããã¯ãŒã¯ã°ã«ãŒãã®æ°ã¯ãglDispatchMeshWorkgroupsEXT(groupCountX, groupCountY, groupCountZ) 颿°ã«ãã£ãŠæ±ºå®ãããŸãããã®é¢æ°ã¯ã忬¡å
ã§èµ·åããã¯ãŒã¯ã°ã«ãŒãã®æ°ãæå®ããŸããã¯ãŒã¯ã°ã«ãŒãã®ç·æ°ã¯ãgroupCountXãgroupCountYãgroupCountZ ã®ç©ã«ãªããŸãã
çµã¿èŸŒã¿å€æ° gl_GlobalInvocationID ã¯ããã¹ãŠã®ã¯ãŒã¯ã°ã«ãŒãã«ããã£ãŠåã¹ã¬ããã«äžæã®èå¥åãæäŸããŸããããã¯æ¬¡ã®ããã«èšç®ãããŸãïŒ
gl_GlobalInvocationID = gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;
ããã§ïŒ
gl_WorkGroupIDïŒçŸåšã®ã¯ãŒã¯ã°ã«ãŒãã®ã€ã³ããã¯ã¹ã衚ã3Dãã¯ãã«ãgl_WorkGroupSizeïŒã¯ãŒã¯ã°ã«ãŒãã®ãµã€ãºã衚ã3Dãã¯ãã«ïŒlocal_size_x,local_size_y,local_size_z修食åã§å®çŸ©ïŒãgl_LocalInvocationIDïŒã¯ãŒã¯ã°ã«ãŒãå ã®çŸåšã®ã¹ã¬ããã®ã€ã³ããã¯ã¹ã衚ã3Dãã¯ãã«ã
ããŒããŠã§ã¢ã«é¢ããèæ ®äºé
ã¯ãŒã¯ã°ã«ãŒãã®ã³ã³ãã¥ãŒããŠããããžã®å®éã®åæ£ã¯ããŒããŠã§ã¢ã«äŸåããGPUããšã«ç°ãªãå ŽåããããŸããããããããã€ãã®äžè¬ååãé©çšãããŸãïŒ
- äžŠè¡æ§ïŒ GPUã¯ã䜿çšçãæå€§åããããã«ãã§ããã ãå€ãã®ã¯ãŒã¯ã°ã«ãŒããåæã«å®è¡ããããšããŸããããã«ã¯ãååãªå©çšå¯èœãªã³ã³ãã¥ãŒããŠããããšã¡ã¢ãªåž¯åå¹ ãå¿ èŠã§ãã
- 屿æ§ïŒ GPUã¯ããã£ãã·ã¥ããã©ãŒãã³ã¹ãåäžãããããã«ãåãããŒã¿ã«ã¢ã¯ã»ã¹ããã¯ãŒã¯ã°ã«ãŒããäºãã«è¿ãã«ã¹ã±ãžã¥ãŒã«ããããšããããšããããŸãã
- è² è·åæ£ïŒ GPUã¯ãããã«ããã¯ãé¿ãããã¹ãŠã®ãŠããããã¢ã¯ãã£ãã«ããŒã¿ãåŠçããããã«ãã¯ãŒã¯ã°ã«ãŒããã³ã³ãã¥ãŒããŠãããéã«åçã«åæ£ãããããšããŸãã
ã¯ãŒã¯ã°ã«ãŒãåæ£ã®æé©å
ã¯ãŒã¯ã°ã«ãŒãã®åæ£ãæé©åããã¡ãã·ã¥ã·ã§ãŒããŒã®ããã©ãŒãã³ã¹ãåäžãããããã«ãããã€ãã®æŠç¥ãæ¡çšã§ããŸãïŒ
é©åãªã¯ãŒã¯ã°ã«ãŒããµã€ãºã®éžæ
é©åãªã¯ãŒã¯ã°ã«ãŒããµã€ãºãéžæããããšã¯ãããã©ãŒãã³ã¹ã«ãšã£ãŠéåžžã«éèŠã§ããå°ããããã¯ãŒã¯ã°ã«ãŒãã¯GPUã®å©çšå¯èœãªäžŠåæ§ãååã«æŽ»çšã§ããªãå¯èœæ§ãããã倧ããããã¯ãŒã¯ã°ã«ãŒãã¯éå°ãªã¬ãžã¹ã¿ãã¬ãã·ã£ãŒãåŒãèµ·ããããªãã¥ãã³ã·ãŒãäœäžãããå¯èœæ§ããããŸããç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ã«æé©ãªã¯ãŒã¯ã°ã«ãŒããµã€ãºã決å®ããã«ã¯ãå®éšãšãããã¡ã€ãªã³ã°ããã°ãã°å¿ èŠã§ãã
ã¯ãŒã¯ã°ã«ãŒããµã€ãºãéžæããéã«ã¯ããããã®èŠå ãèæ ®ããŠãã ããïŒ
- ããŒããŠã§ã¢ã®å¶éïŒ GPUã«ãã£ãŠèª²ãããæå€§ã¯ãŒã¯ã°ã«ãŒããµã€ãºã®å¶éãéµå®ããŠãã ããã
- ã¯ãŒããµã€ãºïŒ ã¯ãŒããµã€ãºïŒéåžž32ãŸãã¯64ïŒã®åæ°ã§ããã¯ãŒã¯ã°ã«ãŒããµã€ãºãéžæããŠãã ãããããã¯ã¯ãŒãåå²ãæå°éã«æããã®ã«åœ¹ç«ã¡ãŸãã
- å ±æã¡ã¢ãªã®äœ¿çšéïŒ ã·ã§ãŒããŒãå¿ èŠãšããå ±æã¡ã¢ãªã®éãèæ ®ããŠãã ããã倧ããªã¯ãŒã¯ã°ã«ãŒãã¯ããå€ãã®å ±æã¡ã¢ãªãå¿ èŠãšããå Žåããããåæã«å®è¡ã§ããã¯ãŒã¯ã°ã«ãŒãã®æ°ãå¶éãããå¯èœæ§ããããŸãã
- ã¢ã«ãŽãªãºã ã®æ§é ïŒ ã¢ã«ãŽãªãºã ã®æ§é ã«ãã£ãŠã¯ãç¹å®ã®ã¯ãŒã¯ã°ã«ãŒããµã€ãºãæ±ããããå ŽåããããŸããäŸãã°ããªãã¯ã·ã§ã³æäœãå®è¡ããã¢ã«ãŽãªãºã ã¯ã2ã®ã¹ãä¹ã®ã¯ãŒã¯ã°ã«ãŒããµã€ãºããæ©æµãåããå¯èœæ§ããããŸãã
äŸïŒ ã¿ãŒã²ããããŒããŠã§ã¢ã®ã¯ãŒããµã€ãºã32ã§ãã¢ã«ãŽãªãºã ãããŒã«ã«ãªãã¯ã·ã§ã³ã§å ±æã¡ã¢ãªãå¹ççã«å©çšããå Žåãã¯ãŒã¯ã°ã«ãŒããµã€ãº64ãŸãã¯128ããå§ããã®ãè¯ãã¢ãããŒããããããŸãããWebGLãããã¡ã€ãªã³ã°ããŒã«ã䜿çšããŠã¬ãžã¹ã¿äœ¿çšéãç£èŠããã¬ãžã¹ã¿ãã¬ãã·ã£ãŒãããã«ããã¯ã«ãªã£ãŠããªãããšã確èªããŠãã ããã
ã¯ãŒãåå²ã®æå°å
ã¯ãŒãåå²ã¯ãã¯ãŒãå ã®ã¹ã¬ãããåå²ã®ããã«ç°ãªãå®è¡ãã¹ããã©ããšãã«çºçããŸããGPUã¯ååå²ãé æ¬¡å®è¡ããå¿ èŠããããäžéšã®ã¹ã¬ãããäžæçã«éã¢ã¯ãã£ãã«ãªããããããã¯ããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžãããå¯èœæ§ããããŸããã¯ãŒãåå²ãæå°åããã«ã¯ïŒ
- æ¡ä»¶åå²ãé¿ããïŒ ã·ã§ãŒããŒã³ãŒãå ã§ã®æ¡ä»¶åå²ãå¯èœãªéãé¿ããããã«ããŠãã ãããåãçµæãåå²ãªãã§éæããããã«ããã¬ãã£ã±ãŒã·ã§ã³ããã¯ãã«åãªã©ã®ä»£æ¿æè¡ã䜿çšããŠãã ããã
- é¡äŒŒã¹ã¬ãããã°ã«ãŒãåããïŒ åãã¯ãŒãå ã®ã¹ã¬ãããåãå®è¡ãã¹ããã©ãããããªãããã«ããŒã¿ãæŽçããŠãã ããã
äŸïŒ `if` æã䜿çšããŠå€æ°ã«æ¡ä»¶ä»ãã§å€ã代å
¥ãã代ããã«ãããŒã«æ¡ä»¶ã«åºã¥ããŠ2ã€ã®å€ã®éã§ç·åœ¢è£éãå®è¡ãã `mix` 颿°ã䜿çšã§ããŸãïŒ
float value = mix(value1, value2, condition);
ããã«ããåå²ããªããªããã¯ãŒãå
ã®ãã¹ãŠã®ã¹ã¬ãããåãåœä»€ãå®è¡ããããšãä¿èšŒãããŸãã
å ±æã¡ã¢ãªã®å¹æçãªæŽ»çš
å ±æã¡ã¢ãªã¯ãã¯ãŒã¯ã°ã«ãŒãå ã®ã¹ã¬ãããéä¿¡ããããŒã¿ãå ±æããããã®é«éã§å¹ççãªæ¹æ³ãæäŸããŸããããããããã¯éããããªãœãŒã¹ã§ããããã广çã«äœ¿çšããããšãéèŠã§ãã
- å ±æã¡ã¢ãªã¢ã¯ã»ã¹ã®æå°åïŒ å ±æã¡ã¢ãªãžã®ã¢ã¯ã»ã¹åæ°ãã§ããã ãæžãããŠãã ãããé »ç¹ã«äœ¿çšãããããŒã¿ã¯ã¬ãžã¹ã¿ã«æ ŒçŽããç¹°ãè¿ãã®ã¢ã¯ã»ã¹ãé¿ããŠãã ããã
- ãã³ã¯ã³ã³ããªã¯ãã®åé¿ïŒ å ±æã¡ã¢ãªã¯éåžžãã³ã¯ã«ç·šæãããŠãããåããã³ã¯ãžã®åæã¢ã¯ã»ã¹ã¯ãã³ã¯ã³ã³ããªã¯ããåŒãèµ·ããå¯èœæ§ããããããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžãããå¯èœæ§ããããŸãããã³ã¯ã³ã³ããªã¯ããé¿ããã«ã¯ãã¹ã¬ãããå¯èœãªéãç°ãªãå ±æã¡ã¢ãªã®ãã³ã¯ã«ã¢ã¯ã»ã¹ããããã«ããŠãã ãããããã«ã¯ãããŒã¿æ§é ã«ããã£ã³ã°ã远å ããããã¡ã¢ãªã¢ã¯ã»ã¹ãåé 眮ãããããããšãå«ãŸããŸãã
äŸïŒ å ±æã¡ã¢ãªã§ãªãã¯ã·ã§ã³æäœãå®è¡ããå Žåããã³ã¯ã³ã³ããªã¯ããé¿ããããã«ã¹ã¬ãããç°ãªãå ±æã¡ã¢ãªã®ãã³ã¯ã«ã¢ã¯ã»ã¹ããããã«ããŠãã ãããããã¯ãå ±æã¡ã¢ãªã¢ã¬ã€ã«ããã£ã³ã°ã远å ãããããã³ã¯æ°ã®åæ°ã§ããã¹ãã©ã€ãã䜿çšããããšã§éæã§ããŸãã
ã¯ãŒã¯ã°ã«ãŒãã®è² è·åæ£
ã¯ãŒã¯ã°ã«ãŒãéã§äœæ¥ãäžåçã«åæ£ããããšãããã©ãŒãã³ã¹ã®ããã«ããã¯ã«ã€ãªããå¯èœæ§ããããŸããäžéšã®ã¯ãŒã¯ã°ã«ãŒãã¯ããã«çµäºããä»ã®ã¯ãŒã¯ã°ã«ãŒãã¯ã¯ããã«æéãããããäžéšã®ã³ã³ãã¥ãŒããŠããããã¢ã€ãã«ç¶æ ã®ãŸãŸã«ãªããŸããè² è·åæ£ã確ä¿ããã«ã¯ïŒ
- äœæ¥ãåçã«åæ£ããïŒ åã¯ãŒã¯ã°ã«ãŒããã»ãŒåãéã®äœæ¥ãè¡ãããã«ã¢ã«ãŽãªãºã ãèšèšããŠãã ããã
- åçãªäœæ¥å²ãåœãŠã䜿çšããïŒ ã·ãŒã³ã®ç°ãªãéšåã§äœæ¥éãå€§å¹ ã«ç°ãªãå Žåã¯ãåçãªäœæ¥å²ãåœãŠã䜿çšããŠã¯ãŒã¯ã°ã«ãŒããããåçã«åæ£ããããšãæ€èšããŠãã ãããããã«ã¯ãã¢ãããã¯æäœã䜿çšããŠã¢ã€ãã«ç¶æ ã®ã¯ãŒã¯ã°ã«ãŒãã«äœæ¥ãå²ãåœãŠãããšãå«ãŸããŸãã
äŸïŒ ããªãŽã³å¯åºŠãå€åããã·ãŒã³ãã¬ã³ããªã³ã°ããå Žåãç»é¢ãã¿ã€ã«ã«åå²ããåã¿ã€ã«ãã¯ãŒã¯ã°ã«ãŒãã«å²ãåœãŠãŸããã¿ã¹ã¯ã·ã§ãŒããŒã䜿çšããŠåã¿ã€ã«ã®è€éããæšå®ããããè€éãªã¿ã€ã«ã«ã¯ããå€ãã®ã¯ãŒã¯ã°ã«ãŒããå²ãåœãŠãŸããããã«ããããã¹ãŠã®ã³ã³ãã¥ãŒããŠããããå®å šã«å©çšãããããã«ãªããŸãã
ã«ãªã³ã°ãšå¢å¹ ã®ããã®ã¿ã¹ã¯ã·ã§ãŒããŒã®æ€èš
ã¿ã¹ã¯ã·ã§ãŒããŒã¯ãªãã·ã§ã³ã§ãããã¡ãã·ã¥ã·ã§ãŒããŒã¯ãŒã¯ã°ã«ãŒãã®ãã£ã¹ããããå¶åŸ¡ããã¡ã«ããºã ãæäŸããŸããããã©ãŒãã³ã¹ãæé©åããããã«ãæŠç¥çã«äœ¿çšããŠãã ããïŒ
- ã«ãªã³ã°ïŒ 衚瀺ãããªãããŸãã¯æçµçãªç»åã«å€§ããå¯äžããªãã¯ãŒã¯ã°ã«ãŒããç Žæ£ããŸãã
- å¢å¹ ïŒ ã·ãŒã³ã®ç¹å®ã®é åã§è©³çްã¬ãã«ãäžããããã«ã¯ãŒã¯ã°ã«ãŒãã现ååããŸãã
äŸïŒ ã¿ã¹ã¯ã·ã§ãŒããŒã䜿çšããŠãã¡ãã·ã¥ã¬ãããã¡ãã·ã¥ã·ã§ãŒããŒã«ãã£ã¹ãããããåã«ãã©ã¹ã¿ã ã«ãªã³ã°ãå®è¡ããŸããããã«ãããã¡ãã·ã¥ã·ã§ãŒããŒã衚瀺ãããªããžãªã¡ããªãåŠçããã®ãé²ãã貎éãªGPUãµã€ã¯ã«ãç¯çŽããŸãã
å®è·µçãªäŸ
ãããã®ååãWebGLã¡ãã·ã¥ã·ã§ãŒããŒã§ã©ã®ããã«é©çšããããããã€ãã®å®è·µçãªäŸãèããŠã¿ãŸãããã
äŸ1ïŒé ç¹ã®ã°ãªããçæ
ãã®äŸã¯ãã¡ãã·ã¥ã·ã§ãŒããŒã䜿çšããŠé ç¹ã®ã°ãªãããçæããæ¹æ³ã瀺ããŠããŸããã¯ãŒã¯ã°ã«ãŒããµã€ãºã¯ãåã¯ãŒã¯ã°ã«ãŒãã«ãã£ãŠçæãããã°ãªããã®ãµã€ãºã決å®ããŸãã
#version 460
#extension GL_EXT_mesh_shader : require
#extension GL_EXT_fragment_shading_rate : require
layout(local_size_x = 8, local_size_y = 8) in;
layout(max_vertices = 64, max_primitives = 64) out;
layout(location = 0) out vec4 f_color[];
layout(location = 1) out flat int f_primitiveId[];
void main() {
uint localId = gl_LocalInvocationIndex;
uint x = localId % gl_WorkGroupSize.x;
uint y = localId / gl_WorkGroupSize.x;
float u = float(x) / float(gl_WorkGroupSize.x - 1);
float v = float(y) / float(gl_WorkGroupSize.y - 1);
float posX = u * 2.0 - 1.0;
float posY = v * 2.0 - 1.0;
gl_MeshVerticesEXT[localId].gl_Position = vec4(posX, posY, 0.0, 1.0);
f_color[localId] = vec4(u, v, 1.0, 1.0);
gl_PrimitiveTriangleIndicesEXT[localId * 6 + 0] = localId;
f_primitiveId[localId] = int(localId);
gl_MeshPrimitivesEXT[localId / 3] = localId;
gl_MeshPrimitivesEXT[localId / 3 + 1] = localId + 1;
gl_MeshPrimitivesEXT[localId / 3 + 2] = localId + 2;
gl_PrimitiveCountEXT = 64/3;
gl_MeshVertexCountEXT = 64;
EmitMeshTasksEXT(gl_PrimitiveCountEXT, gl_MeshVertexCountEXT);
}
ãã®äŸã§ã¯ãã¯ãŒã¯ã°ã«ãŒããµã€ãºã¯8x8ã§ãããåã¯ãŒã¯ã°ã«ãŒãã64é ç¹ã®ã°ãªãããçæããããšãæå³ããŸããgl_LocalInvocationIndex ã¯ãã°ãªããå
ã®åé ç¹ã®äœçœ®ãèšç®ããããã«äœ¿çšãããŸãã
äŸ2ïŒãªãã¯ã·ã§ã³æäœã®å®è¡
ãã®äŸã¯ãå ±æã¡ã¢ãªã䜿çšããŠããŒã¿é åã«å¯ŸããŠãªãã¯ã·ã§ã³æäœãå®è¡ããæ¹æ³ã瀺ããŠããŸããã¯ãŒã¯ã°ã«ãŒããµã€ãºã¯ããªãã¯ã·ã§ã³ã«åå ããã¹ã¬ããã®æ°ã決å®ããŸãã
#version 460
#extension GL_EXT_mesh_shader : require
#extension GL_EXT_fragment_shading_rate : require
layout(local_size_x = 256) in;
layout(max_vertices = 1, max_primitives = 1) out;
shared float sharedData[256];
layout(location = 0) uniform float inputData[256 * 1024];
layout(location = 1) out float outputData;
void main() {
uint localId = gl_LocalInvocationIndex;
uint globalId = gl_WorkGroupID.x * gl_WorkGroupSize.x + localId;
sharedData[localId] = inputData[globalId];
barrier();
for (uint i = gl_WorkGroupSize.x / 2; i > 0; i /= 2) {
if (localId < i) {
sharedData[localId] += sharedData[localId + i];
}
barrier();
}
if (localId == 0) {
outputData = sharedData[0];
}
gl_MeshPrimitivesEXT[0] = 0;
EmitMeshTasksEXT(1,1);
gl_MeshVertexCountEXT = 1;
gl_PrimitiveCountEXT = 1;
}
ãã®äŸã§ã¯ãã¯ãŒã¯ã°ã«ãŒããµã€ãºã¯256ã§ããåã¹ã¬ããã¯å ¥åé åããå€ãå ±æã¡ã¢ãªã«ããŒãããŸããæ¬¡ã«ãã¹ã¬ããã¯å ±æã¡ã¢ãªã§ãªãã¯ã·ã§ã³æäœãå®è¡ããå€ãåèšããŸããæçµçµæã¯åºåé åã«æ ŒçŽãããŸãã
ã¡ãã·ã¥ã·ã§ãŒããŒã®ãããã°ãšãããã¡ã€ãªã³ã°
ã¡ãã·ã¥ã·ã§ãŒããŒã®ãããã°ãšãããã¡ã€ãªã³ã°ã¯ããã®äžŠåæ§ãšå©çšå¯èœãªãããã°ããŒã«ã®å¶éã®ããã«å°é£ãªå ŽåããããŸããããããããã©ãŒãã³ã¹ã®åé¡ãç¹å®ã解決ããããã«äœ¿çšã§ããããã€ãã®ãã¯ããã¯ããããŸãïŒ
- WebGLãããã¡ã€ãªã³ã°ããŒã«ã®äœ¿çšïŒ Chrome DevToolsãFirefox Developer Toolsãªã©ã®WebGLãããã¡ã€ãªã³ã°ããŒã«ã¯ãã¡ãã·ã¥ã·ã§ãŒããŒã®ããã©ãŒãã³ã¹ã«é¢ãã貎éãªæŽå¯ãæäŸã§ããŸãããããã®ããŒã«ã¯ãéå°ãªã¬ãžã¹ã¿ãã¬ãã·ã£ãŒãã¯ãŒãåå²ãã¡ã¢ãªã¢ã¯ã»ã¹ã¹ããŒã«ãªã©ã®ããã«ããã¯ãç¹å®ããããã«äœ¿çšã§ããŸãã
- ãããã°åºåã®æ¿å ¥ïŒ ã·ã§ãŒããŒã³ãŒãã«ãããã°åºåãæ¿å ¥ããŠã倿°ã®å€ãã¹ã¬ããã®å®è¡ãã¹ã远跡ããŸããããã¯ãè«çãšã©ãŒãäºæããªãåäœãç¹å®ããã®ã«åœ¹ç«ã¡ãŸãããã ãããããã°åºåãå€ããããšããã©ãŒãã³ã¹ã«æªåœ±é¿ãäžããå¯èœæ§ããããããæ³šæãå¿ èŠã§ãã
- åé¡ãµã€ãºã®çž®å°ïŒ ãããã°ã容æã«ããããã«åé¡ã®ãµã€ãºãçž®å°ããŸããäŸãã°ãã¡ãã·ã¥ã·ã§ãŒããŒãå€§èŠæš¡ãªã·ãŒã³ãåŠçããŠããå Žåã¯ãããªããã£ããé ç¹ã®æ°ãæžãããŠåé¡ã解決ãããã©ããã確èªããŠã¿ãŠãã ããã
- ç°ãªãããŒããŠã§ã¢ã§ã®ãã¹ãïŒ ããŒããŠã§ã¢åºæã®åé¡ãç¹å®ããããã«ãç°ãªãGPUã§ã¡ãã·ã¥ã·ã§ãŒããŒããã¹ãããŸããäžéšã®GPUã¯ç°ãªãããã©ãŒãã³ã¹ç¹æ§ãæã€ããã·ã§ãŒããŒã³ãŒãã®ãã°ãé²åããå¯èœæ§ããããŸãã
çµè«
WebGLã¡ãã·ã¥ã·ã§ãŒããŒã®ã¯ãŒã¯ã°ã«ãŒã忣ãšGPUã¹ã¬ããç·šæãçè§£ããããšã¯ããã®åŒ·åãªæ©èœã®ããã©ãŒãã³ã¹äžã®å©ç¹ãæå€§åããããã«äžå¯æ¬ ã§ããã¯ãŒã¯ã°ã«ãŒããµã€ãºãæ éã«éžæããã¯ãŒãåå²ãæå°éã«æããå ±æã¡ã¢ãªã广çã«æŽ»çšããè² è·åæ£ã確ä¿ããããšã§ãéçºè ã¯GPUã广çã«å©çšããå¹ççãªã¡ãã·ã¥ã·ã§ãŒããŒãäœæã§ããŸããããã«ãããããé«éãªã¬ã³ããªã³ã°æéãåäžãããã¬ãŒã ã¬ãŒãããããŠããèŠèŠçã«é åçãªWebGLã¢ããªã±ãŒã·ã§ã³ãå®çŸããŸãã
ã¡ãã·ã¥ã·ã§ãŒããŒãããåºãæ¡çšãããã«ã€ããŠããã®å éšåäœã«ã€ããŠã®æ·±ãçè§£ã¯ãWebGLã°ã©ãã£ãã¯ã¹ã®éçãæŒãåºããããšãããã¹ãŠã®éçºè ã«ãšã£ãŠäžå¯æ¬ ã«ãªãã§ããããå®éšããããã¡ã€ãªã³ã°ãç¶ç¶çãªåŠç¿ãããã®æè¡ãç¿åŸãããã®æœåšèœåãæå€§éã«åŒãåºãéµãšãªããŸãã
ãããªããªãœãŒã¹
- Khronos Group - Mesh Shading Extension Specification: [https://www.khronos.org/](https://www.khronos.org/)
- WebGL ãµã³ãã«: [å ¬éãããŠããWebGLã¡ãã·ã¥ã·ã§ãŒããŒã®ãµã³ãã«ããã¢ãžã®ãªã³ã¯ãæäŸ]
- éçºè ãã©ãŒã©ã : [WebGLãã°ã©ãã£ãã¯ã¹ããã°ã©ãã³ã°ã«é¢é£ãããã©ãŒã©ã ãã³ãã¥ããã£ãèšèŒ]