본문으로 건너뛰기

WebGL & OpenGL

· 약 20분
Dongmin Yu

WebGL: 웹 그래픽 라이브러리(Web Graphics Library)

WebGL은 웹 그래픽 라이브러리(Web Graphics Library)의 약자로, 웹 브라우저에서 상호작용 가능한 3D와 2D 그래픽을 표현하기 위한 JavaScript API입니다. WebGL은 HTML5 <canvas> 요소에서 사용할 수 있는, OpenGL ES 2.0을 대부분 충족하는 API를 제공합니다. WebGL은 플러그인을 사용하지 않고 웹 브라우저에서 상호작용 가능한 3D와 2D 그래픽을 표현하기 위한 JavaScript API입니다.

References

  1. WebGL: 2D and 3D graphics for the web - Web APIs | MDN - Mozilla
  2. WebGL - Web API | MDN
  3. WebGL - Wikipedia

WebGL과 OpenGL

WebGL 1.0은 대부분의 주요 브라우저의 안정적인 릴리즈에서 데스크탑 및 모바일 플랫폼 모두에서 지원됩니다. Chrome, Firefox, Internet Explorer, Opera 및 Safari는 모두 데스크탑 및 모바일 브라우저에서 WebGL 지원이 좋은 것으로 알려져 있습니다. 그러나 사용자의 장치도 WebGL 기능을 지원해야 합니다.

OpenGL ES는 OpenGL for Embedded Systems의 약자로, OpenGL 컴퓨터 그래픽 렌더링 응용 프로그래밍 인터페이스(API)의 하위 집합입니다. 이 API는 비디오 게임에서 사용하는 것과 같은 2D 및 3D 컴퓨터 그래픽을 렌더링하기 위해 설계되었으며 일반적으로 그래픽 처리 장치(GPU)를 사용하여 하드웨어 가속됩니다. 스마트폰, 태블릿 컴퓨터, 비디오 게임 콘솔 및 PDA와 같은 임베디드 시스템용으로 설계되었습니다. OpenGL ES 2.0은 OpenGL ES의 버전 중 하나로, 이전 버전인 OpenGL ES 1.X와 달리 프로그래밍 가능한 셰이딩을 지원합니다. 이는 모바일 그래픽 하드웨어의 최신 세대에서 프로그래막 가능한 셰이더를 노출하는 최초의 이식 가능한 모바일 그래픽 API였습니다.

References

  1. OpenGL ES - Wikipedia
  2. OpenGL ES Overview - The Khronos Group Inc
  3. Khronos OpenGL ES Registry - The Khronos Group Inc

OpenGL ES 2.0

OpenGL ES 2.0은 OpenGL ES의 버전 중 하나로, 이전 버전인 OpenGL ES 1.X와 달리 프로그래밍 가능한 셰이딩을 지원합니다. 이는 모바일 그래픽 하드웨어의 최신 세대에서 프로그래막 가능한 셰이더를 노출하는 최초의 이식 가능한 모바일 그래픽 API였습니다. OpenGL ES 2.0 API에는 다양한 함수와 명령이 정의되어 있습니다. 이러한 함수와 명령은 프로그래머가 고품질의 그래픽 이미지, 특히 3차원 객체의 컬러 이미지를 생성하는 데 필요한 객체와 작업을 지정할 수 있도록 합니다. OpenGL ES 2.0 API에 대한 자세한 정보는 Khronos Group의 웹사이트에서 찾을 수 있습니다.

References

  1. OpenGL ES Overview - The Khronos Group Inc
  2. OpenGL ES 2.0 API Quick Reference Card - Khronos Group
  3. Khronos OpenGL ES Registry - The Khronos Group Inc

OpenGL ES 2.0 API의 주요 함수와 명령

OpenGL ES 2.0 API에는 다양한 함수와 명령이 정의되어 있습니다. 이러한 함수와 명령은 프로그래머가 고품질의 그래픽 이미지, 특히 3차원 객체의 컬러 이미지를 생성하는 데 필요한 객체와 작업을 지정할 수 있도록 합니다. OpenGL ES 2.0 API에 대한 자세한 정보는 Khronos Group의 웹사이트에서 찾을 수 있습니다.

  • glGenBuffers(), glBindBuffer(), glBufferData(), glBufferSubData(): 버퍼 객체 생성 및 데이터 저장
  • glCreateShader(), glShaderSource(), glCompileShader(): 셰이더 생성 및 컴파일
  • glCreateProgram(), glAttachShader(), glLinkProgram(), glUseProgram(): 셰이더 프로그램 생성 및 사용
  • glVertexAttribPointer(), glEnableVertexAttribArray(): 정점 속성 지정
  • glDrawArrays(), glDrawElements(): 기하학적 도형 렌더링

