https://dl.dropboxusercontent.com/u/18978109/ParticleTest/ParticleTest.html
¤º¤¤¤Ö¤ó¤È¹¹¿·¤Î´Ö¤¬³«¤¤¤Æ¤·¤Þ¤¤¡¡¤ªÂÔ¤Á¤¤¤¿¤À¤¤¤¿Êý¤Ë¤Ï¿½¤·Ìõ¤Ê¤¤¤Ç¤¹¡£
º£²ó¤ÏDX11¤ò»ÈÍѤ·¤¿¥Ñ¡¼¥Æ¥£¥¯¥ëÉÁ²è¤Î¥µ¥ó¥×¥ë¤òµ»ö¤Ë¤·¤Æ¤ß¤Þ¤·¤¿¡£¡¡
ºÇ¶áÏÃÂê¤Î¡©GPGPU¥³¥ó¥Ô¥å¡¼¥Æ¥£¥ó¥°¡¡¤Þ¤À¸«¤ÌPS4¤ä¤éXBOXOne¤È¤¤¤Ã¤¿¼¡À¤Â嵡¤Ê¤É¤Ç¼çÎϤˤʤë¤Ç¤¢¤í¤¦GPU¤ò»ÈÍѤ·¤¿·×»»¤Ç¤¹¤Í¡£
GPGPU ¡ÊÈÆÍÑÌÜŪ¤ÎGPU·×»»½èÍý¡Ë¤Ï¥·¥§¡¼¥À¡¼¥×¥í¥°¥é¥à¤ò»ÈÍѤ·¤¿¡¡ÉÁ²è¤ò´Þ¤à¿ÍÑÅӤʷ׻»½èÍý¤Î¤³¤È¤Ç¤¹¡£
GPU¤ÎÉâÆ°ÅÀ¾¯¿ô·×»»¤Ë¶¯¤¤ÅÀ¤ä¥Þ¥ë¥Á¥¹¥ì¥Ã¥ÉÂбþ¤Ê¤É¤ÎÍøÅÀ¤òÀ¸¤«¤·¤ÆCPU¤Î½èÍýÉé²Ù¤ò·Ú¸º¤¹¤ë¤³¤È¤Ç
¼Â¹Ô®ÅÙ¤ò¸þ¾å¤µ¤»¤ë¤³¤È¤¬¼ç´ã¤Ç¤¹¡£
¤¤¤Þ¤Î¤È¤³¤íDX11¤ò¥µ¥Ý¡¼¥È¤·¤¿²ÈÄíÍÑPC¤¬»Ô¾ì¤Ë¹¤¯¹Ô¤ÅϤë¤Î¤Ï2ǯ¼å¤«¤Ê¤¢¤È¸«ÀѤâ¤Ã¤Æ¤¤¤ë¤Î¤Ç¤¹¤¬¡¢¡¡³«È¯´ü´Ö¤ò¹Í¤¨¤ë¤È
¤½¤í¤½¤íÊÙ¶¯¤·¤Æ¤ª¤«¤Ê¤¤¤ÈÃÖ¤¤¤Æ¤±¤Ü¤ê¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¤¤½¤¦¤Ê¤Î¤Ç¡¢¤³¤ì¤òµ¡²ñ¤ËÊÙ¶¯¤·¤Æ¤ß¤Æ¤Ï¤¤¤«¤¬¤Ç¤·¤ç¤¦¡£
º£²ó¤Î¥µ¥ó¥×¥ë¤Î¼Â¹Ô¿ôÃͤϥΡ¼¥ÈPC¤Ç¡¡¡ÊCorei7-2630¡Ê2Ghz)¡¡GeforceGT540M¡Ë¡¡
¥Ñ¡¼¥Æ¥£¥¯¥ë¿ô70Ëü¤Ç¡¡70FPSÁ°¸å¤Ç¤·¤¿¡¡Ä¾ÀÜVRAM¤Ë¥Ç¡¼¥¿¤ò½ñ¤¹þ¤à¤Î¤Ç¥É¥í¡¼¥³¡¼¥ë¤Ï£±¤Ç¤¹¡£
¥¹¥Ú¥Ã¥¯¤Ï´Ä¶¤Ë¤è¤Ã¤Æ¤«¤Ê¤êº¹¤¬½Ð¤ë¤È»×¤¤¤Þ¤¹¤Î¤Ç¡¢¤½¤ì¤¾¤ì¤Î´Ä¶¤Ë¹ç¤ï¤»¤ÆºÇŬÃͤòÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
µ»öÆâ¥ê¥ó¥¯Àè¤Ë¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤ò»ÈÍѤ·¤¿¥Ñ¡¼¥Æ¥£¥¯¥ë¥ì¥ó¥À¥ê¥ó¥°¤Î¥µ¥ó¥×¥ë¤È ¼Â¹Ô½èÍý®ÅÙ¤ÎÈæ³Óɽ¤¬·ÇºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤ò»ÈÍѤ¹¤ì¤Ð¤Ê¤ó¤Ç¤â¹â®¤Ë½èÍý¤Ç¤¤ë¤«¤È¤¤¤¦¤È¤½¤¦¤¤¤¦¤ï¤±¤Ç¤â¤Ê¤¯ ¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤Ë¸þ¤¤¤¿½èÍý¤ä¥Ç¡¼¥¿¹½Â¤¤ò¹©Éפ¹¤ë¤³¤È¤Ç½èÍý®Å٤θþ¾å¤¬´üÂԤǤ¤ë¤È¤¤¤¦¤³¤È¤ß¤¿¤¤¤Ç¤¹¤Í
GDC¤Ê¤É¤Çȯɽ¤µ¤ì¤Æ¤¤¤ëÆâÍÆ¤Ç¤Ï ήÂη׻»¡¢ÊªÍý±é»»¡¢¥¹¥¥ó¥·¥§¡¼¥Ç¥£¥ó¥°¡¢¥Ý¥¹¥È¥¨¥Õ¥§¥¯¥È¡¢AI ¤Ê¤É
ÉÁ²è½èÍý¤Î¹â®²½°Ê³°¤Ë¤â¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤ò»ÈÍѤ·¤¿ÍÍ¡¹¤ÊÍÑÅÓ¤¬¤¢¤ê¤½¤¦¤Ç¤¹¡£
¤Á¤Ê¤ß¤Ë¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤âGPU¤Î¥·¥§¡¼¥À¤Ê¤Î¤Ç¥·¥§¡¼¥ÀÍÑ´Ø¿ô¤·¤«ÍѰդµ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¡¡É¬Íפʴؿô¤Ï¼«ºî¤¹¤ë¤«¥é¥¤¥Ö¥é¥ê¤òήÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
DirectX11̤¥µ¥Ý¡¼¥È¤ÎGPU¤Ç¥·¥§¡¼¥À¤Ë·×»»¤µ¤»¤¿¤¤¾ì¹ç¤Ï¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤Î·×»»Éôʬ¤ò¥ì¥ó¥À¥ê¥ó¥°ÍѤΥ·¥§¡¼¥À¤Ë°Ü¿¢¤·¤Æ¡¡¥Ð¥Ã¥Õ¥¡¥á¥â¥ê¤ÎÂå¤ï¤ê¤Ë¥Æ¥¯¥¹¥Á¥ã¤ò¥á¥â¥êÂå¤ï¤ê¤Ë»È¤¦¤³¤È¤ÇGPU¤Ç·×»»¤µ¤»¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£¤³¤Î¾ì¹ç¥Ù¥¯¥È¥ëxyzw¤ò¡¡¥«¥é¡¼rgba¡¡¤ÈÃÖ¤´¹¤¨¤Æ·×»»¤µ¤»¤Æ¤¯¤À¤µ¤¤¡£¡¡¥Þ¥ë¥Á¥¹¥ì¥Ã¥É·×»»¤Î²¸·Ã¤Ï¸º¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¤¬GPU¤Ç¤Î·×»»¤Ï½½Ê¬Â®¤¤¤Î¤ÇCPU·×»»¤Ç¼Â¹Ô®Å٤Υͥ寤ˤʤꤽ¤¦¤ÊÉé²Ù¤Î·Ú¸º¤¬´üÂԤǤ¤Þ¤¹¡£
º£¸å¤ÎŸ˾¤È¤·¤Æ¤Ï¡¡¥é¥¤¥Õ¡¢¥³¥ê¥¸¥ç¥ó¡¢½ÅÎÏ¡¢¥Õ¥©¡¼¥¹¡¢¥Î¥¤¥º¡Ê¥«¡¼¥ë¥Î¥¤¥º¡¢SPH¡¢FFT¡¡¤Ê¤É¡Ë¤Î¥Ñ¥é¥á¡¼¥¿¤ò¼ÂÁõ¤·¤Æ¤¤¤¯¤³¤È¤Ç¡¡¥Ñ¡¼¥Æ¥£¥¯¥ë¥·¥¹¥Æ¥à¤È¤·¤Æ¼ÂÍÑŪ¤Ê¤â¤Î¤Ë¤Ê¤ë¤Î¤Ç¤Ï¤Ê¤¤¤«¤È»×¤¤¤Þ¤¹¡£
¤È¤¤¤¦¤³¤È¤Ç¤½¤ì¤¾¤ì¹©Éפ·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¤Ê¡¡¡¡¡¡¡¦¡¦¡¦¤È¤¤¤¦Åꤲ¤Ã¤Ñ¤Ê¤·¡Ê¾Ð¡¡
¢£º£²ó»²¹Í¤Ë¤·¤¿¥ê¥ó¥¯
Unity 4.0¡§ Compute Shader¤ò»È¤Ã¤Æ¤ß¤ë
DirectX¤ÎÏà Âè108²ó - ¤â¤ó¤·¤ç¤ÎÁã·ê
Compute Shader Overview (Windows)
¤Û¤«¤Ë¤â»²¹Í¤Ë¤·¤¿¤È¤³¤í¤¬¤¢¤Ã¤¿¤Î¤Ç¤¹¤¬ ¤¤¤Ä¤Î´Ö¤Ë¤«¤Î¥ê¥ó¥¯ÀÚ¤ì¤ÇÄÉÀפǤ¤Þ¤»¤ó¤Ç¤·¤¿¡£
¤Ê¤Î¤ÇÉÔÌÀ¤ÊÅÀ¤¬¤¢¤ì¤Ð¤Û¤«¤Î¾Ü¤·¤¤¥µ¥¤¥È¤µ¤ó¤òõ¤¹¤« ¤³¤Îµ»ö¤Î¥³¥á¥ó¥ÈÍó¤Ë¼ÁÌä¤òÅꤲ¤Æ¤¯¤À¤µ¤¤¡£
¢¨¥¹¥¯¥ê¥×¥È̾¤¬°ã¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¡¥¤¥ó¥¹¥Ú¥¯¥¿¡¼¤Ø¤ÎÀßÃ֤Ϥ³¤Î²èÁü¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
¢£¥ì¥ó¥À¥ê¥ó¥°¥·¥§¡¼¥À¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
|
[maxvertexcount(4)] // ¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¤Ç»ÈÍѤ¹¤ëĺÅÀ¿ô¤ò»ØÄê ¡ä º£²ó¤Ï£´ÄºÅÀ¤Ê¤Î¤Ç£´¤ò»ØÄê // ¥Ñ¡¼¥Æ¥£¥¯¥ëºÂɸ¥Ç¡¼¥¿¤òMVP¡Ê¥Ó¥å¡¼ºÂɸ¡Ë¤ËÊÑ´¹
output.pos = corLoc + float4(-dx, dy,0,0); output.uv=float2(0,0); outStream.Append (output); // output.pos ¡ácorLoc¡Ê¥Ñ¡¼¥Æ¥£¥¯¥ë¥·¥¹¥Æ¥àÃæ¿´ºÂɸ¡Ë + float4¡Ê¥Ñ¡¼¥Æ¥£¥¯¥ëĺÅÀ º¸¾å¡Ë; // output.uv ¡á float2(UVºÂɸ º¸¾å¡Ë; // output.col ¡á input[0].col¡¨¡ÊĺÅÀ¥«¥é¡¼ º¸¾å¡Ë; // outStream.Append (output); //¥¹¥È¥ê¡¼¥à¤Ë£±ÄºÅÀʬ¤Î¥Ç¡¼¥¿¤ò½ÐÎÏ
//°Ê²¼ ±¦¾å¡¢º¸²¼¡¢±¦²¼¤Î½ç¤Ë ¥¹¥È¥ê¡¼¥à¤Ë½ÐÎÏ ¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä¡Ä
outStream.RestartStrip(); // ¥Ó¥ë¥Ü¡¼¥É¥á¥Ã¥·¥å¤ÎÉÁ²è
|
¥ì¥ó¥À¥ê¥ó¥°ÍѤΥ·¥§¡¼¥À¤ÏÄ̾ï¤Î¥·¥§¡¼¥À¤ÈÊѤï¤ê¤Þ¤»¤ó¤¬¹â®ÉÁ²è¤Î¤¿¤á¤ËÊѹ¹ÅÀ¤¬¤¢¤ê¤Þ¤¹
¡ü¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¡¼¤Î»ÈÍÑ
¡üStructuredBuffer¤Î»ÈÍÑ
¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¤Ï¥·¥§¡¼¥À¤ò»ÈÍѤ·¤ÆGPUÆâ¤Ç¥á¥Ã¥·¥å¤òÉÁ²è¤¹¤ë¤¿¤á¤Î¥·¥§¡¼¥À¤Ç¤¹¡£
ÂçÎ̤Υá¥Ã¥·¥å¤ÎĺÅÀ¥Ç¡¼¥¿¤òGPU¦¤ËÁ÷¤ë¤Î¤Ï½èÍý¸úΨ¤¬°¤¤¤¿¤á¡¡¡¡¥Ñ¡¼¥Æ¥£¥¯¥ë¤ÎºÂɸ¥Ç¡¼¥¿¡Ê¥»¥ó¥¿¡¼ºÂɸ¡Ë ¤ä¥«¥é¡¼¥Ç¡¼¥¿¤Ê¤É¤ÎºÇ¾®¸Â¤Î¥Ç¡¼¥¿¤ò¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¤Ç¥á¥Ã¥·¥å²½¤¹¤ë¤³¤È¤Ç½èÍý®Å٤θþ¾å¤ò¤¹¤ë¤³¤È¤¬´üÂÔ½ÐÍè¤Þ¤¹¡£¡¡¡¡¡¡ ¤Á¤Ê¤ß¤Ë¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¤Ç°ìÅÙ¤ËÉÁ²è¤Ç¤¤ëĺÅÀ¿ô¤Ï256¤Ç¤¹¡£
¡ü¤µ¤é¤ËStructuredBuffer¡Ê¥·¥§¡¼¥À¥â¥Ç¥ë5¡ËÆÉ¤ß½ñ¤¤¬²Äǽ¤Ê¥Ð¥Ã¥Õ¥¡¡£¤ò »ÈÍѤ¹¤ë¤³¤È¤ÇCPU¡ÝGPU´Ö¤Ç¤Î¥Ç¡¼¥¿¤ä¤ê¤È¤ê¤¹¤ë»þ¥¹¥¯¥ê¥×¥È¤«¤é¹â®¤Ë¥¢¥¯¥»¥¹¤Ç¤¤Þ¤¹¡£
¥·¥§¡¼¥À¡¼¥â¥Ç¥ë4¤Ë¤â cbuffer¡Ê¥³¥ó¥¹¥¿¥ó¥È¥Ð¥Ã¥Õ¥¡¡Ë¡¢tbuffer¡Ê¥Æ¥¯¥¹¥Á¥ã¥Ð¥Ã¥Õ¥¡¡Ë¤È¤¤¤¦»÷¤¿¤è¤¦¤Ê¥Ð¥Ã¥Õ¥¡¤¬
¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤¿¤Î¤Ç¤¹¤¬ ¥·¥§¡¼¥À¥â¥Ç¥ë5¤«¤éStructuredBuffer¤Ç¤½¤ì¤é¤ò¤Þ¤È¤á¤Æ°·¤¦¤³¤È¤¬¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤è¤¦¤Ç¤¹¡£
¹½Â¤ÂΤǤâÄê¿ô¤Ç¤â¤¤¤±¤ë¤Î¤Çº£¸å¤Ï¥³¥ì¤ò»È¤Ã¤Æ¤È¤¤¤¦¤³¤È¤Ê¤Î¤«¤Ê¡©¡¡
¢¨¡¡º£²ó¤Î¥µ¥ó¥×¥ë¤Ç¤Ï¥«¥á¥éÊý¸þ¤Ë¥Ó¥ë¥Ü¡¼¥É¤Î¥Õ¥§¡¼¥¹Ì̤ò¸þ¤±¤ë½èÍý¤ò¾Êά¤·¤Æ¤¢¤ê¤Þ¤¹
¢£¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
RWStructuredBuffer
¥¹¥ì¥Ã¥É¤Ïº£²ó¤ÎÎã¤À¤È £±¼¡¸µÇÛÎó¤ò»ÈÍѤ¹¤ë¤Î¤Ç ¥¹¥ì¥Ã¥ÉID ¤Ïuint3·¿¤Ç ID.xyz¤Î¤¦¤Á¤Î£±¼¡¸µ¤ÎÍ×ÁÇID.x¤Ç»ØÄꤷ¤Þ¤¹
|
#pragma kernel CSMain RWStructuredBuffer[numthreads(10,1,1)] ¡ã¥¹¥ì¥Ã¥ÉID¤Ï £±¼¡¸µÇÛÎó¤ò»ÈÍѤ¹¤ë¾ì¹ç id.xyz ¤Î¤¦¤Á id.x ¤Ç»ØÄꤹ¤ë Îã¡§ posBuffer[id.x]¡ä |
¼Â¹Ô¥«¡¼¥Í¥ë¤ÎÀë¸À¡¡¡¡¡¡#pragma kernel CSMain
¥¹¥¯¥ê¥×¥È¤«¤é¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À¤Î¥«¡¼¥Í¥ë¤Ë¼Â¹Ô¤ò»ØÄꤹ¤ë»þ¤Ë̾Á°¤ò»ØÄꤷ¤Þ¤¹
RWStructuredBuffer
¹½Â¤ÂΤ¬»ÈÍѲÄǽ¤ÊÆÉ¤ß½ñ¤²Äǽ¤Ê¥Ð¥Ã¥Õ¥¡¡¼
¥ê¥Õ¥¡¥ì¥ó¥¹¤Ë¤è¤ë¤È¡¡register ¡Ê¡Ë¤Ï¾Êά²Äǽ¤È¤¤¤¦²òÀ⤬¤µ¤ì¤Æ¤¤¤¿¤Î¤Ç¤¹¤¬¡¡¤Á¤ç¤Ã¤ÈÀµ³Î¤Ë¤Ï¤ï¤«¤ê¤Þ¤»¤ó
[numthreads(10,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
numthreads ¤¬ Compute Shader 1²óʬ¤Î¥¹¥ì¥Ã¥É¤Î°ÕÌ£¤Ç¤¹¡£
¤³¤ÎÎã¤À¤È10*1*1¡¡=10¥¹¥ì¥Ã¥É¡¡¡¡¿ôÃͤϼ«Í³¤Ë³ä¤êÉÕ¤±¤é¤ì¤Þ¤¹¤¬·×»»Í×ÁǤΥ¹¥¿¥¤¥ë¤Ë±þ¤¸¤Æ
1¼¡¸µ¤«¤é3¼¡¸µ¤Þ¤Ç¤ÎID¤Ë¥¢¥¯¥»¥¹¤·¤ä¤¹¤¤¥µ¥¤¥º¤ò³ä¤êÉÕ¤±¤ë¤È¥¢¥¯¥»¥¹¤¬ÊØÍø¤Ç¤¹¡£¡¡
º£²ó¤Î¾ì¹ç¤Ï¤ï¤«¤ê¤ä¤¹¤¯1¼¡¸µÇÛÎó¤Ë¤·¤Æ¤¢¤ê¤Þ¤¹¡£
ºÇÂ祹¥ì¥Ã¥É¿ô¤Ï¥·¥§¡¼¥À¥Ð¡¼¥¸¥ç¥ó4.0¤Ç786¡¢¥·¥§¡¼¥À¥Ð¡¼¥¸¥ç¥ó5.0¤Ç1024¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
¥·¥§¡¼¥À¥Ð¡¼¥¸¥ç¥ó4.0¤Ç¤Ï£ú¤¬£±¤·¤«¤È¤ì¤Ê¤¤ÅÀ¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£
| Compute Shader | Maximum Z | Maximum Threads (X*Y*Z) |
| cs_4_x | 1 | 768 |
| cs_5_0 | 64 | 1024 |
¢¨¥¹¥ì¥Ã¥ÉºÇÂç¿ô¤Ï¤¢¤¯¤Þ¤ÇÌܰ¤Τ褦¤Ç ´Ä¶¤Ë¤è¤Ã¤Æ¤Ïưºî¤·¤Ê¤¤»ö¤¬¤¢¤ë¤è¤¦¤Ç¤¹¡£ GPU¤ÎÀǽ¤Ê¤Î¤«¥á¡¼¥«¡¼¤Ë¤è¤ëº¹°Û¤Ê¤Î¤«¸¶°ø¤¬ÆÃÄê¤Ç¤¤Æ¤¤¤Þ¤»¤ó¤¬¡¢Æ°ºî¤¬°ÂÄꤷ¤Ê¤¤¾ì¹ç¤Ï¥¹¥ì¥Ã¥É¤Î¿ô¤ò¾¯¤Ê¤á¤ËÀßÄꤹ¤ë¤³¤È¤Ç²þÁ±¤¹¤ë¾ì¹ç¤¬¤¢¤ë¤è¤¦¤Ç¤¹¡£
void CSMain (uint3 id : SV_DispatchThreadID)
¤Û¤«¤Ë¤â¥¹¥ì¥Ã¥É¤Î°ú¿ô¤Ï
¡¡SV_GroupIndex, ¡¡SV_DispatchThreadID, ¡¡SV_GroupThreadID, ¡¡SV_GroupID
¤Ê¤É¤ÎÃͤòÀßÄê½ÐÍè¤Þ¤¹¡£
¤½¤ì¤¾¤ì¤ÎÃͤδط¸¤Ï°Ê²¼¤Î¤È¤ª¤ê

| SV_GroupThreadID | SV_GroupID | SV_DispatchThreadID | SV_GroupIndex |
| x, y, z | x', y', z' | x'*X+x, y'*Y+y, z'*Y+z | z*X*Y+y*X+x |
DX£±£±¥×¥í¥°¥é¥à¤Î¾ÜºÙ¤Ïµ»öÆâ¥ê¥ó¥¯Àè¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤
¥¹¥¯¥ê¥×¥ÈÉô¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¥«¥á¥é¤Ë¥»¥Ã¥È¤·¤Æ»ÈÍѤ¹¤ë¥¹¥¯¥ê¥×¥È¤Î¾ì¹ç¡¡´ðËܤϥ¤¥á¡¼¥¸¥¨¥Õ¥§¥¯¥È¤Î¥¹¥¯¥ê¥×¥È¤ÈƱ¤¸¥¹¥¿¥¤¥ë¤Ë¤Ê¤ê¤Þ¤¹¡£
¡üStart( )¥á¥½¥Ã¥ÉÆâ¤Ç
| particleBuffer = new ComputeBuffer(particleCount, 12); particleBuffer.SetData(particleLocations); |
ComputeBuffer¤Î½é´ü²½¤ò¹Ô¤¤¤Þ¤¹¡¡
ComputeBuffer (ÇÛÎóÁ´ÂΤοô : int, ÇÛÎó¸Ä¡¹¤Î¥µ¥¤¥º : int, type : ComputeBufferType)
º£²ó¤Ï»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó¤¬3ÈÖÌܤΰú¿ô¤Ï¥Ð¥Ã¥Õ¥¡¥¿¥¤¥×¤ò»ØÄê¤Ç¤¤Þ¤¹¡£
SetData()¤ò»ÈÍѤ·¤Æ¡¡ComputeBuffer¤Ë¥¹¥¯¥ê¥×¥È¦¤Î½é´ü²½¤·¤¿ÇÛÎó¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
¡üUpdate( )¥á¥½¥Ã¥ÉÆâ¤Ç
| cs.SetBuffer (cs.FindKernel ("CSMain"), "PosBuffer", ParticleBuffer); |
¥¹¥¯¥ê¥×¥ÈÃæ¤Îcs¤ÏComputeShader¤òÀßÄꤹ¤ëºÝ¤Ë¼«Í³¤Ë̾Á°¤ò³ä¤ê¿¶¤ì¤Þ¤¹¤Î¤Ç
public ComputeShader cs;
¤ÈÀë¸À¤·¤Æ¥¹¥¯¥ê¥×¥È¤¬¾éĹ¤Ë¤Ê¤é¤Ê¤¤¤è¤¦¤Ê̾Á°¤ò¤Ä¤±¤Þ¤¹
cs.SetBuffer (cs.FindKernel ("CSMain"), "PosBuffer", ParticleBuffer);
¡¡¡¡FindKernel ("CSMain")¡¡¤ÏComputeShaderÆâ¤Ç¡É#pragma kernel CSMain¡É¤È¤·¤ÆÀë¸À¤·¤¿Ì¾Á°¤Î¥«¡¼¥Í¥ë¤ò
¡¡¡¡Ãµ¤·¤ÆComputeShader¤Î¥Ð¥Ã¥Õ¥¡¤Ë¥¹¥¯¥ê¥×¥È¤ÇÀßÄꤷ¤¿¥Ð¥Ã¥Õ¥¡¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
¡¡¡¡¤¹¤Ù¤Æ¤Î¥Ç¡¼¥¿¤ò¥»¥Ã¥È¤·½ª¤¨¤¿¤éDispatch( ) ¤ò»ÈÍѤ·¤Æ¥¹¥ì¥Ã¥É·×»»¤ò³«»Ï¤µ¤»¤Þ¤¹¡£
void Dispatch( UINT¡¡x , UINT y , UINT z );
¡¡¡¡°ú¿ô¤Ïuint¡Êint¡Ë·¿¤Ç¡¡ComputeShader¤Ç·×»»¤µ¤»¤ë¥¹¥ì¥Ã¥É¤Î¼¡¿ô¤Ë¤¢¤ï¤»¤Æ¤¯¤À¤µ¤¤
¡üOnRenderImage()¥á¥½¥Ã¥ÉÆâ¤Ç
| mat.SetBuffer("particleBuffer", particleBuffer); Graphics.DrawProcedural (MeshTopology.Triangles, particleCount); |
mat¤Ï¥ì¥ó¥À¥ê¥ó¥°¤Ë»ÈÍѤ¹¤ë¥·¥§¡¼¥À¤ò¼¨¤·¤Þ¤¹¡¡ComputeShader¤Ç·×»»¤µ¤ì¤¿·ë²Ì¤ò
¥ì¥ó¥À¥ê¥ó¥°ÍѤΥ·¥§¡¼¥À¤Ë¥»¥Ã¥È¤·¤Þ¤¹¡£
DrawProcedural ( MeshTopology.Type , particleCount );
MeshTopology.Type ¤Ë¤ÏÉÁ²è¥¹¥¿¥¤¥ë¤òÀßÄꤷ¤Þ¤¹¡¡Triangles | Quads¡¡| Lines¡¡| LineStrip¡¡| Points
¤Ê¤É¤Î¼ïÎब¤¢¤ê¤Þ¤¹¤¬¡¢¡¡º£²ó¤Ï¥·¥§¡¼¥À¦¤Ç¥¸¥ª¥á¥È¥ê¥·¥§¡¼¥À¤ò»ÈÍѤ·¤Æ¥á¥Ã¥·¥åÉÁ²è¤¹¤ë¤¿¤á
ÉÁ²è¤¹¤ë²ó¿ô¡ÊparticleCount ¡á¡¡¥Ñ¡¼¥Æ¥£¥¯¥ë¿ô¡Ë¤À¤±¹ç¤Ã¤Æ¤¤¤ì¤Ð²¿¤ò»ØÄꤷ¤Æ¤â¤è¤¤¤Ç¤¹¡£
DrawProcedural ¡Ê¡¡¡ËÌ¿Îá¤Ï¡¡ÄºÅÀ¥Ç¡¼¥¿¤òGPU¤Î¤ËžÁ÷¤»¤º¤ËľÀÜVRAM¤ËÉÁ²è¤¹¤ëÌ¿Îá¤Ç¤¹¡¡Îà»÷¤ÎÌ¿Îá
DrawProceduralIndirect(¡¡)¤È¤Î°ã¤¤¤Ï
DrawProceduralIndirect(¡¡)¤ÏGPU¦¤«¤é¤Î¥³¡¼¥ë¥Ð¥Ã¥¯¤¬Ìµ¤¤ÅÀ¤Ç¤¹¡£¡Ê¤Ä¤Þ¤ê¥Ç¡¼¥¿¤ÎºÆÍøÍÑÉԲġË
¢£¥³¥ó¥Ô¥å¡¼¥È¥·¥§¡¼¥À»ÈÍÑ»þ¤Î¥Ç¡¼¥¿¤Îή¤ì¤ò°Ê²¼¤Î¿Þ¤Ë¼¨¤·¤Þ¤¹
¢£ ¡ÈParticleController_Sample.cs
using UnityEngine;
using System.Collections;
using System.Threading;
public class ParticleController_Sample : MonoBehaviour {
public Texture2D particleTexture;
public Shader shader;
private Material mat;
public float PScale = 1.0f;
public ComputeShader cs;
public int particleCount = 1000;
public Transform OriginLocation;
private Vector3[] particleLocations;
private Vector3[] particleColors;
private Vector3[] particleVelocities;
private ComputeBuffer particleBuffer;
private ComputeBuffer particleColorBuffer;
private ComputeBuffer velocityBuffer;
Thread csThread;
void Start()
{
particleLocations = new Vector3[particleCount];
particleColors = new Vector3[particleCount];
particleVelocities = new Vector3[particleCount];
for (int i = 0; i < particleCount; i++)
{
particleLocations[i] = OriginLocation.position + Random.insideUnitSphere;
particleVelocities[i] = Random.insideUnitSphere;
particleColors[i] = new Vector3(Random.value,Random.value,Random.value);
}
particleBuffer = new ComputeBuffer(particleCount, 12);
particleBuffer.SetData(particleLocations);
velocityBuffer= new ComputeBuffer(particleCount, 12);
velocityBuffer.SetData (particleVelocities);
particleColorBuffer = new ComputeBuffer(particleCount, 12);
particleColorBuffer.SetData (particleColors);
mat = new Material(shader);
mat.hideFlags = HideFlags.HideAndDontSave;
mat.SetTexture ("_Sprite", particleTexture);
mat.SetFloat ("Size", PScale );
}
private void ReleaseResources()
{
csThread.Abort ();
particleBuffer.Release ();
particleColorBuffer.Release ();
velocityBuffer.Release ();
Object.DestroyImmediate (mat);
}
void OnDisable()
{
ReleaseResources ();
}
void Update()
{
cs.SetFloat ("Time",Time.timeSinceLevelLoad);
cs.SetVector ("Origin", OriginLocation.position);
cs.SetBuffer (cs.FindKernel ("CSMain"), "colBuffer", particleColorBuffer);
cs.SetBuffer (cs.FindKernel ("CSMain"), "posBuffer", particleBuffer);
cs.SetBuffer (cs.FindKernel ("CSMain"), "velBuffer", velocityBuffer);
cs.Dispatch (cs.FindKernel ("CSMain"), particleCount, 1, 1);
}
void OnRenderImage(RenderTexture src, RenderTexture dst)
{
Graphics.Blit( src, dst);
mat.SetBuffer("particleBuffer", particleBuffer);
mat.SetBuffer("particleColor", particleColorBuffer);
mat.SetPass (0);
Graphics.DrawProcedural(MeshTopology.Triangles, particleCount);
}
}
¢£ ¡Écompute_sample.compute¡É
#pragma kernel CSMain
RWStructuredBufferposBuffer : register(u0);
RWStructuredBuffervelBuffer : register(u1);
RWStructuredBuffercolBuffer : register(u2);
float Time;
float4 Origin;
float PI = 3.1415926;
[numthreads(16,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
uint Tid = id.x;
colBuffer[Tid ].r = 0.1;
colBuffer[Tid ].g =1.0;
colBuffer[Tid ].b = 0.4;float3 NewPos;
NewPos.x = Origin.x + (sin(Time/10.0 * Tid ) ) * 30;
NewPos.y = Origin.y + (cos((Time/10.0+PI ) * Tid ) ) *30;
NewPos.z = Origin.z + (cos(Time /10.0 * Tid ) )*30;
velBuffer[Tid ].x = NewPos.x - posBuffer[Tid ].x;
velBuffer[Tid ].y = NewPos.y - posBuffer[Tid ].y;
velBuffer[Tid ].z = NewPos.z - posBuffer[Tid ].z;
posBuffer[Tid ].x += velBuffer[Tid ].x / 40;
posBuffer[Tid ].y += velBuffer[Tid ].y / 40;
posBuffer[Tid ].z += velBuffer[Tid ].z / 40;
}
¢£ ¡ÈRenderParticles.shader¡É
Shader "Custom/RenderParticles" {
Properties {
_Sprite ("Sprite", 2D) = "white" {}
}
SubShader {
Pass{
ZWrite Off ZTest Always Cull Off Fog { Mode Off }
Blend SrcAlpha One
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#include "UnityCG.cginc"
StructuredBufferparticleBuffer;
StructuredBufferparticleColor;
float Size = 0.3f;
sampler2D _Sprite;
struct vs_out {
float4 pos : SV_POSITION;
float4 col : COLOR;
};
vs_out vert (uint id : SV_VertexID)
{
vs_out o;
o.pos =mul(_Object2World, float4(particleBuffer[id], 1.0f));
o.col = float4(particleColor[id], 1.0f);
return o;
}
struct gs_out {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 col : COLOR;
};
[maxvertexcount(4)]
void geom (point vs_out input[1], inout TriangleStreamoutStream)
{
float dx = Size;
float dy = Size * _ScreenParams.x / _ScreenParams.y;
gs_out output;
float4 corLoc = mul(UNITY_MATRIX_MVP, input[0].pos);output.pos = corLoc + float4(-dx, dy,0,0); output.uv=float2(0,0);
output.col = input[0].col; outStream.Append (output);
output.pos = corLoc + float4( dx, dy,0,0); output.uv=float2(1,0);
output.col = input[0].col; outStream.Append (output);
output.pos = corLoc + float4(-dx,-dy,0,0); output.uv=float2(0,1);
output.col = input[0].col; outStream.Append (output);
output.pos = corLoc + float4( dx,-dy,0,0); output.uv=float2(1,1);
output.col = input[0].col; outStream.Append (output);
outStream.RestartStrip();
}
fixed4 frag (gs_out i ) : COLOR0
{
fixed4 col = tex2D(_Sprite, i.uv);
col.a = 0.8f;
col *= i.col;
return col;
}
ENDCG
}
}
Fallback Off
}







