WebGL 기초( 4 - Shader 이해 & 색상 채우기 )

WebGL 기초( 4 - Shader 이해 & 색상 채우기 )

이번에는 Shader에서 알아보고
삼각형에 색상을 그라이데이션으로 넣어보는 작업을 하도록 하겠습니다.

Shader의 이해

GPU는 아래와 같이 2가지 일을 합니다.

  1. 원본의 정점을 클립공간 정점으로 처리
  2. 클립공간을 pixel로 처리

vertexShader 셰이더와 fragmentShader는 GPU가 이러한 일들을 할 수 있도록
명령과 계산된 데이터를 전달하는 기능을 수행합니다.

먼저 vertex-Shader와 fragment-Shader를 작성해줍니다.
(* vertex-Shader : 정점, fragment-Shader : 색상 )

1
2
3
4
5
6
7
8
9
10
11
<!-- 버텍스 셰이더 작성 -->
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
uniform mat4 u_matrix;

void main(void) {
gl_Position = u_matrix * aVertexPosition;
// 클립공간은 -1.0 ~ 1.0의 범위 인데
// gl_Position * 0.5 + 0.5 하여 0.0 ~ 1.0 으로 변경하였다.
}
</script>
1
2
3
4
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 9;
gl.drawArrays(primitiveType, offset, count);

버텍스셰이
출처 : webglfundamentals.org

위의 이미지와 같이 원본 정점 9개를 작성한 vertexShader 함수를 통하여
GLSL에서 정의된 변수인 gl_Position에 주면 클립공간 정점으로 GPU에 저장합니다.

gl.drawArrays() 함수를 호출할 때 primitiveType을 TRIANGLES로 지정하였기 때문에
3개의 클립공간의 정점이 생성될 때마다 GPU는 이를 이용해 삼각형을 그리게 됩니다.

이 삼각형을 그릴때 아래의 그림과 같이 3개의 정점을 기준으로 래스터화 합니다.

  • 래스터화 = ‘삼각형을 픽셀로 그림’
    Ex) 정점삼각형 >> 삼각형래스터화

래스터화를 할 때 삼각형을 구성하는 각각의 픽셀에 대해서 프래그먼트 셰이더를 호출하게 되는데
이때 프래그먼트 셰이더는 특수변수인 gl_FragColor를 통해 각 픽셀의 색상을 알려주게 됩니다.

1
2
3
4
5
6
7
8
9
10
<!-- 프래그먼트 셰이더 작성 -->
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float; // 실수 정확도
// 낮은 정도의 precision을 가질수록 빠른 렌더 속도를 가지지만 렌더 퀄리가 그만큼 떨어진다.
varying vec4 v_color;
void main(void) {
gl_FragColor = vec4(0.5, 1.0, 0.5, 1.0); // vec4(R,G,B,A)
// GLSL의 색상값은 0~1 의 값으로 나타낸다.
}
</script>

이를 응용하면 아래와 같이 응용할 수 있습니다.

참고)
varing은 vertexShader에서 만든 데이터를 에서 fragmentShader에게 전달하는데 사용됩니다.
(* varing의 타입과 이름이 동일해야 연결이 됩니다.)

  1. 프래그먼트 셰이더는 래스터화된 점, 선, 면 등을 구성하는 픽셀 수 만큼 호출된다.
  2. 버텍스 셰이더에서 설정한 배어링 값은 선의 경우 2점 보간, 삼각형의 경우 3점 보간을 해서
    프래그먼트 셰이더에게 전달된다(배어링은 보간되어 전달된다는 점이 중요합니다).

아래의 그림을 통하여 정점 3개의 삼각형의 v_color가 보간되어 레스터화 되는 동작을 확인할 수 있습니다.

출처 : [webglfundamentals.org]


Comments: