WebGL ๋ฉ์ ์ ฐ์ด๋ ์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ์ GPU ์ค๋ ๋ ๊ตฌ์ฑ์ ๋ณต์ก์ฑ์ ํ๊ตฌํฉ๋๋ค. ๋ค์ํ ํ๋์จ์ด์์ ์ต๋์ ์ฑ๋ฅ๊ณผ ํจ์จ์ฑ์ ์ํ ์ฝ๋ ์ต์ ํ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
WebGL ๋ฉ์ ์ ฐ์ด๋ ์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ: GPU ์ค๋ ๋ ๊ตฌ์ฑ ์ฌ์ธต ๋ถ์
๋ฉ์ ์ ฐ์ด๋๋ WebGL ๊ทธ๋ํฝ ํ์ดํ๋ผ์ธ์์ ์ค์ํ ๋ฐ์ ์ ์๋ฏธํ๋ฉฐ, ๊ฐ๋ฐ์์๊ฒ ์ง์ค๋ฉํธ๋ฆฌ ์ฒ๋ฆฌ ๋ฐ ๋ ๋๋ง์ ๋ํ ๋ ์ธ๋ฐํ ์ ์ด๊ถ์ ์ ๊ณตํฉ๋๋ค. GPU์์ ์ํฌ๊ทธ๋ฃน๊ณผ ์ค๋ ๋๊ฐ ์ด๋ป๊ฒ ๊ตฌ์ฑ๋๊ณ ๋ฐฐํฌ๋๋์ง ์ดํดํ๋ ๊ฒ์ ์ด ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ฑ๋ฅ ์ด์ ์ ๊ทน๋ํํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์์๋ WebGL ๋ฉ์ ์ ฐ์ด๋ ์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ์ GPU ์ค๋ ๋ ๊ตฌ์ฑ์ ๋ํด ์ฌ์ธต์ ์ผ๋ก ํ๊ตฌํ๋ฉฐ, ํต์ฌ ๊ฐ๋ , ์ต์ ํ ์ ๋ต ๋ฐ ์ค์ ์์ ๋ฅผ ๋ค๋ฃน๋๋ค.
๋ฉ์ ์ ฐ์ด๋๋ ๋ฌด์์ธ๊ฐ?
์ ํต์ ์ธ WebGL ๋ ๋๋ง ํ์ดํ๋ผ์ธ์ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ ์ (vertex) ๋ฐ ํ๋๊ทธ๋จผํธ(fragment) ์ ฐ์ด๋์ ์์กดํฉ๋๋ค. ํ์ฅ ๊ธฐ๋ฅ์ผ๋ก ๋์ ๋ ๋ฉ์ ์ ฐ์ด๋๋ ๋ ์ ์ฐํ๊ณ ํจ์จ์ ์ธ ๋์์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๊ณ ์ ํจ์ ์ ์ ์ฒ๋ฆฌ ๋ฐ ํ ์ ๋ ์ด์ ๋จ๊ณ๋ฅผ ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ฅํ ์ ฐ์ด๋ ๋จ๊ณ๋ก ๋์ฒดํ์ฌ ๊ฐ๋ฐ์๊ฐ GPU์์ ์ง์ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ์กฐ์ํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ ํนํ ํ๋ฆฌ๋ฏธํฐ๋ธ ์๊ฐ ๋ง์ ๋ณต์กํ ์ฅ๋ฉด์์ ์๋นํ ์ฑ๋ฅ ํฅ์์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๋ฉ์ ์ ฐ์ด๋ ํ์ดํ๋ผ์ธ์ ๋ ๊ฐ์ง ์ฃผ์ ์ ฐ์ด๋ ๋จ๊ณ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค:
- ํ์คํฌ ์ ฐ์ด๋ (์ ํ ์ฌํญ): ํ์คํฌ ์ ฐ์ด๋๋ ๋ฉ์ ์ ฐ์ด๋ ํ์ดํ๋ผ์ธ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์ ๋๋ค. ๋ฉ์ ์ ฐ์ด๋๋ก ๋์คํจ์น๋ ์ํฌ๊ทธ๋ฃน์ ์๋ฅผ ๊ฒฐ์ ํ๋ ์ญํ ์ ํฉ๋๋ค. ๋ฉ์ ์ ฐ์ด๋๊ฐ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ์ปฌ๋งํ๊ฑฐ๋ ์ธ๋ถํํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ๋ฉ์ ์ ฐ์ด๋: ๋ฉ์ ์ ฐ์ด๋๋ ๋ฉ์ ์ ฐ์ด๋ ํ์ดํ๋ผ์ธ์ ํต์ฌ ๋จ๊ณ์ ๋๋ค. ์ ์ ๊ณผ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ฅผ ์์ฑํ๋ ์ญํ ์ ํฉ๋๋ค. ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ ๋์ผํ ์ํฌ๊ทธ๋ฃน ๋ด์ ์ค๋ ๋ ๊ฐ์ ํต์ ํ ์ ์์ต๋๋ค.
์ํฌ๊ทธ๋ฃน๊ณผ ์ค๋ ๋ ์ดํดํ๊ธฐ
์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ ์ ์ GPU ์ปดํจํ ์ ๋งฅ๋ฝ์์ ์ํฌ๊ทธ๋ฃน๊ณผ ์ค๋ ๋์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ํฌ๊ทธ๋ฃน
์ํฌ๊ทธ๋ฃน์ GPU ์ปดํจํ
์ ๋์์ ๋์์ ์คํ๋๋ ์ค๋ ๋์ ๋ชจ์์
๋๋ค. ์ํฌ๊ทธ๋ฃน ๋ด์ ์ค๋ ๋๋ค์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํตํด ์๋ก ํต์ ํ ์ ์์ด, ์์
์ ํ๋ ฅํ๊ณ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ณต์ ํ ์ ์์ต๋๋ค. ์ํฌ๊ทธ๋ฃน์ ํฌ๊ธฐ(ํฌํจ๋ ์ค๋ ๋ ์)๋ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น๋ ์ค์ํ ๋งค๊ฐ๋ณ์์
๋๋ค. ์ด๋ ์
ฐ์ด๋ ์ฝ๋์์ layout(local_size_x = N, local_size_y = M, local_size_z = K) in; ํ์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ์๋๋ฉฐ, ์ฌ๊ธฐ์ N, M, K๋ ์ํฌ๊ทธ๋ฃน์ ์ฐจ์์
๋๋ค.
์ต๋ ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ๋ ํ๋์จ์ด์ ๋ฐ๋ผ ๋ค๋ฅด๋ฉฐ, ์ด ํ๊ณ๋ฅผ ์ด๊ณผํ๋ฉด ์ ์๋์ง ์์ ๋์์ด ๋ฐ์ํฉ๋๋ค. ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ์ ์ผ๋ฐ์ ์ธ ๊ฐ์ 2์ ๊ฑฐ๋ญ์ ๊ณฑ(์: 64, 128, 256)์ด๋ฉฐ, ์ด๋ GPU ์ํคํ ์ฒ์ ์ ๋ง์๋จ์ด์ง๋ ๊ฒฝํฅ์ด ์์ต๋๋ค.
์ค๋ ๋ (์ธ๋ณด์ผ์ด์ )
์ํฌ๊ทธ๋ฃน ๋ด์ ๊ฐ ์ค๋ ๋๋ ์ธ๋ณด์ผ์ด์
(invocation)์ด๋ผ๊ณ ๋ ๋ถ๋ฆฝ๋๋ค. ๊ฐ ์ค๋ ๋๋ ๋์ผํ ์
ฐ์ด๋ ์ฝ๋๋ฅผ ์คํํ์ง๋ง ๋ค๋ฅธ ๋ฐ์ดํฐ์ ๋ํด ์๋ํฉ๋๋ค. gl_LocalInvocationID ๋ด์ฅ ๋ณ์๋ ๊ฐ ์ค๋ ๋์ ์ํฌ๊ทธ๋ฃน ๋ด์์ ๊ณ ์ ํ ์๋ณ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ์๋ณ์๋ (0, 0, 0)์์ (N-1, M-1, K-1) ๋ฒ์์ 3D ๋ฒกํฐ์ด๋ฉฐ, ์ฌ๊ธฐ์ N, M, K๋ ์ํฌ๊ทธ๋ฃน ์ฐจ์์
๋๋ค.
์ค๋ ๋๋ ์ํ(warp) ๋๋ ์จ์ด๋ธํ๋ก ํธ(wavefront)๋ก ๊ทธ๋ฃนํ๋๋ฉฐ, ์ด๋ GPU์์ ์คํ์ ๊ธฐ๋ณธ ๋จ์์ ๋๋ค. ์ํ ๋ด์ ๋ชจ๋ ์ค๋ ๋๋ ๋์์ ๋์ผํ ๋ช ๋ น์ ์คํํฉ๋๋ค. ๋ง์ฝ ์ํ ๋ด์ ์ค๋ ๋๋ค์ด (๋ถ๊ธฐ๋ก ์ธํด) ๋ค๋ฅธ ์คํ ๊ฒฝ๋ก๋ฅผ ํํ๋ฉด, ์ผ๋ถ ์ค๋ ๋๋ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์คํ๋๋ ๋์ ์ผ์์ ์ผ๋ก ๋นํ์ฑํ๋ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํ ๋ค์ด๋ฒ์ ์ค(warp divergence)๋ผ๊ณ ํ๋ฉฐ ์ฑ๋ฅ์ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค.
์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ
์ํฌ๊ทธ๋ฃน ๋ฐฐํฌ๋ 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)์ ๋ฐฐ์์ธ ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ๋ฅผ ์ ํํ์ญ์์ค. ์ด๋ ์ํ ๋ค์ด๋ฒ์ ์ค๋ฅผ ์ต์ํํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋: ์ ฐ์ด๋๊ฐ ํ์๋ก ํ๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์์ ๊ณ ๋ คํ์ญ์์ค. ๋ ํฐ ์ํฌ๊ทธ๋ฃน์ ๋ ๋ง์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์๋ก ํ ์ ์์ผ๋ฉฐ, ์ด๋ ๋์์ ์คํ๋ ์ ์๋ ์ํฌ๊ทธ๋ฃน์ ์๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
- ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ: ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์กฐ๊ฐ ํน์ ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ๋ฅผ ์ง์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ถ์(reduction) ์ฐ์ฐ์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ 2์ ๊ฑฐ๋ญ์ ๊ณฑ์ธ ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ์์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค.
์์: ๋์ ํ๋์จ์ด์ ์ํ ํฌ๊ธฐ๊ฐ 32์ด๊ณ ์๊ณ ๋ฆฌ์ฆ์ด ๋ก์ปฌ ์ถ์๋ก ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ฉํ๋ค๋ฉด, ์ํฌ๊ทธ๋ฃน ํฌ๊ธฐ๋ฅผ 64 ๋๋ 128๋ก ์์ํ๋ ๊ฒ์ด ์ข์ ์ ๊ทผ ๋ฐฉ์์ผ ์ ์์ต๋๋ค. WebGL ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์ง์คํฐ ์ฌ์ฉ๋์ ๋ชจ๋ํฐ๋งํ์ฌ ๋ ์ง์คํฐ ์๋ฐ์ด ๋ณ๋ชฉ์ด ๋์ง ์๋๋ก ํ์ญ์์ค.
์ํ ๋ค์ด๋ฒ์ ์ค ์ต์ํ
์ํ ๋ค์ด๋ฒ์ ์ค๋ ์ํ ๋ด์ ์ค๋ ๋๋ค์ด ๋ถ๊ธฐ๋ก ์ธํด ๋ค๋ฅธ ์คํ ๊ฒฝ๋ก๋ฅผ ํํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด๋ GPU๊ฐ ๊ฐ ๋ถ๊ธฐ๋ฅผ ์์ฐจ์ ์ผ๋ก ์คํํด์ผ ํ๊ณ ์ผ๋ถ ์ค๋ ๋๋ ์ผ์์ ์ผ๋ก ๋นํ์ฑํ๋๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ํฌ๊ฒ ์ ํ์ํฌ ์ ์์ต๋๋ค. ์ํ ๋ค์ด๋ฒ์ ์ค๋ฅผ ์ต์ํํ๋ ค๋ฉด:
- ์กฐ๊ฑด๋ถ ๋ถ๊ธฐ ํผํ๊ธฐ: ์ ฐ์ด๋ ์ฝ๋ ๋ด์์ ๊ฐ๋ฅํ ํ ์กฐ๊ฑด๋ถ ๋ถ๊ธฐ๋ฅผ ํผํ๋ ค๊ณ ๋ ธ๋ ฅํ์ญ์์ค. ๋ถ๊ธฐ ์์ด ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ํด ์์ธก(predication)์ด๋ ๋ฒกํฐํ(vectorization)์ ๊ฐ์ ๋์ ๊ธฐ์ ์ ์ฌ์ฉํ์ญ์์ค.
- ์ ์ฌํ ์ค๋ ๋ ๊ทธ๋ฃนํ: ๋์ผํ ์ํ ๋ด์ ์ค๋ ๋๋ค์ด ๋์ผํ ์คํ ๊ฒฝ๋ก๋ฅผ ํํ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋๋ก ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์ฑํ์ญ์์ค.
์์: `if` ๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ณ์์ ์กฐ๊ฑด๋ถ๋ก ๊ฐ์ ํ ๋นํ๋ ๋์ , ๋ถ๋ฆฌ์ธ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ ๊ฐ ์ฌ์ด์ ์ ํ ๋ณด๊ฐ์ ์ํํ๋ `mix` ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
float value = mix(value1, value2, condition);
์ด๋ ๊ฒ ํ๋ฉด ๋ถ๊ธฐ๊ฐ ์ ๊ฑฐ๋๊ณ ์ํ ๋ด์ ๋ชจ๋ ์ค๋ ๋๊ฐ ๋์ผํ ๋ช
๋ น์ ์คํํ๊ฒ ๋ฉ๋๋ค.
๊ณต์ ๋ฉ๋ชจ๋ฆฌ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๊ธฐ
๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ ์ํฌ๊ทธ๋ฃน ๋ด ์ค๋ ๋๋ค์ด ํต์ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ์ ํ๋ ๋ฆฌ์์ค์ด๋ฏ๋ก ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ต์ํ: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํ์๋ฅผ ๊ฐ๋ฅํ ํ ์ค์ด์ญ์์ค. ์์ฃผ ์ฌ์ฉ๋๋ ๋ฐ์ดํฐ๋ ๋ ์ง์คํฐ์ ์ ์ฅํ์ฌ ๋ฐ๋ณต์ ์ธ ์ ๊ทผ์ ํผํ์ญ์์ค.
- ๋ฑ ํฌ ์ถฉ๋ ํผํ๊ธฐ: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฑ ํฌ(bank)๋ก ๊ตฌ์ฑ๋๋ฉฐ, ๋์ผํ ๋ฑ ํฌ์ ๋ํ ๋์ ์ ๊ทผ์ ๋ฑ ํฌ ์ถฉ๋๋ก ์ด์ด์ ธ ์ฑ๋ฅ์ ํฌ๊ฒ ์ ํ์ํฌ ์ ์์ต๋๋ค. ๋ฑ ํฌ ์ถฉ๋์ ํผํ๋ ค๋ฉด ์ค๋ ๋๋ค์ด ๊ฐ๋ฅํ ๋๋ง๋ค ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ๋ค๋ฅธ ๋ฑ ํฌ์ ์ ๊ทผํ๋๋ก ํ์ญ์์ค. ์ด๋ ์ข ์ข ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ํจ๋ฉ์ ์ถ๊ฐํ๊ฑฐ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์์๋ฅผ ์ฌ๋ฐฐ์ดํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
์์: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์์ ์ถ์ ์ฐ์ฐ์ ์ํํ ๋, ๋ฑ ํฌ ์ถฉ๋์ ํผํ๊ธฐ ์ํด ์ค๋ ๋๋ค์ด ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ๋ค๋ฅธ ๋ฑ ํฌ์ ์ ๊ทผํ๋๋ก ํ์ญ์์ค. ์ด๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ์ด์ ํจ๋ฉ์ ์ถ๊ฐํ๊ฑฐ๋ ๋ฑ ํฌ ์์ ๋ฐฐ์์ธ ์คํธ๋ผ์ด๋(stride)๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
์ํฌ๊ทธ๋ฃน ๋ก๋ ๋ฐธ๋ฐ์ฑ
์ํฌ๊ทธ๋ฃน ๊ฐ์ ์์ ์ด ๊ณ ๋ฅด์ง ์๊ฒ ๋ถ๋ฐฐ๋๋ฉด ์ฑ๋ฅ ๋ณ๋ชฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์ผ๋ถ ์ํฌ๊ทธ๋ฃน์ ๋นจ๋ฆฌ ๋๋์ง๋ง ๋ค๋ฅธ ์ํฌ๊ทธ๋ฃน์ ํจ์ฌ ๋ ์ค๋ ๊ฑธ๋ ค ์ผ๋ถ ์ปดํจํ ์ ๋์ด ์ ํด ์ํ๋ก ๋จ๊ฒ ๋ฉ๋๋ค. ๋ก๋ ๋ฐธ๋ฐ์ฑ์ ๋ณด์ฅํ๋ ค๋ฉด:
- ์์ ์ ๊ณ ๋ฅด๊ฒ ๋ถ๋ฐฐ: ๊ฐ ์ํฌ๊ทธ๋ฃน์ด ๊ฑฐ์ ๋์ผํ ์์ ์์ ์ ์ํํ๋๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ์ญ์์ค.
- ๋์ ์์ ํ ๋น ์ฌ์ฉ: ์ฅ๋ฉด์ ๋ค๋ฅธ ๋ถ๋ถ ๊ฐ์ ์์ ๋์ด ํฌ๊ฒ ๋ค๋ฅธ ๊ฒฝ์ฐ, ๋์ ์์ ํ ๋น์ ์ฌ์ฉํ์ฌ ์ํฌ๊ทธ๋ฃน์ ๋ ๊ณ ๋ฅด๊ฒ ๋ถ๋ฐฐํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ์ ํด ์ํฌ๊ทธ๋ฃน์ ์์ ์ ํ ๋นํ๊ธฐ ์ํด ์์์ ์ฐ์ฐ(atomic operations)์ ์ฌ์ฉํ๋ ๊ฒ์ ํฌํจํ ์ ์์ต๋๋ค.
์์: ๋ค๊ฐํ ๋ฐ๋๊ฐ ๋ค์ํ ์ฅ๋ฉด์ ๋ ๋๋งํ ๋, ํ๋ฉด์ ํ์ผ๋ก ๋๋๊ณ ๊ฐ ํ์ผ์ ์ํฌ๊ทธ๋ฃน์ ํ ๋นํ์ญ์์ค. ํ์คํฌ ์ ฐ์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ํ์ผ์ ๋ณต์ก๋๋ฅผ ์ถ์ ํ๊ณ ๋ณต์ก๋๊ฐ ๋์ ํ์ผ์ ๋ ๋ง์ ์ํฌ๊ทธ๋ฃน์ ํ ๋นํ์ญ์์ค. ์ด๋ ๋ชจ๋ ์ปดํจํ ์ ๋์ด ์์ ํ ํ์ฉ๋๋๋ก ํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์ปฌ๋ง ๋ฐ ์ฆํญ์ ์ํ ํ์คํฌ ์ ฐ์ด๋ ๊ณ ๋ ค
ํ์คํฌ ์ ฐ์ด๋๋ ์ ํ ์ฌํญ์ด์ง๋ง, ๋ฉ์ ์ ฐ์ด๋ ์ํฌ๊ทธ๋ฃน์ ๋์คํจ์น๋ฅผ ์ ์ดํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋ค์์ ํตํด ์ฑ๋ฅ์ ์ต์ ํํ๊ธฐ ์ํด ์ ๋ต์ ์ผ๋ก ์ฌ์ฉํ์ญ์์ค:
- ์ปฌ๋ง: ๋ณด์ด์ง ์๊ฑฐ๋ ์ต์ข ์ด๋ฏธ์ง์ ํฌ๊ฒ ๊ธฐ์ฌํ์ง ์๋ ์ํฌ๊ทธ๋ฃน์ ํ๊ธฐํฉ๋๋ค.
- ์ฆํญ: ์ฅ๋ฉด์ ํน์ ์์ญ์์ ๋ํ ์ผ ์์ค์ ๋์ด๊ธฐ ์ํด ์ํฌ๊ทธ๋ฃน์ ์ธ๋ถํํฉ๋๋ค.
์์: ํ์คํฌ ์ ฐ์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์ ์ ฐ์ด๋๋ก ๋์คํจ์นํ๊ธฐ ์ ์ ๋ฉ์ค๋ฆฟ(meshlet)์ ๋ํด ์ ๋์ฒด ์ปฌ๋ง(frustum culling)์ ์ํํ์ญ์์ค. ์ด๋ ๋ฉ์ ์ ฐ์ด๋๊ฐ ๋ณด์ด์ง ์๋ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ๊ท์คํ 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 ๊ทธ๋ํฝ์ ํ๊ณ๋ฅผ ๋ฐ์ด๋์ผ๋ ค๋ ๋ชจ๋ ๊ฐ๋ฐ์์๊ฒ ํ์์ ์ผ ๊ฒ์ ๋๋ค. ์คํ, ํ๋กํ์ผ๋ง, ๊ทธ๋ฆฌ๊ณ ์ง์์ ์ธ ํ์ต์ ์ด ๊ธฐ์ ์ ๋ง์คํฐํ๊ณ ๊ทธ ์ ์ฌ๋ ฅ์ ์ต๋ํ ๋ฐํํ๋ ์ด์ ์ ๋๋ค.
์ถ๊ฐ ์๋ฃ
- ํฌ๋ก๋ ธ์ค ๊ทธ๋ฃน - ๋ฉ์ ์ ฐ์ด๋ฉ ํ์ฅ ์ฌ์: [https://www.khronos.org/](https://www.khronos.org/)
- WebGL ์ํ: [๊ณต๊ฐ WebGL ๋ฉ์ ์ ฐ์ด๋ ์์ ๋๋ ๋ฐ๋ชจ ๋งํฌ ์ ๊ณต]
- ๊ฐ๋ฐ์ ํฌ๋ผ: [WebGL ๋ฐ ๊ทธ๋ํฝ ํ๋ก๊ทธ๋๋ฐ ๊ด๋ จ ํฌ๋ผ ๋๋ ์ปค๋ฎค๋ํฐ ์ธ๊ธ]