JJONG`sFACTORY
반응형

WebGPU란?

웹 어플리케이션에서 GPU의 기능에 액세스 하기 위한 최신 기술이다.

기존에는 WebGL이 있었지만, 성능적인 제약이 많았다.

벌컨, 메탈, Direct3D 12가 제공하는 API를 기반으로 모방리 및 데스크톱 플랫폼에 고성능을 제공하는 것이 목적이며, 애플, 모질라, 마이크로소프트, 구글 등의 엔지니어들과 함께 개발 되어가고 있다.

 

한 때, canvas를 이용하여 이것저것 해본 경험들이 있었는데 WebGPU 기술을 이용하여서 뭔가 쪼물쪼물 만들어 봐야겠다. 일단 그를 위해서 튜토리얼 먼저 진행을 해 보는 것으로!

 

첫 번째 WebGPU 앱을 통한 튜토리얼 시작. node + ts로 환경 세팅

https://codelabs.developers.google.com/your-first-webgpu-app

 

첫 번째 WebGPU 앱  |  Google Codelabs

이 Codelab에서는 새로운 WebGPU API의 기본사항을 소개합니다. GPU에서 실행되는 Conway's Game of Life의 버전을 빌드하는 방법을 안내합니다. WebGPU의 렌더링 기능은 보드를 그리는 데 사용되고 WebGPU의 컴

codelabs.developers.google.com

일단, 위 글을 토대로 튜토리얼을 진행해 보려고 한다.

typscript를 완벽하게 지원하고, 사용하려면 다음을 참고해서 사용해 주어야 한다.

https://github.com/gpuweb/types 

 

GitHub - gpuweb/types: TypeScript type definitions for WebGPU https://gpuweb.github.io/types/ (NOTE: the WebGPU API itself is st

TypeScript type definitions for WebGPU https://gpuweb.github.io/types/ (NOTE: the WebGPU API itself is still unstable! These types do not directly reflect the implementation status of any browser! ...

github.com

실제로 사용하려면 ts를 이용해야 하고 모듈 형태로 개발 해 두는게 좋으니 테스트 할 환경을 구축해 보도록 하자!

먼저 프로젝트를 하나 만들어 주도록 하자.

bash
npm init

이후, typescript를 사용할 것이기 때문에, webgpu type을 설치해 주자.

bash
npm install --save @webgpu/types

tsconfig.json을 아래와 같이 작성해 주었다.

javascript
{ "compilerOptions": { "target": "ES2022", "module": "ES2022", "outDir": "dist", "typeRoots": [ "./node_modules/@webgpu/types", "./node_modules/@types"] }, "include": [ "src/**/*" ] }

 

이후, src 폴더 하위에, canvas.ts 파일을 생성하고 여기서 부터 작업을 진행해 보기로 했다.

 

캔버스 생성 및 WebGPU 초기화

1. HTML 파일 생성

html
<html> <head> <meta charset="utf-8"> <title>WebGPU Life</title> </head> <body> <canvas width="512" height="512" id="test-canvas"></canvas> <script type="module" src="./test.js"></script> </body> </html>

먼저, 테스트 대상 캔버스를 생성해 줘야 하기 때문에 적당한 곳에 index.html 파일을 생성하고 위와 같이 작성해 주었다.

다음은 test.js 파일 전문.

javascript
import {Canvas} from "../dist/canvas.js" const canvas = Canvas.getInstance() await canvas.init(document.getElementById('test-canvas')) canvas.clearCanvas()

ts로 작성한 파일을 호출하고, canvas Element를 넘겨주게끔 만들어 주었다.

 

2. canvas.ts 파일 작성

javascript
export class Canvas { static #instance; static getInstance() { if (!Canvas.#instance) { Canvas.#instance = new Canvas(); } return Canvas.#instance; } canvas: HTMLCanvasElement; // HTML Canvas Element를 저장하는 곳 adapter:GPUAdapter; // GPUAdapter를 지정. 어댑터는 기기의 특정 GPU 하드웨어를 WebGPU가 표현한 것 device: GPUDevice; // GPU Device와 상호작용하는 인터페이스 context: GPUCanvasContext; // GPU Canvas Context canvasFormat: GPUTextureFormat; // WebGPU에서 캔버스에서 사용할 형식 (기기 유형에 따라 텍스처 형식에 따라 성능 이슈가 있다.) encoder: GPUCommandEncoder; // GPU 명령어를 기록하기 위한 인터페이스 pass: GPURenderPassEncoder; // 어댑터 연결 + 디바이스 연결 + 캔버스 구성 async init(canvas) { this.canvas = canvas if(!navigator.gpu) { throw new Error("WebGPU not supported on this browser.") } this.adapter = await navigator.gpu.requestAdapter() // GPU adapter 요청 if(!this.adapter) { throw new Error("No appropriate GPUAdapter found."); } this.device = await this.adapter.requestDevice() // GPU device 요청 this.context = this.canvas.getContext("webgpu") this.canvasFormat = navigator.gpu.getPreferredCanvasFormat() // 적합한 캔버스 포맷을 gpu에서 알려주기 때문에, 텍스처 형식에 따른 성능 이슈를 없앰 // context에서 사용할 device, format을 설정 this.context.configure({ device: this.device, format: this.canvasFormat }) // encoder 세팅 this.encoder = this.device.createCommandEncoder(); } clearCanvas() { // context.getCurrentTexture => 현재 캔버스 컨텍스트에서 텍스처를 가져옴. width, height, format 등등 // loadOp :: 랜더패스가 시작 되기 전 작업 // storeOp :: 랜더 패스 완료 후 작업. // beginRenderPass :: 랜더 패스 시작 this.pass = this.encoder.beginRenderPass({ colorAttachments: [{ view: this.context.getCurrentTexture().createView(), loadOp: "clear", clearValue:[0,0,0.4,1], storeOp: "store", }] }) this.pass.end() // 명령 버퍼 제출 this.device.queue.submit([this.encoder.finish()]) } }

3. 결과 확인

반응형

'JAVASCRIPT > vanilla' 카테고리의 다른 글

[javascript] DOM 변화를 관측하여 observer 패턴 사용  (0) 2023.11.02
WebGPU(4) - cell 색 지정  (1) 2023.05.17
WebGPU(3) - bindGroup  (0) 2023.05.16
WebGPU(2) - draw rect  (0) 2023.05.16