Canvas 2D와 같은 좌표가 아니다
Canvas 2D에서는 왼쪽 위가 (0, 0)이고 y가 커질수록 아래로 내려간다. 이번 WebGL 예제에서 화면 중심은 (0, 0)이고 x와 y는 -1부터 1까지이며, y가 커지면 위로 올라갔다.
그렇다고 WebGL에 처음 넣는 정점 데이터가 항상 이 좌표계로 고정되는 것은 아니다. 개발자는 월드 좌표나 픽셀 같은 임의의 값을 전달할 수 있다. vertex shader가 최종 클립 공간 위치를 gl_Position으로 출력하고, 원근 나눗셈을 거친 NDC가 화면 중심 (0, 0), 범위 -1~1인 좌표가 된다.
이번 예제는 변환 없이 입력값을 그대로 출력했다.
gl_Position = vec4(a_position, 0.0, 1.0);
그래서 입력한 a_position이 NDC처럼 바로 화면 위치가 됐다.
꼭짓점 하나만 움직여 보기
아래 삼각형에서 A와 B는 고정하고 C의 x만 움직인다. C의 y와 삼각형 색도 그대로 둔다.
A=(-0.72, -0.65)와 B=(0.72, -0.65)는 고정하고,C=(0.0, 0.70)의 x만 바꿉니다.
vertex shader는 각 꼭짓점 위치를 gl_Position으로 결정하고, fragment shader는 삼각형 내부에서 생성된 각 fragment의 색을 계산합니다.
C가 오른쪽으로 움직이면 C와 연결된 A–C, B–C의 방향이 바뀐다. 따라서 A와 B가 같은 자리에 있어도 삼각형의 윤곽은 달라진다.
여기서 기억할 것꼭짓점 좌표가 바뀌면 그 꼭짓점과 연결된 변이 바뀌고, 삼각형 모양도 달라진다.
세 점에서 fragment까지
처음에는 fragment shader가 “점 3개가 모여 생기는 삼각형의 색”을 계산한다고 설명했다. 하지만 세 꼭짓점을 삼각형으로 조립하는 일과 내부를 채우는 일은 서로 다른 단계다.
JavaScript의 꼭짓점 데이터
→ vertex shader가 각 꼭짓점 위치 결정
→ WebGL이 세 꼭짓점을 삼각형으로 조립
→ 삼각형 내부의 fragment 생성
→ fragment shader가 각 fragment의 색 계산
→ 여러 검사를 거쳐 화면의 픽셀로 기록
fragment는 최종 픽셀이 되기 전의 픽셀 후보로 이해했다. 깊이 검사에서 가려지거나 버려질 수 있으므로 fragment 하나를 최종 픽셀 하나와 항상 같다고 단정하지 않는다.
두 shader의 역할 나누기
vertex shader가 각 꼭짓점의 최종 위치를 정한다. C의 x 좌표를 바꾸었을 때 윤곽이 달라진 이유다.
fragment shader는 삼각형 내부에 생성된 각 fragment의 색을 계산한다. 꼭짓점 좌표를 그대로 두고 fragment shader가 반환하는 색만 바꾸면 모양은 유지되고 색만 달라진다.
영어로는 다음과 같이 다시 썼다.
The vertex shader determines the position of each vertex, and the fragment shader calculates the color of each fragment.
색 값 전달과 다시 그리기
JavaScript에서 색을 선택하면 이미 그린 삼각형도 바로 바뀔까? 고정된 삼각형에서 색 선택과 전달 버튼을 따로 실행했다. 색을 선택한 직후에는 변화가 없었고, “shader로 전달하고 다시 그리기”를 눌러야 색이 바뀌었다.
이 예제의 흐름은 JavaScript 값 변경 → uniform 전달 → 다시 그리기다. 이미 준비한 프로그램과 세 꼭짓점 데이터를 사용하는 설명용 코드는 다음과 같다.
gl.useProgram(program);
const colorLocation = gl.getUniformLocation(program, "u_color");
gl.uniform4fv(colorLocation, selectedColor);
gl.drawArrays(gl.TRIANGLES, 0, 3);
uniform4fv는 uniform 값을 지정하고, drawArrays는 준비한 꼭짓점으로 그리기를 요청한다. JavaScript 변수 변경만으로 이 두 호출이 자동 실행되지는 않는다.
이번 fragment shader는 gl_FragColor = u_color로 전달된 색을 그대로 출력한다. 파란색을 전달하면 모든 fragment가 파란색을 출력하므로 삼각형 전체가 파랗게 된다. 다른 shader에서는 uniform을 계산에 사용할 수 있어 출력색이 전달값과 항상 같지는 않다.
여기서 기억할 것JavaScript에서 색을 바꾼 뒤 shader에 전달하고 삼각형을 다시 그려야 화면이 바뀐다.
영어는 첫 시도 뒤 참고 문장을 보고 다음과 같이 다시 썼다.
After changing the color value in JavaScript, we need to pass it to the shader and redraw the triangle.
이번에 확인한 범위
실제 WebGL로 단색 삼각형을 그리고 꼭짓점 하나를 움직였다. Canvas 2D와 NDC의 좌표 방향을 비교하고, vertex shader·삼각형 조립·fragment 생성·fragment shader를 순서대로 구분해 설명했다.
uniform 색 전달과 다시 그리기도 직접 관찰하고 설명했다. 행렬 변환, 보간값, 깊이 검사 구현, 여러 삼각형과 3D 장면은 아직 다루지 않았다. 다음 단계인 WebGPU 장치 준비에서는 준비 성공과 그리기 실행을 먼저 구분한다.