셰이더 프로그램

셰이더 프로그램은 그래픽 파이프라인의 특정 부분에서 실행되는 작은 프로그램입니다. OpenGL ES 2.0에서는 두 가지 유형의 셰이더가 지원됩니다: 버텍스 셰이더와 프래그먼트 셰이더. 버텍스 셰이더는 모든 정점에 대해 실행되며, 정점의 위치와 다른 속성을 계산하는 데 사용됩니다. 프래그먼트 셰이더는 화면에 그려지는 각 픽셀에 대해 실행되며, 픽셀의 최종 색상을 계산하는 데 사용됩니다. 셰이더 프로그램은 버텍스 셰이더와 프래그먼트 셰이더를 결합하여 생성됩니다. 먼저 glCreateShader() 함수를 사용하여 각 셰이더 객체를 생성한 다음, glShaderSource() 함수를 사용하여 셰이더 소스 코드를 지정하고 glCompileShader() 함수를 사용하여 셰이더를 컴파일합니다. 그런 다음 glCreateProgram() 함수를 사용하여 셰이더 프로그램 객체를 생성하고, glAttachShader() 함수를 사용하여 버텍스 셰이더와 프래그먼트 셰이더를 프로그램에 첨부한 다음, glLinkProgram() 함수를 사용하여 프로그램을 링크합니다. 마지막으로 glUseProgram() 함수를 사용하여 링크된 프로그램을 현재 렌더링 상태의 일부로 지정합니다. 셰이더 프로그램을 사용하면 개발자가 그래픽 파이프라인의 중요한 부분을 직접 제어할 수 있어 더욱 유연하고 강력한 그래픽 효과를 만들 수 있습니다. 셰이더 소스 코드는 OpenGL ES 셰이딩 언어(GLSL ES)로 작성됩니다. GLSL ES는 C 언어와 유사한 구문을 가진 고수준 프로그래밍 언어로, 그래픽 처리 장치(GPU)에서 실행되도록 설계되었습니다. 셰이더 소스 코드는 일반적으로 문자열 형태로 작성되며, glShaderSource() 함수를 사용하여 셰이더 객체에 전달됩니다. 각 셰이더 유형(버텍스 셰이더 또는 프래그먼트 셰이더)에 대해 다른 소스 코드가 필요합니다. GLSL ES에는 벡터, 행렬, 텍스처 등과 같은 그래픽 처리에 유용한 데이터 형식과 함수가 포함되어 있습니다. 또한 조건문, 반복문, 함수 정의 등과 같은 일반적인 프로그래밍 구조도 지원됩니다.

간단한 버텍스 셰이더 예제

attribute vec4 a_position;
uniform mat4 u_mvpMatrix;
void main() {
    gl_Position = u_mvpMatrix * a_position;
}

이 버텍스 셰이더는 정점 위치(a_position)를 모델-뷰-투영 행렬(u_mvpMatrix)로 변환하여 최종 정점 위치(gl_Position)를 계산합니다.

precision mediump float;
uniform vec4 u_color;
void main() {
    gl_FragColor = u_color;
}

이 프래그먼트 셰이더는 모든 픽셀의 색상을 동일한 색상(u_color)으로 설정합니다.

Node.js에서 OpenGL을 활용하는 방법

셰이더 소스 코드 작성에 대한 자세한 정보는 OpenGL ES 셰이딩 언어 사양서에서 찾을 수 있습니다. Node.js에서 OpenGL을 활용할 수 있는 몇 가지 라이브러리가 있습니다. 이 중 일부는 다음과 같습니다:

  • node-webgl: 데스크톱 OpenGL에 대한 WebGL 바인딩
  • headless-gl: Node.js에서 windowless WebGL을 제공하는 라이브러리
  • node-glfw: Node.js에서 GLFW 바인딩
  • node-occ: OpenCascade와 NodeJS로 BREP Solids를 구축하는 3D 모델링 라이브러리

References

  1. GitHub - mikeseven/node-webgl: WebGL bindings to desktop OpenGL
  2. 10 Best Node.js Graphics Libraries in 2023 | Openbase
  3. Getting started with WebGL - Web APIs | MDN - Mozilla

