gpu-io: 웹에서 물리 시뮬레이션을 위한 GPU 가속 컴퓨팅 라이브러리
요약
gpu-io는 WebGL 기반의 GPU 가속 컴퓨팅 라이브러리로, 웹 환경에서 물리 시뮬레이션 및 다양한 계산 집약적 애플리케이션을 쉽게 구현할 수 있도록 돕습니다. 이 라이브러리는 복잡한 WebGL 상태 관리와 보일러플레이트 코드를 추상화하여 개발 편의성을 높였습니다. WebGL 2.0 지원과 함께 구형 브라우저를 위한 폴백 기능 및 GLSL 버전 자동 변환 기능을 제공하여 높은 호환성을 자랑합니다.
핵심 포인트
- 웹에서 물리 시뮬레이션을 위한 GPU 가속 컴퓨팅 라이브러리입니다.
- 복잡한 WebGL 상태 관리와 보일러플레이트 코드를 추상화했습니다.
- WebGL 2.0을 기본으로 하며, 구형 브라우저를 위한 폴백 기능을 제공합니다.
- 다양한 계산 집약적 애플리케이션에 활용 가능하며 낮은 수준의 제어권을 유지합니다.
gpu-io
웹에서 물리 시뮬레이션을 위한 GPU 가속 컴퓨팅 라이브러리
gpu-io는 GPU 가속 컴퓨팅 워크플로우를 쉽게 구성할 수 있도록 돕는 WebGL 라이브러리입니다. 이 라이브러리는 실시간 물리 시뮬레이션, 입자/에이전트 기반 시뮬레이션, 셀룰러 오토마타(cellular automata), 이미지 처리 및 일반 목적의 GPU 연산을 포함한 다양한 애플리케이션에 사용될 수 있습니다. gpu-io는 WebGL 캔버스에 직접 렌더링을 지원하며 상호작용성을 쉽게 구현할 수 있는 몇 가지 내장 기능을 갖추고 있습니다. 자세한 내용은 Examples를 참조하십시오.
WebGL 2.0(사용 가능한 경우)을 위해 설계되었으며, WebGL 1.0을 지원하는 폴백(fallback) 기능을 제공하므로 거의 모든 모바일 또는 구형 브라우저에서 실행될 수 있습니다. WebGPU 지원은 향후 계획되어 있습니다.
동기(Motivation)
gpu-io의 주요 동기는 낮은 수준의 WebGL 세부 사항에 너무 신경 쓰지 않고도 GPU 가속 애플리케이션을 쉽게 구성할 수 있도록 하는 것입니다. 이 라이브러리는 WebGL 상태를 관리하고, 셰이더 및 프로그램 캐싱을 구현하며, 다양한 브라우저/하드웨어 간의 사용 가능한 WebGL 버전 또는 사양 불일치 문제를 처리합니다. 이를 통해 애플리케이션에서 필요한 보일러플레이트 코드(boilerplate code)와 상태 관리를 크게 줄일 수 있습니다. 동시에 gpu-io는 계산 집약적인 애플리케이션을 위해 극도로 효율적인 프로그램을 작성할 수 있을 만큼 충분한 낮은 수준의 제어권을 제공합니다.
2022년 2월 기준으로 WebGL2는 모든 주요 플랫폼(모바일 Safari 및 Microsoft Edge 포함)에 배포되었습니다 [https://www.khronos.org/blog/webgl-2-achieves-pervasive-support-from-all-major-web-browsers] - 하지만 WebGL2 구현체 사이에도 브라우저별로 동작 방식의 차이가 존재합니다(특히 모바일). 게다가, 여전히 WebGL2가 활성화되지 않은 브라우저를 접할 수도 있습니다. gpu-io는 이러한 문제점들을 철저히 확인하며 소프트웨어 폴리필(software polyfills)을 사용하여 모든 문제를 패치하므로 걱정할 필요가 없습니다. 또한 gpu-io는 사용자의 GLSL3 셰이더 코드를 WebGL1에서 사용할 수 있도록 자동으로 GLSL1로 변환하려고 시도합니다. 브라우저 지원에 대한 더 자세한 정보는 tests/README.md를 참조하세요.
설치 (Installation)
npm을 통한 설치
npm install gpu-io
그리고 프로젝트에 가져옵니다:
import { GPUComposer, GPULayer, GPUProgram } from 'gpu-io';
HTML에 포함하기
또는 gpu-io.js 또는 gpu-io.min.js를 HTML에 직접 추가할 수 있습니다:
<html>
<head>
<script src=
```js
import {
GPUComposer,
GPULayer,
...
Demo this code - 노이즈가 서서히 흐릿해지는 것을 볼 수 있으며, 페이지를 새로고침하여 다시 시작할 수 있습니다.
예제 (Examples)
Examples page에서 gpu-io가 어떻게 작동하는지, 그리고 애플리케이션에 터치 상호작용을 쉽게 만드는 방법을 이해해 보세요.
모든 예제의 소스 코드는 examples/ 폴더에서 찾을 수 있습니다.
만약 gpu-io를 사용하여 무언가를 만드셨다면 저에게 알려주세요!
Show and Tell 토론 스레드에 링크를 게시하는 것도 자유입니다. 제가 주기적으로 이 중 일부를 Examples 페이지에도 추가할 것입니다.
API
전체 API 문서는 docs/ 폴더에서 찾을 수 있습니다.
gpu-io용 GLSL 셰이더 작성에 대한 더 많은 정보는 docs/GLSL에서 확인할 수 있습니다.
Threejs와의 호환성 (Compatibility with Threejs)
gpu-io는 Threejs와 webgl 컨텍스트를 공유할 수 있어 두 라이브러리 모두 GPU의 공유 메모리에 접근할 수 있게 합니다:
import THREE from 'three';
import {
GPUComposer,
...
data는 WebGLTextures를 통해 gpu-io와 Threejs 간에 전달됩니다. GPULayer를 Threejs Texture에 바인딩하려면 다음 코드를 사용합니다:
const layer1 = new GPULayer(composer, {
name: 'layer1',
dimensions: [100, 100],
...
gpu-io를 Threejs와 함께 사용하는 방법에 대한 더 많은 정보는 Threejs Example에서 찾을 수 있습니다.
제한 사항/참고 (Limitations/Notes)
제한 사항 (Limitations)
- gpu-io는 현재 1D 또는 2D 배열의 밀집 데이터(dense data)를 가진 GPULayers만 지원합니다. 라이브러리에서 3D 텍스처는 공식적으로 지원되지 않습니다 (예: 현재 3D GPULayer가 없지만, 제가 추가하는 것을 보고 있습니다). gpu-io에서 삼각형 메시(triangle meshes)를 이용한 3D 시뮬레이션을 수행하려면, 3D 위치 데이터를 1D 리스트로 GPULayer에 전달하고 프래그먼트 셰이더(fragment shader)에서 .xyz를 사용하여 접근하기만 하면 됩니다. TODO: 이에 대한 예제를 만듭니다.
- gpu-io는 현재 사용자가 직접 커스텀 버텍스 셰이더(vertex shaders)를 전달하는 것을 허용하지 않습니다. 현재 모든 계산은 사용자 지정 프래그먼트 셰이더에서 이루어지며, 버텍스 셰이더는 내부적으로 관리됩니다.
- WRAP/FILTER 폴리필링(polyfilling)이 올바르게 작동하려면,
texture()호출에는 해당 연산을 수행해야 할 sampler2D에 대한 직접적인 참조가 포함되어야 합니다. 예를 들면:
varying vec2 v_uv;
uniform sampler2D u_sampler1;
...
GLSL 버전
gpu-io는 WebGL2(사용 가능한 경우)를 기본으로 사용하며, GLSL 버전 300 (GLSL3)을 사용하지만, GPUComposer에 contextID 또는 glslVersion 매개변수를 전달하여 WebGL1 또는 GLSL 버전 100 (GLSL1)을 사용하도록 설정할 수 있습니다:
import {
GPUComposer,
GLSL1,
...
더 자세한 정보는 docs>GPUComposer>constructor를 참조하십시오.
gpu-io는 WebGL1을 대상으로 할 때 모든 GLSL3 셰이더를 자동으로 GLSL1로 변환합니다. WebGL1/GLSL1 지원이 중요하다면, GLSL1 Support 문서를 참조하여 gpu-io의 GLSL1 형태에서 사용 가능한 함수/타입/연산자에 대한 추가 정보를 확인하십시오.
Transform Feedback
gpu-io는 GPULayers에서 계산을 처리하기 위해 트랜스폼 피드백(transform feedback)을 사용하지 않는 것을 알 수 있습니다. 트랜스폼 피드백은 파티클 시뮬레이션이나 픽셀 레벨이 아닌 버텍스 레벨에서 계산되는 다른 유형의 물리 현상에 매우 유용합니다. gpu-io를 사용하여 이러한 유형의 시뮬레이션을 수행하는 것은 여전히 가능하지만(예시 참조: Examples), 현재 모든 계산은 프래그먼트 셰이더(fragment shader)에서 이루어집니다. 여기에는 몇 가지 이유가 있습니다:
- gpu-io의 주요 사용 사례는 텍스처에 저장된 2D 공간 분산 상태(즉, 필드)를 프래그먼트 셰이더로 조작하는 것입니다. 1D 배열 및 라인/파티클에 대한 추가 지원도 있지만, 이는 부차적인 기능입니다.
- 트랜스폼 피드백은 WebGL2에서만 지원됩니다. 제가 2020년에 이 글을 작성하기 시작했을 때, 모바일 Safari에서는 WebGL2가 지원되지 않았습니다. 최근에는 상황이 바뀌었지만, 현재로서는 gpu-io의 모든 기능을 WebGL1/GLSL1에서도 지원하고 싶습니다.
- 계산을 프래그먼트 셰이더로만 제한하면 API가 더 간단해집니다.
현재 계획은 WebGPU가 일부 브라우저에서 기본적으로 공식 출시되기를 기다린 후, gpu-io에 적용된 몇 가지 설계 결정을 재평가하는 것입니다. WebGL은 일반 목적 컴퓨팅을 컴퓨트 파이프라인(compute pipeline) 대신 버텍스 및 프래그먼트 셰이더 렌더링 파이프라인에서 발생하도록 강제함으로써 현재 API에 인위적인 제약을 가합니다. 따라서 장기적으로는 WebGL에서 벗어나고 싶으며, 이 시점에서 트랜스폼 피드백을 사용하는 것은 한 발짝 뒤로 물러나는 느낌입니다.
정밀도 (Precision)
gpu-io의 모든 셰이더는 기본적으로 highp 정밀도의 부동 소수점(float) 및 정수(int)로 초기화되지만, highp가 사용 불가능할 경우 mediump로 폴백됩니다(이는 Threejs에서 사용되는 것과 동일한 규칙입니다). 더 자세한 내용은 src/glsl/common/precision.ts를 참조하십시오.
GPUComposer의 생성자에서 intPrecision과 floatPrecision을 지정하여 이러한 기본값을 재정의할 수 있습니다:
import {
GPUComposer,
PRECISION_LOW_P,
...
물론, 셰이더 코드 내 특정 변수의 정밀도(precision)를 수동으로 지정할 수도 있습니다:
in vec2 v_uv;
// u_state는 BYTE 배열이므로, lowp로 정밀도를 설정할 수 있습니다.
...
참고: 셰이더 코드에 highp가 지정되어 있더라도, 현재 브라우저가 highp를 지원하지 않으면 gpu-io는 mediump로 변환합니다 (대안은 오류를 발생시키는 것입니다).
또한, 기기에서 mediump의 정밀도를 테스트하고 highp 지원 여부를 판단하기 위해 다음과 같은 헬퍼 함수도 포함했습니다:
import {
isHighpSupportedInVertexShader,
isHighpSupportedInFragmentShader,
...
감사의 글 (Acknowledgements)
이 문서를 작성하면서 몇 가지 코드베이스를 참고했으며, 이 레포지토리를 공개해 주신 저자분들께 감사드립니다:
기타 자료:
- Mozilla의 WebGL 모범 사례 (best practices)
- Shadertoy / webGLSL의 호환성 문제 Shadertoy – 비공식
라이선스 (License)
본 작업은 MIT 라이선스에 따라 배포됩니다. gpu-io는 몇 가지 npm 패키지에 의존한다는 점에 유의하십시오:
- @amandaghassaei/type-checks - MIT 라이선스, 의존성 없음.
- @petamoriken/float16 - MIT 라이선스, 의존성 없음.
- changedpi - MIT 라이선스, 의존성 없음.
- file-saver - MIT 라이선스, 의존성 없음.
개발 현황 (Development)
2022년 10월 업데이트: 저는 방향을 조금 바꿔서 새로운 프로젝트에 집중할 예정이지만, 제가 작업하는 거의 모든 것에 gpu-io를 기반으로 계속 사용할 것입니다. 앞으로 약 6개월 동안 이 라이브러리에 몇 가지 새로운 기능이 추가될 것으로 예상하지만, 여러분이 겪을 수 있는 문제의 디버깅 시간을 보장할 수는 없습니다. issue를 남기거나 질문을 하셔도 좋지만, 즉각적인 답변은 기대하지 마세요! 이 라이브러리를 사용하는 방법에 대한 더 많은 정보는 예제(Examples)를 참고하세요.
풀 리퀘스트(Pull requests) 환영합니다! 제가 만든 것이 다른 사람들에게 유용하기를 바라지만, 이 코드가 진행 방향에 영향을 미친 저의 매우 구체적인 필요 사항들이 있다는 것도 알고 있습니다 – 그래서 지켜봐야 할 것 같습니다. 만약 이것을 사용하게 된다면 저에게 알려주세요. 여러분이 무엇을 만들고 계신지 보고 싶습니다!
Webpack으로 컴파일하기
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub GameDev의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기