← 블로그 목록
CanvasWebGL웹 게임게임 개발렌더링

Canvas 2D vs WebGL: 웹 게임을 만들 때 어느 쪽을 골라야 하나

Canvas 2D와 WebGL의 차이를 그리기 방식부터 짚고, 3D 여부·객체 수·학습 비용 기준으로 어떤 상황에서 무엇을 고르는지 정리했습니다.

Vibeollio 팀-

브라우저에서 그림을 그리는 두 가지 길

HTML5로 게임을 만들기로 했다면 처음 만나는 갈림길이 Canvas 2D와 WebGL입니다. 둘 다 같은 <canvas> 요소를 쓰지만, 가져오는 컨텍스트가 다르고 그 뒤의 세계가 완전히 다릅니다.

const ctx = canvas.getContext("2d");    // Canvas 2D
const gl  = canvas.getContext("webgl2"); // WebGL

이 한 줄 차이가 학습 곡선, 성능 한계, 그리고 AI 코딩 도구로 작업할 때의 난이도까지 가릅니다. 어느 쪽이 우월한지가 아니라 어떤 상황에서 무엇을 고르는지의 문제입니다.

Canvas 2D: 명령형으로 그린다

Canvas 2D는 "여기에 사각형을 채워라", "여기에 이미지를 그려라" 같은 명령을 순서대로 실행합니다. 도화지에 붓질하는 것과 같아서 코드를 읽으면 화면이 그려집니다.

ctx.fillStyle = "#d76542";
ctx.fillRect(x, y, 40, 40);        // 사각형
ctx.beginPath();
ctx.arc(x, y, 12, 0, Math.PI * 2); // 원
ctx.fill();
ctx.drawImage(sprite, x, y);       // 이미지

fillRect, arc, drawImage 정도만 알면 첫 화면이 나옵니다. 좌표를 바꾸면 그 자리에서 결과가 보이므로 디버깅도 눈으로 합니다.

AI 코딩 도구와 특히 잘 맞는 것도 이 지점입니다. 명령형 코드는 부분 수정이 쉬워서 "장애물이 위에서도 내려오게 해줘" 같은 요청이 기존 코드에 그대로 이식됩니다.

한계는 CPU가 그린다는 데서 옵니다. 그리기 명령 하나하나가 비용이라 화면에 올리는 객체가 늘어날수록 프레임이 떨어집니다. 정확한 한계치는 객체 종류와 그리기 방식, 기기 성능에 따라 크게 달라지므로 숫자로 못 박기 어렵습니다. 다만 "많아지면 느려진다"는 방향은 분명합니다.

그리고 3D는 불가능합니다. 원근이나 조명이 필요하면 다른 길로 가야 합니다.

WebGL: GPU에 일을 맡긴다

WebGL은 GPU에 직접 접근하는 저수준 API입니다. 정점 데이터를 GPU 메모리에 올려두고, 셰이더라는 작은 프로그램을 GLSL로 작성해 GPU에서 실행시킵니다.

같은 도형을 수천 개 그려도 한 번의 드로우 콜로 처리할 수 있기 때문에, 객체 수가 늘어날 때의 확장성이 Canvas 2D와 근본적으로 다릅니다. 3D 렌더링, 파티클, 화면 전체에 거는 후처리 효과가 모두 이 위에서 가능해집니다.

대가는 진입 비용입니다. 삼각형 하나를 화면에 띄우려 해도 셰이더 컴파일, 버퍼 생성, 속성 연결까지 수십 줄이 필요합니다. 벡터와 행렬 개념도 피할 수 없습니다. GPU에서 벌어지는 일은 콘솔로 찍어볼 수도 없어서, 화면이 검게 나올 때 원인을 좁히기가 훨씬 어렵습니다.

AI 코딩 도구로 셰이더를 생성하면 문법은 대체로 맞지만 의도한 그림이 안 나오는 경우가 있습니다. 이때 무엇이 틀렸는지 판단하려면 결국 파이프라인을 이해하고 있어야 합니다.

대부분은 라이브러리를 쓴다