WebGL을 기반으로 풍부한 반응형 UI를 제공하는 라이브러리

  • Three.js: WebGL을 사용하여 3D 그래픽을 쉽게 생성할 수 있는 JavaScript 라이브러리
  • Babylon.js: 강력한 3D 엔진으로, WebGL을 사용하여 3D 그래픽을 생성하는 데 사용됩니다
  • A-Frame: 웹에서 가상 현실(VR) 경험을 쉽게 만들 수 있는 웹 프레임워크
  • PlayCanvas: WebGL 기반의 3D 게임 엔진으로, 강력한 툴과 API를 제공합니다

References

  1. List of WebGL frameworks - Wikipedia
  2. 10 Best JavaScript WebGL Libraries in 2023 | Openbase
  3. GitHub - bradtraversy/design-resources-for-developers: Curated list of design and UI ...

Three.js

Three.js는 WebGL을 사용하여 3D 그래픽을 쉽게 생성할 수 있는 JavaScript 라이브러리입니다. 이 라이브러리는 다양한 3D 객체, 재질, 조명, 애니메이션, 카메라 등을 제공하여 개발자가 쉽게 3D 씬을 구성하고 렌더링할 수 있도록 합니다. Three.js는 다양한 형식의 3D 모델을 로드하고, 물리 엔진과 통합하며, 다양한 효과와 포스트 프로세싱 기능을 제공합니다. 이 라이브러리는 웹 브라우저에서 실행되므로, 플러그인이나 추가 설치 없이도 사용자가 쉽게 접근할 수 있습니다. Three.js는 꾸준히 업데이트되고 있으며, 활발한 커뮤니티와 많은 예제 및 문서가 제공됩니다. 이 라이브러리를 사용하면 개발자가 WebGL의 복잡한 세부 사항을 걱정하지 않고도 강력한 3D 그래픽을 쉽게 만들 수 있습니다. Three.js의 공식 웹사이트에는 다양한 예제가 제공됩니다. 이 예제들은 Three.js의 다양한 기능을 보여주며, 개발자가 이 라이브러리를 사용하는 방법을 배울 수 있도록 도와줍니다. 다음은 간단한 Three.js 예제입니다:

// 씬 생성
const scene = new THREE.Scene();
// 카메라 생성
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000,
);
// 렌더러 생성

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 큐브 생성

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 카메라 위치 조정
camera.position.z = 5;
// 애니메이션 루프
function animate() {
  requestAnimationFrame(animate); // 큐브 회전
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01; // 렌더링
  renderer.render(scene, camera);
}
animate();

이 예제는 Three.js를 사용하여 간단한 큐브를 생성하고 회전시키는 방법을 보여줍니다. 먼저 씬, 카메라, 렌더러를 생성하고, 큐브의 기하학과 재질을 정의하여 큐브 메시를 생성합니다. 그런 다음 큐브를 씬에 추가하고, 애니메이션 루프에서 큐브를 회전시키며 렌더링합니다. Three.js의 공식 웹사이트에서는 이보다 훨씬 더 다양하고 복잡한 예제들을 볼 수 있습니다. Three.js를 React 또는 React Native에서 사용하기 위한 몇 가지 래퍼(wrapper) 컴포넌트가 있습니다. 이러한 래퍼 컴포넌트는 Three.js의 기능을 React 컴포넌트로 캡슐화하여 개발자가 쉽게 사용할 수 있도록 합니다. React에서 Three.js를 사용하기 위한 래퍼 컴포넌트 중 일부는 다음과 같습니다:

  • react-three-fiber: Three.js의 선언적 리액트 렌더러
  • threejs-react-wrapper: Three.js 코드를 React 컴포넌트 내에서 실행할 수 있는 간단한 래퍼

React Native에서 Three.js를 사용하기 위한 래퍼 컴포넌트 중 하나는 다음과 같습니다:

  • expo-three: Expo와 함께 사용할 수 있는 Three.js 래퍼

References

  1. Using Three.js in React - Medium
  2. GitHub - felixturner/threejs-react-wrapper
  3. How to develop 3D games with React Native using Three.js

Expo Three JS 모듈

