[WebGL] WebGL 알아보기_1
PL 분야 이해를 위해 저번에 OCaml에 대해서 간단히 공부해 보았다. 이제 PL 분야 이외에 컴퓨터 그래픽스 분야에 대해서도 간단히 파보고자 작년에 컴퓨터 그래픽스 강의를 들었던 한학년 선배가 준 강의 자료 및 강의 실습 Github를 통해 WebGL이라는 API에 대해 간단히 알아보았다.
WebGL이란?
WebGL이란 Web Graphics Library의 약자로, 웹에서 2D 그래픽, 또는 3D 그래픽을 그릴 수 있게 해주는 JS API다. 브라우저 상에서 OpenGL을 돌릴 수 있도록 해주며, 작동은 JS 내 canvas에서 작동된다.
브라우저 상에서 작동하므로 OS가 다를 때의 문제나 전용 플러그인의 설치 없이 브라우저 및 하드웨어가 WebGL만 지원한다면 어떤 곳에서든 동일한 코드로 2D, 3D 그래픽을 그릴 수 있는 것이다.
액체 시뮬레이션
레이트레이싱
위 사이트들은 WebGL으로 제작된 사이트들로 별도 설치 없이 3D 그래픽 화면을 볼 수 있을 것이다.
WebGL이 그림을 그리는 과정
WebGL이 그림을 그리는 순서는 다음과 같다.
1.GPU에 넘겨야할 데이터를 정의한다.
2.GPU가 실행해야 할 셰이더를 정의한다.
3.GPU에 데이터를 넘기고, 실제 그리도록 API를 호출한다.
이 과정을 통해 WebGL이 그림을 그리게 된다. 이 과정에서 버퍼(buffer)와 셰이더(Shader)라는 개념이 등장하게 된다.
버퍼, 셰이더
버퍼란 GPU에 데이터를 넘기기 위한 저장소(?) 정도로 생각할 수 있다. CPU에서 만든 데이터를 GPU로 넘기는 공간을 의미한다. 작동은 크게
생성 -> 바인딩 -> 업로드
의 순서로 이뤄지게 된다. 이때 바인딩이란 “이 데이터를 이 버퍼에 넣을거야!”를 지정해주는 역할이라고 볼 수 있다.
셰이더란 GPU에서 실행되는 작은 프로그램으로 GPU가 렌더링하는 과정에서 빛, 어둠, 그림자 등을 계산하는데, 이런 계산 프로그램이라고 볼 수 있다.
셰이더는 정점 셰이더(Vertex Shader)과 프래그먼트 셰이더(fragment Shader)가 있는데, 정점 셰이더란 정점의 변환을 통해 계산하는 프로그램, 프래그먼트 셰이더란 픽셀의 색상을 계산하는 프로그램이다.
우리는 이 둘을 계산하여 넣어주는 것이다.
function main() {
// Get A WebGL context
var canvas = document.querySelector("#c");
var gl = canvas.getContext("webgl2");
if (!gl) {
return;
}
var positions = [
-0.5, -0.5,
0.0, 0.5,
0.5, -0.5,
];
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(positions),
gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT,false,0, 0);
var program = webglUtils.createProgramFromSources(gl, [vertexShaderSource, fragmentShaderSource]);
gl.useProgram(program);
//---Draw Call---//
gl.drawArrays(gl.TRIANGLES,
0,
3);
}
main();
간단한 삼각형을 그리는 예제이다. 먼저 html 코드의 canvas 부분을 선택하고, 해당 canvas가 WebGL을 호출할 수 있는지 확인한다.
이후 posititionBuffer라는 버퍼를 만들어주고, 해당 버퍼를 바인딩한 뒤, 데이터를 넣어준다. 그리고 넣어준 데이터의 첫번째 position의 위치를 활성화시켜주고, 데이터를 읽어오는 방식을 정해준다.
이때 0, 2, gl.FLOAT, false, 0, 0은 순서대로
“0번째 location은 2개의 데이터로 이뤄져있고, 각 데이터는 FLOAT 타입이며, 데이터의 normalization은 필요하지 않고, 데이터는 0byte씩 떨어져 있으며, 0번째 byte부터 읽어라.”
라고 해석할 수 있다.
이후 정점 셰이더와 프래그먼트 셰이더 코드를 받아서 WebGL 프로그램 객체를 만들어준 뒤, 해당 프로그램을 사용하여 그림을 그리라는 명령을 내리게 된다.
그리고 해당 코드를 실행해보면
삼각형 그림이 그려짐을 볼 수 있다!