현실적으로 WebGL을 맨손으로 다루는 경우는 드뭅니다. 렌더링 라이브러리가 보일러플레이트를 감춰주기 때문입니다. 여기서 자주 오해가 생기는데, 요즘 2D 게임 라이브러리들도 내부적으로는 WebGL로 그립니다.

  • Pixi.js: 2D 전용 WebGL 렌더러. Canvas 2D와 비슷한 감각으로 쓰면서 GPU 성능을 얻습니다.
  • Phaser: 2D 게임 프레임워크. 기본 렌더러가 WebGL이고 미지원 환경에서 Canvas로 폴백합니다. 물리, 입력, 씬 관리까지 포함합니다.
  • Three.js: 3D의 사실상 표준. 학습 자료가 가장 많습니다.
  • Babylon.js: 3D 엔진. 기능 범위가 넓고 에디터 도구가 함께 제공됩니다.

즉 "Canvas냐 WebGL이냐"는 실제로는 "직접 그릴 것이냐, 어떤 라이브러리를 쓸 것이냐"로 번역되는 경우가 많습니다.

선택 기준

3D가 필요한가? 필요하면 WebGL 계열로 갑니다. 선택지가 없습니다.

2D인데 객체가 많이 등장하는가? 총알 지옥형 슈팅, 대량 파티클, 타일이 많은 맵이라면 처음부터 Pixi.js나 Phaser로 시작하는 편이 낫습니다. 나중에 옮기려면 렌더링 코드를 전부 다시 써야 합니다.

2D이고 객체가 적은가? Canvas 2D로 직접 씁니다. 의존성이 없어 배포가 단순하고, 로딩이 빠르고, 코드를 전부 이해한 상태로 유지할 수 있습니다. 퍼즐, 카드, 보드, 간단한 액션 게임이 여기 해당합니다.

무엇을 만들지 아직 모르는가? Canvas 2D로 프로토타입을 먼저 만드세요. 재미가 있는지부터 확인하는 게 렌더링 기술을 고르는 것보다 우선입니다.

성능이 문제가 됐을 때 먼저 볼 것

기술을 바꾸기 전에 그리기 방식부터 점검하는 편이 빠릅니다.

Canvas 2D라면 매 프레임 화면 전체를 지우고 다시 그리는 대신 변한 영역만 갱신할 수 있는지, 반복해서 그리는 도형을 오프스크린 캔버스에 미리 그려두고 이미지로 복사할 수 있는지 봅니다. 상태 변경(fillStyle, save/restore)이 잦아도 비용이 붙습니다.

WebGL 계열이라면 드로우 콜을 줄이는 것이 핵심입니다. 같은 텍스처와 재질을 쓰는 객체를 묶어 한 번에 그리고, 스프라이트를 아틀라스 하나로 합쳐 텍스처 교체를 줄입니다.

초보자는 어느 쪽으로 시작해야 하나요?

Canvas 2D입니다. 그리기 명령과 게임 루프라는 개념을 먼저 익히는 편이 순서상 맞습니다. WebGL은 렌더링 파이프라인이라는 별도의 학습 대상이 앞에 있어서, 게임을 만들려다 그래픽스 공부를 하게 되는 경우가 많습니다.

나중에 WebGL로 옮기기 어렵나요?

렌더링 코드는 다시 써야 하지만 게임 로직은 대부분 그대로 씁니다. 충돌 판정, 점수 계산, 입력 처리, 상태 관리는 그리기 방식과 무관하기 때문입니다. 그래서 처음부터 렌더링 코드와 로직을 분리해두면 나중 이전 비용이 크게 줄어듭니다.

둘을 같이 쓸 수 있나요?

가능합니다. 게임 화면은 WebGL로 그리고 점수판이나 메뉴 같은 UI는 별도의 Canvas 2D 또는 그냥 HTML 요소로 겹쳐 올리는 구성이 흔합니다. UI를 HTML로 두면 접근성과 반응형 처리가 훨씬 쉬워집니다.

결론은 만들어보고 정하는 것

문서만 읽고 고르기는 어렵습니다. 같은 게임을 Canvas 2D로 먼저 만들어보면 무엇이 부족한지가 구체적으로 드러나고, 그때 옮길지 말지가 분명해집니다.

만든 게임이 돌아가는 상태라면 Vibeollio에 프로젝트 등록해서 공개해보세요. 브라우저에서 바로 실행되는 게임은 방문자가 설치 없이 눌러볼 수 있어, 내 기기에서는 못 보던 성능 문제가 드러나기도 합니다. 댓글로 들어오는 반응이 다음 버전의 기준이 됩니다.