expo-three는 Expo와 함께 사용할 수 있는 Three.js 래퍼입니다. 이 라이브러리는 Expo 앱에서 Three.js의 기능을 쉽게 사용할 수 있도록 지원합니다. expo-three를 사용하면 개발자가 Expo 앱에서 Three.js의 다양한 기능을 사용하여 3D 그래픽을 생성하고 렌더링할 수 있습니다. 이 라이브러리는 Three.js의 기본 객체와 메소드를 지원하며, 추가적으로 Expo의 기능과 통합되어 있습니다. expo-three는 Expo 앱에서 Three.js를 사용하는 데 필요한 추가 설정이나 설치 없이 쉽게 사용할 수 있습니다. 이 라이브러리의 문서와 예제는 GitHub에서 찾을 수 있습니다. expo-three의 GitHub 저장소에는 다양한 예제가 제공됩니다. 이 예제들은 expo-three의 다양한 기능을 보여주며, 개발자가 이 라이브러리를 사용하는 방법을 배울 수 있도록 도와줍니다. 다음은 간단한 expo-three 예제입니다:

import React from "react";
import { View } from "react-native";
import { GLView } from "expo-gl";
import ExpoTHREE, { THREE } from "expo-three";
export default function App() {
  return (
    <View style={{ flex: 1 }}>
           {" "}
      <GLView
        style={{ flex: 1 }}
        onContextCreate={async (gl) => {
          const scene = new THREE.Scene();
          const camera = new THREE.PerspectiveCamera(
            75,

            gl.drawingBufferWidth / gl.drawingBufferHeight,

            0.1,

            1000,
          );
          const renderer = new ExpoTHREE.Renderer({ gl });
          renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
          const geometry = new THREE.BoxGeometry(1, 1, 1);
          const material = new THREE.MeshBasicMaterial({
            color: 0x00ff00,
          });
          const cube = new THREE.Mesh(geometry, material);
          scene.add(cube);
          camera.position.z = 5;
          const animate = () => {
            requestAnimationFrame(animate);
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
            renderer.render(scene, camera);
            gl.endFrameEXP();
          };
          animate();
        }}
      />
         {" "}
    </View>
  );
}

이 예제는 expo-three를 사용하여 간단한 큐브를 생성하고 회전시키는 방법을 보여줍니다. 먼저 씬, 카메라, 렌더러를 생성하고, 큐브의 기하학과 재질을 정의하여 큐브 메시를 생성합니다. 그런 다음 큐브를 씬에 추가하고, 애니메이션 루프에서 큐브를 회전시키며 렌더링합니다. expo-three의 GitHub 저장소에서는 이보다 훨씬 더 다양하고 복잡한 예제들을 볼 수 있습니다.

Three.js의 3D 모델을 공유하는 오픈소스 커뮤니티

Three.js의 3D 모델을 공유하는 오픈소스 커뮤니티가 몇 가지 있습니다. 이러한 커뮤니티에서는 개발자들이 Three.js로 만든 3D 모델을 공유하고, 서로의 작업을 검토하고 피드백을 제공합니다. Three.js의 공식 웹사이트에서는 다양한 예제와 모델이 제공됩니다. 이 예제들은 Three.js의 다양한 기능을 보여주며, 개발자가 이 라이브러리를 사용하는 방법을 배울 수 있도록 도와줍니다. 또한 GitHub에서도 Three.js로 만든 3D 모델을 찾아볼 수 있습니다. 여러 개발자들이 자신의 작업물을 GitHub 저장소에 공유하고 있으며, 이러한 저장소에서는 다양한 종류의 3D 모델을 찾아볼 수 있습니다.

References

  1. Three.js – JavaScript 3D Library
  2. GitHub - mrdoob/three.js: JavaScript 3D Library.
  3. 10 Stunning Open-Source Examples of Three.js In Action - Speckyboy Design Magazine
  4. GitHub - Fasani/three-js-resources: A collection of resources for building 3D projects ...

Three.js의 공식 웹사이트에는 다양한 예제 모델이 제공됩니다. 이 예제들은 Three.js의 다양한 기능을 보여주며, 개발자가 이 라이브러리를 사용하는 방법을 배울 수 있도록 도와줍니다. 예를 들어, Three.js의 공식 웹사이트에서는 다음과 같은 예제 모델들을 볼 수 있습니다:

  • Interactive Cubes: 마우스로 상호작용하는 큐브 모델
  • Clipping with Cap: 클리핑 효과가 적용된 모델
  • Morph Targets: 모핑 타겟 애니메이션이 적용된 모델
  • Lines: 다양한 선 스타일이 적용된 모델

Three.js의 공식 웹사이트에서는 이보다 훨씬 더 다양하고 복잡한 예제 모델들을 볼 수 있습니다. 이러한 예제들은 Three.js의 다양한 기능과 가능성을 보여주며, 개발자가 이 라이브러리를 사용하여 자신만의 3D 모델을 만드는 데 도움이 됩니다.